《javascript语言精粹》读书笔记(二)

第三章 对象
javascript

    javascript的简单类型包括数字、字符串、布尔值、null值和undefined值,其余全部的值都是对象。
java

    javascript包含一个原型链特性,容许对象继承另外一对象的属性。正确的使用它能减小对象初始化的时间和内存消耗。node

    3.1对象字面量编程

如:var person={
        "name":"John",
        "age":18,
        "wife":{
            "name":"Lucy",
            "agen":22
        }
    }

    3.2检索设计模式

        点表示法或[]表示法。如:数组

person.name;
person["name"];

    3.3更新
闭包

        对象中的值能够赋值更新,若是已有属性,那么属性值被替换;若没有属性,则该属性会被扩充到对象中。
app

    3.4引用
编程语言

        对象经过引用传递,他们永远不会被拷贝。(传递的仅仅是地址)
函数

    3.5原型

        (1)每一个对象都链接到一个原型对象--Object.prototype这个标准对象。

        (2)原型链接在更新时是不起做用的,当咱们改变某个对象的属性值时,不会触及到对象的原型。(只针对于实例属性的修改,对于原型上的引用类型会改变对象的原型)

        (3)原型链只有在检索值的时候用到,当尝试获取某个对象的属性值时,会沿着他的原型链从下到上依次找,直到Object.prototype,若是Object.prototype依然没有该属性,则返回undefined。这个过程称为委托。

        (4)原型关系是一种动态的关系,若是添加一个新的属性到原型中,该属性会当即对全部基于该原型建立的对象可见。

    3.6反射

        (1)typeof操做符用于肯定属性的类型。

        (2)hasOwnProperty对象是否拥有独立的属性,他不会检测原型链上的。

person.hasOwnProperty("name");//true
person.hasOwnProperty("c");//false

     3.7枚举

        for in语句会遍历对象的全部属性,包括原型链上的属性。能够用typeof和hasOwnPropery过滤。

    3.8删除

        delete操做符会删除对象的属性,但不会触及原型链上的属性。

    3.9减小全局变量污染

        最小化使用全局变量的一个方法是你的应用中只建立惟一一个全局变量。

var MYAPP={};

MYAPP.stooge={
    "first-name":"Joe",
    "last-name":"Howard"
}
MYAPP.person={
        "name":"John",
        "age":18,
        "wife":{
            "name":"Lucy",
            "agen":22
        }
    }


第四章 函数

    4.1函数对象

        在javascript中函数就是对象,他链接到Function.prototype(该原型对象自己链接到Object.prototype)。

        每一个函数对象在建立时也会带有一个prototype属性,他的值中拥有一个constructor属性,constructor属性的值即为该函数的对象。

    4.2函数字面量

var add = function(a,b){
    return a+b;
}

        经过函数字面量建立的函数对象包含一个连到外部上下文的链接,这被称为闭包。他是javascript强大表现力的根基。

    4.3调用

        除了声明时定义的形式参数,每一个函数接受两个附加参数:this和arguments(实际参数)。this的值取决于函数调用的模式。javascript一共有四种调用模式:方法调用模式、函数调用模式、构造器调用模式和apply调用模式。

        (1)方法调用模式

                当一个函数被保存为一个对象的属性时,咱们称它为一个方法

var myObjec={
    value:0,
    increment:function(inc){
        this.value += typeof inc === 'number' ? inc : 1;
    }
}
myObject.increment();
console.log(myObject.value);//1

                经过this可取得它所属对象的上下文的方法称为公共方法

        (2)函数调用模式

                当一个函数并不是一个对象的属性时,那么它被当作一个函数来调用。

var sum=add(3,4);    //7

                当函数以此模式调用时,this被绑定到全局对象。书中说这个设计是错误的,由于外部函数没法利用内部函数来帮助他工做,由于内部函数的this绑定了错误的值,不能共享该方法对对象的访问权(即不能在内部函数中用this访问对象的属性,由于this指向了全局变量)。书中提供了一个解决方法:

//给myObject添加一个double方法
myObject.double=function(){
    var that=this;    //解决方法
    
    var helper=function(){
        that.value=add(that.value,that.value);
    }
    
    helper();    //以函数形式调用helper();
}

