码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-03-12 17:24:22      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:

第三章 对象

    javascript的简单类型包括数字、字符串、布尔值、null值和undefined值,其他所有的值都是对象。

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

    3.1对象字面量

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

    3.2检索

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

person.name;
person["name"];

    3.3更新

        对象中的值可以赋值更新,如果已有属性,那么属性值被替换;若没有属性,则该属性会被扩充到对象中。

    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记忆

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

    


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

标签:

原文地址:http://my.oschina.net/brant/blog/386287

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!