原型链学习demo
1.隐式原型 和 显示原型
所有实例对象都有隐式原型,即 _proto_属性。 在ES6语法之前,不能通过隐式原型操作原型对象
所有构造函数都有显式原型,即 prototype属性
它们的关系是: 实例对象.__proto__ === 构造函数.prototype , 且看下面代码举例(fn.proto === Fn.prototype)。
let Fn = new Function()
let fn = new Fn()
let obj = {}
console.log(fn.__proto__) // 打印结果:Object()的一个实例对象
console.log(Fn.prototype) // 打印结果:Object()的一个实例对象
console.log(fn.__proto__ == Fn.prototype) // true
2.所有函数都是 Function 的实例对象,包括它自己 因为 Function = new Function()
所以这里有一点要注意:Function.__proto__ === Function.prototype
console.log(Function.__proto__ === Function.prototype) // true
3.实例对象.proto 和 函数对象.prototype 都是Object()的一个实例对象,但有一个例外:
当你尝试 console.log(typeof Function.__proto__ ) 或 console.log(typeof Function.prototype)
打印 function
console.log(typeof Function.__proto__) // function
console.log(typeof Function.prototype) // function
4.Object() 也是一个函数,所以它同样是 Function() 的一个实例对象
Object() 的定义方法 :var Object = new Function()
console.log(Object.__proto__ === Function.prototype) // true
5.Function.prototype 和 Object.prototype 在原型链中都有特殊之处
Function 的特殊之处在上文提过,只有Function.proto 等于 Function.prototype 且类型为 function
其他函数的这两个属性不同,上文说到 实例对象.proto === 构造函数.prototype 且类型为 Object
那么,Object 和 Function 是什么关系?
在 JS 中,一切函数实际上都是对象,但对象可不一定是函数。fn是对象,但obj不是函数。
console.log(fn instanceof Object)//true
console.log(Function instanceof Object); // true
console.log(obj instanceof Function)//false
6.上面的代码较好理解,再看看下面这行代码
对象虽不一定是函数,但Object()这个构造函数是
Object也是函数.因为Object的结构是function Object(){native code}.
console.log(Object instanceof Function); // true
最后,原型链是一条链,它的顶端是谁?
console.log(Function.prototype.__proto__ === Object.prototype) // true
console.log(Object.prototype) // 打印一个特殊对象
console.log(Object.prototype.__proto__) // null 原型链的顶端
原型链到 Object.prototype.proto 这里就结束了
Object.prototype 是一个特殊对象,它的特殊之处在于:
console.log(Object.prototype instanceof Object) // false
Object 不在 Object.prototype的原型链上。
总结
- 原型链是由原型对象组成,每个对象都有 __proto__ 属性,指向了创建该对象
的构造函数的原型,__proto__ 将对象连接起来组成了原型链。是一个用来实现
继承和共享属性的有限的对象链。 - 属性查找机制: 当查找对象的属性时,如果实例对象自身不存在该属性,则沿着
原型链往上一级查找,找到时则输出,不存在时,则继续沿着原型链往上一级查
找,直至最顶级的原型对象 Object.prototype,如还是没找到,则输出
undefined;
属性修改机制: 只会修改实例对象本身的属性,如果不存在,则进行添加该属性,
如果需要修改原型的属性时,则可以用: b.prototype.x = 2;但是这样会造成
所有继承于该对象的实例的属性发生改变。
文末贴上网上很有名的这张原型链关系图: