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

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

  1. 原型链

    SubType.prototype=new SuperType();

    这种方法的问题就是,如果超类有引用型属性,那这个属性会被所有的SubType实例共享,一个实例修 改这个属性,其他实例也会有同样的效果。所有很少单独使用。
  2. 借用构造函数
    就是在子类型构造函数内部调用超类型构造函数,这样子类型就会拥有超类型的所有属性了,各个实例是各自拥有属性的副本,不会相互影响,和原型链相比还有有一个优势就是可以传入参数,存在的一个问题就是方法都在构造函数中,就没有函数复用了,因此也很少单独使用。

    function SubType(){
    Super.call(this,“name”);
    }

    tips:为了确保SuperType的构造函数不会重写子类型的属性,在调用超类型的构造函数之后,再定义子类型自由的属性。
  3. 原型链+借用构造函数法
    使用原型链实现对原型属性和方法的继承,通过构造函数实现对实例属性的继承。解决了前两个方法的不足之处,其实就是优势互补。是最常用的继承模式。

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.οnclick=handler方法添加的关联函数,事件处理函数是在元素的作用域中进行,this引用当前元素,二用attachEvent关联的函数,this==window,所以要在关联函数中获取当前元素,最兼容的办法还是用element.οnclick=handler。
4.在IE中使用DOM0级方法即element.οnclick=handler,event对象是作为window对象的一个属性存在,如果是attachEvent方法添加的,则会有一个event对象作为参数被传入事件处理程序函数中。

6.第18章,高级函数

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

function Person(name,age,job){
    ifthis 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)减少属性查找,因为属性查找要遍历会对原型链中拥有改名称的属性进行一次搜索,多次用到的属性,可以存储在局部变量中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值