您的位置:首页 > Web前端 > JavaScript

《JavaScript高级程序设计-第2版》读书笔记

2015-05-04 15:50 316 查看

1:继承的各种实现方法:

原型链

SubType.prototype=new SuperType();


这种方法的问题就是,如果超类有引用型属性,那这个属性会被所有的SubType实例共享,一个实例修 改这个属性,其他实例也会有同样的效果。所有很少单独使用。

借用构造函数

就是在子类型构造函数内部调用超类型构造函数,这样子类型就会拥有超类型的所有属性了,各个实例是各自拥有属性的副本,不会相互影响,和原型链相比还有有一个优势就是可以传入参数,存在的一个问题就是方法都在构造函数中,就没有函数复用了,因此也很少单独使用。

function SubType(){

Super.call(this,“name”);

}


tips:为了确保SuperType的构造函数不会重写子类型的属性,在调用超类型的构造函数之后,再定义子类型自由的属性。

原型链+借用构造函数法

使用原型链实现对原型属性和方法的继承,通过构造函数实现对实例属性的继承。解决了前两个方法的不足之处,其实就是优势互补。是最常用的继承模式。

2:函数内的this指针问题:

this对象是在运行时基于函数的执行环境绑定的,在全局函数中,this指向window,当函数作为某个对象的方法调用时,this执行调用这个方法的对象,匿名函数的执行环境具有全局性。通常指向window。如果是普通的调用函数,那函数内部的this指针指向的是全局变量,即window对象。如果是构造函数的话,那this指针指向的就是构造出来的对象实例。


var name="donglin";
function sayName(name){
alert(this.name);
}
sayName("ab");
//运行结果是:donglin
var name="donglin_g"
function sayName(name){
this.name=name;
alert(this.name);
}
var oo=new sayName("ab");
//运行结果:ab


匿名函数中的this指针:

下面代码中匿名函数中的this就是指向window对象,并不会指向外部作用域对象。因为函数调用的时候,活动对象会自动获得this,arguments这两个对象,而此时调用匿名函数,this首先搜索自身作用域,此时this就是window,所以不会再向上搜索。

var name="the window";
var object={
name:"the object",
getName:function(){
return function(){
return this.name;
}
}
}
alert(object.getName()());
//运行结果是 "the window"


为了实现能访问外部作用域的this,把外部作用域中的this对象保存在一个闭包能够访问到的变量里,就可以让闭包访问该对象了。

var name="the window";
var object={
name:"the object",
getName:function(){
var that=this;
return function(){
return that.name;
}
}
}
alert(object.getName()());
//运行结果是 "the object"


tips:构造函数和普通函数的唯一区别,就在于调用它们的方式不对,任何函数,只要通过new操作符来调用,那他就可以成为构造函数,不通过new操作符,那就是普通函数。

3.匿名函数

1.递归函数应该始终使用arguments.callee来递归地调用自身,不要使用函数名–函数名可能会发生变化

4.BOM对象

1.修改window.location、location.href会调用location.assign()方法,所以这三个操作效果是一样的,并会在历史记录中生成一条记录,用replace()方法就不会生成新纪录。location.reload()重新加载,但是给true参数后,则会从服务器重新加载,否则可能从缓存中加载。

5.event对象,跨浏览器绑定事件方法:

IE是事件冒泡,Chrome Safari,Opera,FireFox是事件捕获,w3c采取折中的方式:任何事件会首先被捕获直至到达目标元素然后再冒泡回去,默认是冒泡。

var EventUtil={
addHandler:function(element,type,handler){
if(element.addEventListener){            //chrome ...之类的浏览器方式
element.addEventListener(type,handler,false);//默认是false
}else if(element.attachEvent){           //IE
element.attachEvent("on"+type,handler);
}else{
element["on"+type]=handler;
}
},
removeHandler:function(element,type,handler){
if(element.removeEventListener){
element.removeEventListener(type,handler,false);
}else if(element.detachEvent){
element.detachEvent("on"+type,handler){
}else{
element["on"+type]=null;
}
},
getEvent:function(event){
return event?event:window.event;
},
getTarget:function(event){
return event.target||event.srcElement;
},
getRelatedTarget:function(event){
if(event.relatedTarget){
return event.relatedTarget;
}else if(event.toElement){
return event.toElement;
}else if(event.fromElement){
return event.fromElement;
}else{
return null;
}
},
preventDefault:function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue=false;
}
},
stopPropagation:function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble=true;
}
}
};


tips:

1.用addEventListener和attachEvent关联的匿名函数,将无法移除。

2.addEventListener可以添加多个事件处理函数,执行顺序是按添加顺序。attachEvent则是相反,类似堆栈。

3.用addEventListener和element.onclick=handler方法添加的关联函数,事件处理函数是在元素的作用域中进行,this引用当前元素,二用attachEvent关联的函数,this==window,所以要在关联函数中获取当前元素,最兼容的办法还是用element.onclick=handler。

4.在IE中使用DOM0级方法即element.onclick=handler,event对象是作为window对象的一个属性存在,如果是attachEvent方法添加的,则会有一个event对象作为参数被传入事件处理程序函数中。

6.第18章,高级函数

1.可以创建作用域安全的构造函数,确保在缺少new操作符时调用构造函数不会改变错误的环境对象,因为直接调用函数时,this对象是window,而使用new操作符时,this指向新创建的对象实例。

function Person(name,age,job){
if(this instanceof Person){
this.name=name;
this.age=age;
this.job=job;
}else{
return new Person(name,age,job);
}
}


2.大量if语句时,可以采用惰性载入,即在第一次调用的过程中,该函数会被覆盖为另外一个按合适方式执行的函数,这样,第二次调用这个函数时,就不会再经过多次的if了

function createXHR(){
if(typeof XMLHttpRequest!="undefined"){
createXHR=function(){
return new XMLHttpRequest();
};
}...
...
return createXHR();
}


3.定时器代码是放在一个等待区域,知道时间间隔到了以后,此时将代码添加到JavaScript的处理队列中,等待下一次JavaScript进程空闲时被执行,setTimeout()里的this指向window

7.第20章最佳实践

1.JavaScript性能优化

1)避免全局查找,将在一个函数中多次用到的全局变量存储为局部变量

2)避免使用with语句,因为会增加作用域的长度,增加查找作用域的时间,解决办法也是用局部变量

3)减少属性查找,因为属性查找要遍历会对原型链中拥有改名称的属性进行一次搜索,多次用到的属性,可以存储在局部变量中
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