javascript前端开发那些事首页投稿(暂停使用,暂停投稿)

JS链知多少?

2016-10-19  本文已影响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标准推出的方法,用来获取生成对象的类的原型。

上一篇下一篇

猜你喜欢

热点阅读