myObject.double();    //以方法形式调用double
myObject.getValue();    //6

        (3)构造器调用模式

                    就是建立一个函数,而后用new操做符去调用它,这样就建立了这个函数(类)的一个实例,同时this会绑定到这个新实例(对象)上。

(例子比较简单,就直接截图了)

        (4)Apply调用模式

                因为javascript是一门函数式的面向对象编程语言,因此函数能够拥有方法。

         

            其实就是将方法的执行做用域更改了,放到了apply的一个参数中,和call的做用是同样的。

        4.4参数

            函数被调用时,内部自动得到一个arguments数组,经过他能够访问全部函数被调用时的参数列表。

          

            arguments并非一个真正的数组,它只是一个类数组的对象,它拥有length属性,却没有数组的方法。

        4.5返回

            每一个函数都有返回值(return),若没有指定,则返回undefined。

            以new调用的函数,且返回值不是对象,则返回this(该新对象)。

        4.6异常

            javascript也提供了异常处理机制。

var add=function(a,b){
    if(typeof a!=='number'){
        throw{
            'name':'TypeError',
            'message':'add needs numbers'
        };
    }
    return a+b;
}

            throw语句中断函数的执行,抛出一个exception对象,该对象包括一个可识别的异常类型name和一个描述性message。你也能够添加其余属性。

        该exception对象将传递到一个try语句的catch从句。

var try_it=function(){
    try{
        add("seven");
    }catch(e){
        console.log(e.name+":"+e.message);
    }
}
try_it();

        4.7给类型增长方法

            经过给Function.prototype添加方法使得该方法对全部函数可用:

Function.prototype.method=function(name,func){
    if(!this.prototype[name]){
        this.prototype[name]=func;
    }
    return this;
}

        为Number的原型添加一个integer方法取整:

Number.method('integer',function(){
    return Math[this<0?'ceiling':'floor'](this);
});

console.log((-3/10).integer());    //-3

        为String添加一个去除两侧空格的方法:

String.method('trim',function(){
    return this.replace(/^\s+|\s+$/g,'');
});

        这样就省去了prototype。我的以为书中的这种写法很牛逼!

    4.8递归(略)

    4.9做用域

        javascript没有块级做用域,只有函数级做用域,因此尽可能把变量定义在函数的顶部。

    4.10闭包

        函数能够访问他被建立时所处的上下文环境,称为闭包。就是说,内部函数一直保留着对外部函数属性的引用,这个属性会一直存在内存中。

//糟糕的例子
var addHandlers=function(nodes){
    var i;
    for(i;i<nodes.lengh;i++){
        nodes[i].onclick=function(e){
            alert(i);
        }
    }
}

书中没说致使的结果是什么,我以为应该是,点击任意节点alert的结果都是同样的,即最后一个node值,由于onclick函数一直保持着对i的引用。

//更好的例子
var addHandlers=function(nodes){
    var i;
    for(i;i<nodes.lengh;i++){
        nodes[i].onclick=function(e){    //书中此处的形参写的是i,应该是写错了
            return function(e){
                    alert(e);
                }
        }(i)
    }
}

    4.11回调callback(略)

    4.12模块

        此处其实是介绍了一个设计模式--模块模式,它一般和单体模式一块儿使用,目的是利用函数和闭包减小全局变量带来的弊端。

var serial_maker=function(){
    //实际上此处是定义了2个局部变量,一直放在内存中,但外部是不可访问的
    var prefix='';
    var seq=0;
    return{
        set_prefix:function(p){
            prefix=String(p);
        },
        set_seq:function(s){
            seq=s;
        },
        gensym:function(){
            var result=prefix+seq;
            seq+=1;
            return result;
        }
    };   
};

var seqer=serial_maker();
seqer.set_prefix('Q');
sequer.set_seq(1000);
var unique=seqer.gensym();    //Q1000

    4.13级联(略)--至关于jQuery的链式操做,都返回this

    4.14套用(略)--感受用处不大

    4.15记忆

        提供了一个设计思路以提升执行效率,减小循环次数。

相关文章
相关标签/搜索