JavaScript
将字符串转换为数字
parseInt() 只保留数字的整数部分,不会进行四舍五入运算。
parseFloat()如果在数字后加上非数字的字符,也可以转换成功。
事件
事件源.事件 = function(event){ 事件处理函数 }或=函数名;
事件 | 描述 |
---|---|
鼠标单击 | |
ondblclick | 鼠标双击 |
onkeyup | 按下并释放键盘上的一个键时触发 |
onchange | 文本内容或下拉菜单中的选项发生改变 |
onfocus | 获得焦点,表示文本框等获得鼠标光标。 |
onblur | 失去焦点,表示文本框等失去鼠标光标。 |
onmouseover | 鼠标悬停,即鼠标停留在图片等的上方 |
onmouseout | 鼠标移出,即离开图片等所在的区域 |
网页文档加载事件 | |
onunload | 关闭网页时 |
onsubmit | 表单提交事件 |
onreset | 重置表单时 |
oninput | 正在输入时 |
event 常见属性
属性 | 作用 |
---|---|
data | 返回拖拽对象的URL字符串(dragDrop) |
width | 该窗口或框架的高度 |
height | 该窗口或框架的高度 |
pageX | 光标相对于该网页的水平位置(ie无) |
pageY | 光标相对于该网页的垂直位置(ie无) |
screenX | 光标相对于该屏幕的水平位置 |
screenY | 光标相对于该屏幕的垂直位置 |
target | 该事件被传送到的对象 |
type | 事件的类型 |
clientX | 光标相对于该网页的水平位置 (当前可见区域) |
clientY | 光标相对于该网页的水平位置 |
pageX clientX screenX 区别
screenX screenY 是以我们的电脑屏幕为基准点测量
pageX pageY 以我们的文档(绝对定位)的基准点对齐 (ie678 不认识)
clientX clientY 以可视区域(不包含滚动条内容)为基准点类似于固定定位
入口函数
window. = function(){内部放js} 页面的结构,样式,节点等加载完毕后执行。
变量声明提升
function fun(){console.log(num); var num = 20;} 相当于 ---function fun(){var num; console.log(num); Num = 20;}
在函数体内部,声明变量,会把该声明提升到函数体的最顶端。 只提升变量声明,不赋值。
函数参数
JavaScript在创建函数的同时,会在函数内部创建一个arguments对象实例,用于存储函数传送过过来实参,长度为实参个数。
arguments对象只有函数开始时才可用。函数的 arguments 对象并不是一个数组,访问单个参数的方式与访问数组元素的方式相同
function fn(a,b){
console.log(fn.length); //得到是函数的形参的个数
console.log(arguments.length);
} // 得到的是实参的个数arguments.callee; 返回的是正在执行的函数本身。 也是在函数体内使用。 在使用函数递归调用时推荐使用arguments.callee代替函数名本身
this (事件的调用者)
函数中遇到要修改自身属性的一定要用this来代替自身。
innerHTML 更换盒子里面的内容 文字 标签都换.
Input.value 更换表单内容(单标签内容都是通过value得到)
$("txt").focus();给表单使用,使光标聚焦在表单可直接输入。
$("txt").select();全选表单中的内容。
判断真假
我们用条件语句来判断5大数据类型中的真假;
数据 | 结论 |
---|---|
数字类型 | 所有数字都是真,0是假 |
字符串 | 所有字符串都是真,’ ’串是假 |
对象 | 所有对象都是真,null是假 |
未定义 | undefined是假,没有真 |
访问关系
父 : this.parentNode 得到父亲的标签
兄弟: nextElementSibling 下一个兄弟
previousElementSibling 上一个兄弟子节点: children
插入节点
appendChild(); 添加子节点放到盒子的最后面。
insertBefore(插入的节点,参照节点) 子节点 写满两个参数
demo.insertBefore(test,childrens[0]);
如果第二个参数为 null则默认这新生成的盒子放到最后面。
克隆节点
cloneNode();
括号里面如果里面是 true 深层复制,除了复制本盒子,还复制子节点。
如果为 false 浅层复制 只复制 本节点 不复制 子节点。
设置节点属性
获取节点属性 getAttribute(属性)
设置节点属性 setAttribute(“属性”,”值”);
删除某个属性 removeAttribute(“属性”);
声明日期
var date = new Date();
若括号内写日期“2015/12/12 17:30:00”则是定义自己的时间 日期与时间中用空格隔开,不写日期是当前时间。
提倡使用date.getTime();date.valueOf();都是得到距离 1970年的毫秒数,做计算用
Date.prototype.toLocaleDateString()转换为当前日期格式
定时器
var timer= window.setInterval(“执行的函数名”,间隔时间)
关闭定时器 clearInterval(定时器名称);
倒计时定时器 setTimeout(“函数”, 时间 ) 只执行一次
深层次的看待定时器区别:
setInterval是排队执行的,假如间隔时间是1秒,而执行的程序的时间是2秒,上次还没执行完的代码会排队, 上一次执行完下一次的就立即执行, 这样实际执行的间隔时间为2秒
setTimeout延迟时间为1秒执行, 要执行的代码需要2秒来执行,那这段代码上一次与下一次的执行时间为3秒.
要养成习惯要使用定时器前先清楚之前的定时器。
Javascript是单线程执行的,当某段代码正在执行的时候,所有后续的任务必须等待,行程一个队列,一旦当前任务执行完毕,再从队列中取出下一个任务,被称为“阻塞式执行”。如果代码中设定了一个setTimeout,那么浏览器会在合适的时间将代码插入任务队列,如果这个时间设为0就代表立即插入队列等待执行。属于异步执行函数。
offset
得到对象的宽度和高度(自己的,与他人无关) offsetWidth = width + border + padding div.style.width 这样只能得到行内样式的数值 offsetLeft offsetTop 返回子盒子到带有定位的父盒子边框到边框的距离 如果父级都没有定位则以body 为准 offsetLeft 从父级的padding 开始算,父亲的border 不算 offsetParent 返回改对象带有定位的父级 如果当前元素的父级元素中有CSS定位(position),offsetParent取最近的那个父级元素。
offsetTop 与 style.top 的区别:
最大区别在于 offsetTop 可以返回没有定位盒子的距离左侧的位置。 而 style.top 不可以(只有定位的盒子才有 left top right)
最重要的区别style.left 只能得到行内样式offsetLeft都可以
offsetTop 返回的是数字,而 style.top 返回的是字符串,除了数字外还带有单位:px。
offsetTop 只读,而 style.top 可读写。
如果没有给 HTML 元素指定过 top 样式,则 style.top 返回空字符串。
scrollTop scrollLeft
scrollTop 当滑动滚轮浏览网页的时候网页隐藏在屏幕上方的距离
页面滚动效果
window.onscroll = function() { 页面滚动语句 }
谷歌浏览器 和没有声明 DTD : document.body.scrollTop;
火狐 和其他浏览器 document.documentElement.scrollTop;
ie9+ 和 最新浏览器都认识window.pageXOffset; pageYOffset (scrollTop)
兼容性写法: var scrollTop = window.pageYOffset || document.documentElement.scrollTop|| document.body.scrollTop || 0;
JSON
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,我们称之为JavaScript对象表示法。使用JSON进行数据传输的优势之一。
JSON.stringify(value,repalcer?,space?)将JSON输出字符串,replacer是一个含有参数key,value的节点访问函数,可以对每个键值进行操作后输出,return的是value值,space是使用给定的字符为每个层级缩进,生成一个对象树。只输出可枚举的属性。采用的是前序遍历算法(父元素先于子元素)。
也可以JSON.stringify(value).replace(/"/g,"")对转换后的string做操作。
JSON.parse(text,recicer?)reviver是一个节点访问函数,可以用来转换解析后的数据,函数的参数为key,value用来对转换后的数据进行操作,return的是value值。采用的是后序遍历算法(子元素先于父元素)。
Json一般就是被当做一个配置单用; 字符串必须用双引号括起来。
用for循环json时for(key in json){其中json[key]表示相应的value}
var json1 = {name :"刘德华",age: 55};
console.log(json1.name); // 输出名字 刘德华
正则表达式
/g 表示该表达式将用来在输入字符串中查找所有可能的匹配,返回的结果可以是多个。如果不加/g最多只会匹配一个
/i 表示匹配的时候不区分大小写,这个跟其它语言的正则用法相同
/m 表示多行匹配。什么是多行匹配呢?就是匹配换行符两端的潜在匹配。影响正则中的^$符号
/s 与/m相对,单行模式匹配。
/e 可执行模式,此为PHP专有参数,例如preg_replace函数。
/x 忽略空白模式。
scroll函数返回scrollLeft和scrollTop的json
function scroll() {if(window.pageYOffset != null) // ie9+ 和其他浏览器{return {left: window.pageXOffset, top: window.pageYOffset}}else if(document.compatMode == "CSS1Compat") // 声明的了 DTD// 检测是不是怪异模式的浏览器 -- 就是没有声明<!DOCTYPE html>{return {left: document.documentElement.scrollLeft, top: document.documentElement.scrollTop}}return {left: document.body.scrollLeft, // 剩下的肯定是怪异模式的 top: document.body.scrollTop}}
页面点击滑动效果
var leader = 0,target = 0,timer = null; for(var i= 0; i<ulBoxLi.length; i++) { olBoxLi[i].index = i; // 记录当前的索引号 olBoxLi[i]. = function() { clearInterval(timer); target = ulBoxLi[this.index].offsetTop; // 核心语句 timer = setInterval(function() { leader = leader + (target - leader ) /10; window.scrollTo(0,leader); // 屏幕滑动 //pic.style.left = leader + 'px'; },30)}}
client 家族(可视区域)
offsetWidth: width + padding + border clientWidth: width + padding 不包含border scrollWidth: 大小是内容的大小
检测屏幕宽度(可视区域)
ie9及其以上的版本 window.innerWidth
标准模式 document.documentElement.clientWidth
怪异模式 document.body.clientWidth
自己封装一个 返回可视区宽度和高度的函数。function client() { if(window.innerWidth != null) // ie9 + 最新浏览器 { return {width: window.innerWidth, height: window.innerHeight}} else if(document.compatMode === "CSS1Compat") // 标准浏览器 {return {width: document.documentElement.clientWidth, height: document.documentElement.clientHeight}} return { width: document.body.clientWidth, height: document.body.clientHeight}} // 怪异浏览器
window.onresize 改变窗口事件
window.onresize = function() {} 窗口框架被调整大小时的事件
简单冒泡机制
事件冒泡: 当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有父元素中被触发。这一过程被称为事件冒泡;这个事件从原始元素开始一直冒泡到DOM树的最上层。
顺序div -> body -> html -> document -> window
不是所有的事件都能冒泡。以下事件不冒泡:blur、focus、load、unload
**阻止冒泡的方法 **
if(event && event.stopPropagation) {event.stopPropagation();} // w3c 标准 else {event.cancelBubble = true; } // ie678 ie浏览器
判断当前对象
火狐 谷歌 等 event.target.id
ie 678 event.srcElement.id
兼容 var targetId = event.target ? event.target.id : event.srcElement.id;
获得用户选择内容
window.getSelection() 标准浏览器document.selection.createRange().text; ie 获得选择的文字 兼容性的写法:if(window.getSelection) {txt = window.getSelection().toString();} // 转换为字符串else {txt = document.selection.createRange().text;} // ie 的写法
动画原理: style.left = 盒子的 offsetLeft + 步长
function animate(obj,target){ var speed = obj.offsetLeft < target ? 5 : -5; // 用来判断应该+还是 - obj.timer = setInterval(function() { var result = target - obj.offsetLeft; // 因为他们的差值不会超过5 obj.style.left = obj.offsetLeft + speed + "px"; if(Math.abs(result)<=5) // 如果差值不小于 5 说明到位置了 {clearInterval(obj.timer); obj.style.left = target + "px"; //直接跳转目标位置 } },30) }
我们访问得到css 属性,比较常用的有两种:
利用点语法
box.style.width box.style.top
但是这个语法有非常大的缺陷,不变的。 后面的width和 top没有办法传递参数的。利用 [] 访问属性
语法格式: box.style[“width”]
元素.style[“属性”];
最大的优点 : 可以给属性传递参数
得到css 样式
box.style.left box.style.backgorundColor 只能得到行内的样式。
得到内嵌或者外链的样式
obj.currentStyle ie opera 常用
外部(使用link)和内嵌(使用style)样式表中的样式(ie和opera)window.getComputedStyle("元素", "伪类") w3c
两个选项是必须的, 没有伪类用 null 替代兼容写法 :
封装获取属性的方法。function getStyle(obj,attr) { if(obj.currentStyle) // ie 等 {return obj.currentStyle[attr];} else {return window.getComputedStyle(obj,null)[attr]; }} // w3c 浏览器
in 运算符
in运算符也是一个二元运算符,但是对运算符左右两个操作数的要求比较严格。in运算符要求第1个(左边的)操作数必须是字符串类型或可以转换为字符串类型的其他类型,而第2个(右边的)操作数必须是数组或对象。只有第1个操作数的值是第2个操作数的属性名,才会返回true,否则返回false.
html5中javascript的提升
新选择器 JS多了一个原始支持,类似jqueryDOM选择器
document.querySelector(selector) 可以通过CSS选择器的语法找到DOM元素
document.querySelectorAll('.item') 返回所有满足该条件元素dom类型数组
本质上jquery方式和querySelector方式都是获取DOM数组, 只不过jquery会多一些其他成员。
DOM数组的每一个成员注册事件不能像jquery一样直接注册, 必须分别给每个元素注册.
h5就是将我们经常需要的操作又包装一层
元素.classList
新H5中DOM对象多了一个classList属性,是一个数组
.add() 添加一个新的类名
.remove() 删除一个的类名
.contains() 判断是否包含一个指定的类名
.toggle() 切换一个class element.toggle('class-name',[add_or_remove])
.toggle()函数的第二个参数true为添加 false删除
访问历史 API
界面上的所有JS操作不会被浏览器记住,就无法回到之前的状态
在HTML5中可以通过window.history操作访问历史状态,让一个页面可以有多个历史状态
window.history.forward(); // 前进
window.history.back(); // 后退
window.history.go(); // 刷新
history.pushState(放入历史中的状态数据, 设置title(现在浏览器不支持), 改变历史状态)
2.2 网页存储
2.2.1 Web Storage
localStorge.setItem(键,值)方式向本地存储数据,sessionStorge临时数据
2.4 拖放操作
想要捕获drop事件就一定要在改事件里阻止默认事件
target.addEventListener(“dragover”,function(e ){
e.preventDefault();
e.stopPropagation();
})
使用indexDB数据库
获取浏览器关于indexDB的一些对象,为了浏览器兼容性
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
window.IDBCursor = window.IDBCursor || window.webkitIDBCursor || window.msIDBCursor;
var dbInfo = { //定义一些数据库配置信息
dbName:"IndexDB", // 数据库的名称
dbVersion:2018 // 数据库的版本号
};数据库创建的时候默认版本号为1,当我们传入的版本号和数据库当前版本号不一致的时候onupgradeneeded就会被调用,当然我们不能试图打开比当前数据库版本低的version,否则调用的就是了
var dbContent = window.indexedDB.open(dbInfo.dbName, dbInfo.dbVersion); // 3、创建数据库连接控制数据库版本升级的方法,创建新store(表),或者是修改,都在这里面执行
dbContent.onupgradeneeded = function (e) {console.log("数据库版本发生变化");}// 3.2当数据库连接成功的时候执行的方法,我们一般的增删改查都在这里面进行操作dbContent.onsuccess = function (e) {console.log(e);}// 3.3当我们数据库连接是失败的时候执行的方法。dbContent. = function (e) { }
面向对象构造函数方式,传参时使用对象形式{ }
function Sprite( option ) {this._init( option );} Sprite.prototype = { _init: function( option ) {// 加下划线进行区分,仅用于内部调用。 this.name = option.name; this.x = option.x === 0 ? 0 : (option.x || 10); //传入参数x不为数字或没有传入参数情况下使用默认值10,因为有可能传入0,所以使用三元运算符来保证传入0的时候不被当做false而使用默认值 this.color = 'red'; }, angleToRad: function( angel ) { return angel * Math.PI / 180; }, show: function( arg ) { console.log( this.angleToRad( 30 ) ); console.log( 'ss' + arg ); } };
get set语法规范
Object.defineProperty(this, "price", { get: function () {return price*0.9;}, set: function (value) { /*大概普通产品的价格都在0--1万*/ if(value>10000) { alert('产品价格必须在0--1万之间'); }else{ price = value; } } });
javascript中的封装
封装:通过将一个方法或者属性声明为私用的,可以让对象的实现细节对其他对象保密以降低对象之间的耦合程度,可以保持数据的完整性并对其修改方式加以约束,这样可以是代码更可靠,更易于调试。封装是面向对象的设计的基石。
封装实现细节指的是,使得对象内部的变化对于其他对象而言是不可见的,对象只对自己的行为负责。对象之间的耦合变松散,对象之间只通过暴露的API接口来通讯。这样一来,即便当我们需要修改对象时,可以任意修改它的内部实现,而由于对外接口没有变化,则不会影响程序的其他功能。
很多编程语言是通过语法解析来实现封装数据的,比如Java提供private、public、protected等关键字来限定访问权限,而JavaScript缺乏这些关键字的支持,只能依赖变量的作用域来实现public和private的封装特性。
私有属性和方法:函数有作用域,在函数内用var 关键字声明的变量在外部无法访问,私有属性和方法本质就是你希望在对象外部无法访问的变量。
特权属性和方法:创建属性和方法时使用的this关键字,因为这些方法定义在构造器的作用域中,所以它们可以访问到私有属性和方法;只有那些需要直接访问私有成员的方法才应该被设计为特权方法。
共有属性和方法:直接链在prototype上的属性和方法,不可以访问构造器内的私有成员,可以访问特权成员,子类会继承所有的共有方法。
共有静态属性和方法:最好的理解方式就是把它想象成一个命名空间,实际上相当于把构造器作为命名空间来使用。
/* -- 封装 -- */ var _packaging =function(){ //私有属性和方法 var name ='Darren'; var method1 =function(){ //... } //特权属性和方法 this.title ='JavaScript Design Patterns' ; this.getName =function(){ return name; } } //共有静态属性和方法 _packaging._name ='Darren code'; _packaging.alertName =function(){ alert(_packaging._name); } //共有属性和方法 _packaging.prototype = { init:function(){ //... } }
javascript中的继承
继承本身就是一个抽象的话题,在JavaScript中继承更是一个复杂的话题,因为JavaScript想要实现继承有两种实现方式,分别是类式继承和原型式继承,每种实现的方式都需要采取不少措施,下面本人通过分析例子的方式讲解JavaScript中这个很重要的话题。
/* -- 类式继承 -- */ //先声明一个超类 function Person(name){ this.name = name; } //给这个超类的原型对象上添加方法 getName Person.prototype.getName =function(){ returnthis.name; } //实例化这个超类 var a =new Person('Darren1') alert(a.getName()); //再声明类 function Programmer(name,sex){ //这个类中要调用超类Person的构造函数,并将参数name传给它 Person.call(this,name); this.sex = sex; } //这个子类的原型对象等于超类的实例 Programmer.prototype =new Person(); //因为子类的原型对象等于超类的实例,所以prototype.constructor这个方法也等于超类构造函数,你可以自己测试一下,//如果没这一步,alert(Programmer.prototype.constructor),这个是Person超类的引用,所以要从新赋值为自己本身 Programmer.prototype.constructor = Programmer; //子类本身添加了getSex 方法 Programmer.prototype.getSex =function(){ returnthis.sex; } //实例化这个子类 var _m =new Programmer('Darren2','male'); //自身的方法 alert(_m.getSex()); //继承超类的方法 alert(_m.getName());
/* -- 原型式继承 -- */ //clone()函数用来创建新的类Person对象 var clone =function(obj){var _f =function(){}; //这句是原型式继承最核心的地方,函数的原型对象为对象字面量 _f.prototype = obj; returnnew _f; } //先声明一个对象字面量 var Person = { name:'Darren', getName:function(){ returnthis.name; } } //不需要定义一个Person的子类,只要执行一次克隆即可 var Programmer = clone(Person); //可以直接获得Person提供的默认值,也可以添加或者修改属性和方法 alert(Programmer.getName()) Programmer.name ='Darren2' alert(Programmer.getName()) //声明子类,执行一次克隆即可 var Someone = clone(Programmer);
原型编程泛型包括以下的特点:
所有的数据都是对象;
不通过实例化创建对象,而是找到一个对象作为原型并克隆它;
对象会记住个各自的原型;
如果对象无法响应某个请求,会把这个请求委托给自己的原型;
你使用new操作符调用构造函数时,会经历以下步骤:
创建一个空对象,作为将要返回的实例对象;
将空对象的原型指向构造函数的prototype属性,也就是Keith构造函数的prototype属性;
将空对象赋值给构造函数内部的this关键字,也就是this关键字会指向实例对象;
开始执行构造函数内部的代码;
对象会记住各自的原型,如果对象无法响应某个请求,会把这个请求委托给自己的原型。
JavaScript中的多态
多态最根本的作用是消除条件分之语句,将过程化的条件分之语句转化为对象的多态性。
每个对象应该做什么,封装在成对象内部的一个方法,每个对象负责自己的行为。所以这些对象可以根据同一个指令,有条不紊地分别进行各自的工作,这正是面向对象的优点。
由于JavaScript的变量类型在运行期是可变的,意味着JavaScript对象的多态性是与生俱来的 。判断对象是否具有某种能力,不需要判断对象是否属于某种类型,只取决于它有没有相对应的方法,不存在任何程度的“类型耦合”。
小知识点:
设置图片时<image scr="" alt="" width="">单设置一个长或宽则剩下的边长按比例自动设置。
鼠标移至图片上时变成小手给图片添加样式 cursor:pointer;
阻止表单提交<form action="javascript:;">
设置盒子权重时在样式中写 z-index:数字越大优先级越高。
id选择器与类选择器的区别:同一个页面中一个标签只能对应一个id但是可以选择多个类,类也可以应用在多个标签中。
给a标签的href="javascript:;" 其中javascript:是伪协议,它可以让我们通过一个链接来调用javascript函数.而采用这个方式 javascript:;可以实现A标签的点击事件运行时,如果页面内容很多,有滚动条时,页面不会乱跳,用户体验更好。相当于执行了一段javascript空代码,地址不发生跳转。与这个相同<a href=”javascript:void(0);”></a>
去掉li前面的小点用list-style-type: none;
使li或span的外形变为圆形用border-radius: 50%; 添加圆角边框。
textarea设置resize:none;可以防止用户改变文本框大小。
想让盒子根据里面内容多少改变大小将盒子height改成auto。
使按钮或者表单不可用this.disable=true;
a&&b 如果a 为假 ,则返回 a ;如果a 为真 ,则返回 b 。
i. a||b 如果 a 为假 ,则返回b ;如果 a 为真 ,则返回a 。img {vertical-align: top; } /取消图片底部3像素距离/
一定要注意在javascript里修改style样式时候赋值都要用“”以字符串形式赋值。
javascript修改style中的数值后都可以到行内数值样式上看到。
使用webstorm新建javascript文件时候先把右下角的编码格式改为utf-8否则后面运行会出错。新建css文件也一样。
如果在head里面引用javascript文件则需要考虑文件内函数是否在window.里面否则会产生因为网页未加载完造成javascript出错。
表单中的input可以直接通过name属性获取到DOM对象,form.控件name
创建字符串时若里带有标签的最好用单引号括起来避免和里面的双引号冲突。
JS 页面跳转: window.location.href = ”http://www.itcast.cn”。
要获取当前页面宽度用document.documentElement.clientWidth。
获取当前页面相对滚动document.documentElement.scrollTop||document.body.scrollTop;
input的type改为search时可以将回车当确认键。
获取屏幕触摸用addEventListener(“touchstart”,function(event){})在函数中用event.touches[0].clientY;来获取鼠标点击的Y坐标用touchmove来获取触摸离开时鼠标最后所在的坐标。
使用var img=new Image(width,height );效果和cratelement的效果相同。用img.src添加图片。
字符串转换成JSON对象用全局的JSON函数 JSON.parse(string);
可以利用instanceof来判断对象的构造函数。
若函数中加return就不能当做构造函数来看,构造函数return的是一个对象。
判断数据类型时常用typeof和call,在使用 typeof 运算符时采用引用类型存储值(NULL,数组,对象)会出现一个问题,无论引用的是什么类型的对象,它都返回 "object"。
console.log(toString.call({})) //[object Object]
console.log(toString.call([])) //[object Array]
用window.addListener(“hashchange”,function(e){})来监听地址栏中#后的哈希值变化,利用window.location来得到地址对象。
解析一个地址先创建一个a对象var aLink=document.creatElement(“a”)
再给a标签对象href赋值为地址字符串,之后既可通过aLink.hash得到地址哈希值
小技巧给一个数组不断添加内容可以arr[arr.length]=…;来给数组不断赋值。
从数组中删除元素也可以splice(元素索引,删除元素数目)。
for循环数组或对象时若用(index in arry)作为条件index表示当前元素索引。
可以使用外部链接的标签img(支持跨域但无法获取服务端数据)、iframe(可以接受数据单操作复杂)、link(在CSS处理阶段会报错)、script(可以获取服务器数据,被选做jsonp传送方式)。
为了使代码易于维护采用开闭原则,对于后期会产生变化的量一定不能写死,以后需要通过修改来迭代。
变化点封装,一般都把今后会变化的地址类的写在config函数里面,后面通过别名来使用。一定不要暴露在代码中。
将一个对象利用“=”赋值给另一个对象时传递的是一个内存对象,若修改其中一个的属性则都会发生改动,想要避免源对象被篡改可以利用object.assign()方法或者object.creat()方法。
js中函数对象是有长度的,它的长度是由参数的个数决定。(function (a, b, c, d) {}).length === 4。
想要正确处理上传的文件,并接受到文件的内容,需要把表单的enctype属性设置为multipart/form-data,这是个适用于于BLOB(大型二进制文件)的MIME类型。
想要将一个包含对象的数组以字符串的形式保存到文件中,需要循环遍历数组并用JSON对象的.stringify方法将对象转化为字符串形式,再进行保存。
写静态网页可以使用gulp+browersync(yo webapp生成模板),编写动态网站用express+ejs+sass.
Sass监听文件夹:sass --watch sassFileDirectory:cssFileDirectory;
Sass监听单个文件:sass --watch style.scss:style.css;函数的柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。增加了函数的适用性,但同时也降低了函数的适用范围。
惰性载入表示函数执行的分支只会在函数第一次掉用的时候执行,在第一次调用过程中,该函数会被覆盖为另一个按照合适方式执行的函数,这样任何对原函数的调用就不用再经过执行的分支了。如函数功能是对应不同浏览器创建XMLHttpRquest当第一次执行时判断完浏览器类型并创建完成后及可以返回一个被修改过后的本函数,覆盖原来的函数,这样以后调用此函数时就不需要再判断浏览器类型,可以直接创建对应XMLHttpRquest。
面向切面编程AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。比如最常见的就是日志记录了.
String的search、match、replace参数都可以为正则表达式。
任何语言在浮点数运算时都会有误差,浮点数运算的时候,先转化为二进制,用二进制来算,结果再转回十进制,转换的过程中会装换成无限循环小数,所以最后结果会有误差。js中使用Number.prototype.toFixed()来设置保留小数的位数,返回的是字符串。可以使用valueOf()来再转为number类型。
数组的归约函数reduce(function(prev,cur,i){})会从左到右进行迭代,每次返回的值作为下一次的prev参数。
在循环遍历数组时若是想在找到结果后将结果在数组中剔除防止重复,因为若是直接删除会影响数组的循环,解决办法是将此值赋为NaN,这样在数组中显示时为null。使用delete删除数值元素,删除元素会产生空缺,不会更新length,空缺部分显示undefined。如果没按照数组顺序给数组某一索引赋值,数组将不连续,中间空缺部分会显示undefined。forEach()会忽略undefined。使用splice()函数可以移除元素而不产生空缺。若修改数组的length为某个值,数组在此索引之外的部分都会被删除。使用array.filter(function(v){return true;})可以滤出空缺函数。
使用闭包要注意,由于变量被保存在内存中,所以会对内存造成消耗,所以不能滥用闭包。解决方法是 在退出函数之前,将不使用的局部变量全部删除。
使用array.filter(function(val){})可以遍历数组里的所有内容,return true的话数组会保留当前内容,false移除当前内容。
获得所有传入的参数放入一个数组args = Array.prototype.slice.call(arguments);
写递归函数时要注意:无论是否满足跳出递归的条件,下一步的执行都要带上return,即在调用自身时前面一定要带上return,满足跳出条件时才能一步一步跳出循环。
var lefted,sliced = [];
function chunkArrayInGroups(arr, size) {
sliced.push(arr.slice(0, size));
lefted = arr.slice(size, arr.length);
if (lefted.length == 0) {
return sliced;
} else {
return chunkArrayInGroups(lefted, size);
}
}
```
面向对象
在构造函数中创建共有属性通过this.创建,私有属性通过var 创建。
使用delete collection.tracks,可以删除collection的tracks属性。
数据属性有4个描述的行为特性,通过Object.defineProperty(obj,propKey,propDesc)设置。
writable 表示能否修改属性的值。默认为false
Enumerable 表示能否过过for in循环返回属性是否可以枚举。默认为false可以枚举
configuralbe 表示是否能过来delete删除属性从来重新定义属性,能否修改其配置。默认为false。
value 包含这个属性的数据值。读取属性值的时候,从这个位置读取。
使用Object.keys(obj)可以得到obj对象的所有自有(非继承)可枚举的属性键,属性通常都是可枚举的,Object.getOwnPropertyNames(obj)返回obj对象的所有属性键。
枚举的一般规则是,系统创建的属性不可枚举,用户创建的属性可枚举。枚举的主要目的是判断for-in循环中的哪些属性该忽略。对于自己的代码,通常可忽略枚举属性,且应该避免用for-in循环,属性的枚举特性默认为可枚举。
保护对象的三种方式:
防止扩展:Object.preventExtensions(obj);设置对象不能添加属性。
封闭:Object.seal(obj);可以改变属性的值,但属性的特性不能被改变。
冻结:Object.freeze(obj)使所有的属性不可写,且封闭obj不能扩展。
A instanceof B运算符可以用来判断B构造函数的prototype属性是否存在A对象的原型链上。等价于B.prototype.isPrototypeOf(A);
设置原型的另一种方法Object.creat(proto,propDescObj?);
获取原型的另一种方法Object.getPropertypeOf(obj);
实现模块化编程
// 计算模块calc_v2015.js(function(calculator,$) { function convert(input) {return parseInt(input);} calculator.add = function(a, b) {return convert(a) + convert(b);} window.calculator = calculator; })(window.calculator || {},jquery);
//自执行函数先判断window里面是否含有calculator没有的话传入空对象{}
// 新增需求calc_v2016.js(function(calculator,$) { function convert(input) {return parseInt(input);} // calculator 如果存在的话,我就是扩展,不存在我就是新加 calculator.remain = function(a, b) {return convert(a) % convert(b);} window.calculator = calculator; })(window.calculator || {},jquery);
//为了使代码高内聚低耦合不过度依赖第三方库,在自执行函数外给代码注入第三方的库。
// 开闭原则,对新增开放,对修改关闭;
```
作者:AkaTBS
链接:https://www.jianshu.com/p/1a3693e084b0