JS链知多少?

作者: 留七七 | 来源:发表于2016-10-19 00:20 被阅读226次

    “链”这个概念也算是JS的一大特色了,这里总结了常见的JS链相关概念,资料主要还是来自于js权威指南这本书,再加上自己的一点理解,欢迎补充。

    js作用域链

    简单来说就是一个对象列表。那么这个对象列表是怎么来的呢?每次调用js函数时,编译器环境都会为这个js函数创建一个新的对象(上下文对象)来保存局部变量,并且把这个新的对象添加到作用域链中。当函数返回时,就从作用域链中将绑定变量的对象移除。

    js权威指南中的一段话很好的诠释这个概念,摘录如下:

    在js的顶层代码中(即不包含在任何函数定义内的代码),作用域链由一个全局对象组成。在不包含嵌套的函数体内,作用域链上有两个对象,第一个是定义函数参数和局部变量的对象(上下文对象),第二个是全局对象。在一个嵌套函数体内,作用域链上至少有三个对象。
    对象作用域链创建规则,当定义一个函数时,它实际上保存一个作用域链。当调用这个函数时,它创建一个新的对象来存储它的局部变量,并将这个对象添加至保存的那个作用域链上,同时创建一个新的更长的表示函数调用作用域的"链"。
    对于嵌套函数,每次调用外部函数时,内部函数会重新定义一遍。因此每次调用外部函数时,作用域链都不同。每次调用外部函数时,虽然内部嵌套函数的代码没变,但是关联这段代码的作用域链不相同了,所以内部函数也有差别,做永远链不同了。

    js链式调用

    这个就很容易理解了,使用过jQuery的人应该都知道链式调用。方法的链式调用又称为方法链。如果一个对象有多个方法属性,并且每个方法属性的返回值都是这个对象,那么这个对象的方法属性就可以链式调用
    例如:

        //支持方法链式调用的对象
        var obj = {
        
            "first":function(){
                        console.log("first");
                        return this;
                    },
            "second":function(){
                        console.log("second");
                        return this;
                    }
            }
        //方法链调用,在控制台输出:first    second
        obj.first().second()
    

    最典型的例子就是jQuery库,jQuery库中绝大多数方法都支持链式调用。关于如何创建js对象,请参见这篇文章

    js原型链

    理解原型链概念之前必须先理解原型的概念。

    原型:是一个可以让其他对象继承属性的对象。没有原型的对象很少,例如Object.prototype。普通对象都有原型,函数对象都有一个继承自Object.prototype的原型,其中函数对象的原型通过prototype属性获取,普通对象的原型通过__proto__属性访问(只有标准浏览器支持)。

    例子:var date = new Date() // Date.prototype就是Date的原型,date从原型中继承Date属性

    接着上面的例子,date对象的属性继承自Date.prototypeDate.prototype的属性又继承自Object.prototype,所以date对象的属性同时继承Date.prototypeObject.prototype,此时的Date.prototypeObject.prototype就是原型链。

    下面的代码可以证明date的属性继承自Date.prototype,Date.prototype的属性继承自Object.prototype

    date instanceof Date  //true
    Date.prototype instanceof Object //true
    date instanceof Object  //true
    
    date instanceof Date.prototype.constructor  //true
    Date.prototype instanceof Object.prototype.constructor   //true
    date instanceof Object.prototype.constructor    //true
    
    Object.getPrototypeOf(date) === Date.prototype  //true
    Object.getPrototypeOf(Date.prototype) === Object.prototype   //true
    Object.getPrototypeOf(date) === Object.prototype    //false
    

    PS: instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性;
    Object.getPrototypeOf,用来获取对象的原型,ES5标准推出的方法,用来获取生成对象的类的原型。

    相关文章

      网友评论

        本文标题:JS链知多少?

        本文链接:https://www.haomeiwen.com/subject/wjbvyttx.html