在JS 中, 有两条链子,作用域链和原型链,作用域链相对容易理解点,而原型链就相对复杂了,我们今天就来详细的讲讲这复杂的原型链以及原型继承。我们直接进入正题吧!
作用域链
作用域链相对容易理解,两点
1、函数限定变量作用域,就是说,在JavaScript中,在函数里面定义的变量,可以在函数里面被访问,但是在函数外无法访问
2、在JavaScript中使用变量,JavaScript解释器首先在当前作用域中搜索是否有该变量的定义,如果有,就是用这个变量;如 果没有就到父域中寻找该变量. 由于变量提升,因此在实际开发的时候,推荐将变量都写在开始的地方,也就是在函数的开头将变量就定义好.
接着再来看看原型链
原型链
在 Javascript 中, 每一个对象 o 都具有 proto 属性(这个属性在IE9 以下没有暴露出来),被称为原型 ,根据属性搜索原则 对象 o 可以通过.或者 [] 读取原型的属性,但是当写入时,不会在原型上修改属性,而是直接在对象 o 上添加.
当然,原型也是对象,原型也有proto 属性, 子子孙孙无穷尽也 ~~~
真的是无穷尽吗,当然不是 !
var obj = {a: 'pawn'};
上面通过对象字面值的方式申明了一个对象 obj,并且拥有属性 a .
由于 o.proto === Object.prototype,那么可以认为这种方式等价于
var obj = new Object({a: 10});
所以,o 是继承自 Object.prototype,但 Object.prototype 也是对象,它继承自什么呢?
好吧,它继承自 null , 万剑归宗。
好了,现在找到了原型链的第一条子链
我们在来看 function
var func = function() {}
通过字面值声明一个function
同理
func 继承自Function.prototype,那 Function.prototype 也是对象,它继承自什么呢?
可以看到,Function.prototype 继承自Object.prototype,这也就回到了上一条链子.
好了,那现在引入一个问题,Function 本身也是函数,那 Function继承自哪呢? 当然是 Function.prototype,所以JS中最乱伦的东西出现了,Function 是自己的老子,即
那 Object 也是函数,Object 也当然继承自 Function.prototype
好了,这就是所有原型链的东西
看起来好像很乱,盗 JK老师 一张图, 详细说明这个问题
现在做一个总结
1、所有的函数都继承自 Function.prototype,Function,Object 是函数,所以继承自 Function.prototype
2、所有的对象都直接或间接继承自 Object.prototype,Function.prototype.proto === Object.prototype函数也是对象,所以函数最终继承自Object.prototype .
3、Object.prototype 继承自 null,万剑归宗
原型继承
看完了原型链,再看原型继承就简单了
var ProtoHerite = function(source) { var o = {}; if(o.proto){ o.proto = source; return o; } var F = function() {}; F.prototype = source; return new F(); }
这个函数返回的对象原型继承自 source,这也是 Object.create(source) 实现思路.
原型链继承固然很强大,但是也有一些问题,比如共享的原型属性容易被修改,在创建子类型的实例时,不能向超类传参数,等等。
以上是js中的作用域链和原型链以及原型继承的详细内容。更多信息请关注PHP中文网其他相关文章!