可结合另一篇”JS中的对象和原型” 一起食用
__proto__ 隐式原型 类型为function或者object
构造函数的隐式原型为function,对象的隐式原型为object
==告诉你这是一个什么类型的东东,它是由什么构造出来的==
==所有函数的隐式原型都是一样的!包括构造函数非构造函数,也包括匿名函数!!有一个除外:有继承关系的,A继承自B,那A和B的隐式原型不一样!!A的隐式原型为B,B隐式原型才为那个匿名函数表示==
有继承关系的A和B(B是爸爸,A继承自B)
这时有关原型的属性 A先向B看齐,B再向Object看齐
A.prototype.__proto__ == B.prototype 「A的原型由B构造而来」
B.prototype.__proto__ == Object.prototype
A.__proto__ == B
函数的隐式原型是一个匿名函数的表示
切记💡
function(){}.__proto__ != function(){}
Object的隐式原型是一个匿名函数表示(类型为function),而这个匿名函数的隐式原型相当于一个空对象的隐式原型(类型为对象,但这个隐式原型是非空的对象)!
Object.__proto__.__proto__==={}.__proto__
Object.__proto__.__proto__===new Object().__proto__
但是Object.__proto__并不等于{}或new Object()
一个对象被创建时,会自动为当前对象添加一个属性: __proto__
对象的隐式原型相当于它的祖宗,它是怎么来的;祖宗拥有的属性和方法是他们的所有后代都有的
1 | function fn1(){ |
调用对象的属性或方法时,
- js会首先在该对象自身上查找是否存在改属性或方法
- 该对象自身不存在该属性或方法时,会自动去该对象的__proto__找,如果还没有就再往下一层的__proto__找,找到最后一层,没有就算啦。
prototype是一个对象
xiaohua.constructor 可以看出xiaohua的构造函数Cat,相当于xiaohua.__proto__.constructor
Cat.prototype.constructor == Cat
方法的原型对象的构造函数是自己,方法构造出方法的原型对象
[1,2,3].constructor => Array | [1,2,3].__proto__.constructor
prototype 类型为对象
==函数的原型对象,介绍它的孩子们(实例们)是什么类型的东东,由什么构造来,即孩子们的隐式原型。==
Object === Object.prototype.constructor
改原型的时候,不要把构造函数覆盖掉了,最好不要直接把对象赋值给prototype,用assign方法更好
Object.assign(Cat.prototype,{x:10});
Object.prototype都找不到就不用再往下看了,永远找不到了
Object.prototype.__proto__ = null 已经到空了
继承是依靠原型链来的
Cat.prototype.__proto__ == Animal.prototype
Cat.__proto__==Animal
原型链查找方法
1 | class Animal{eat(){console.log(‘吃’);}}; |
属于类的属性或方法 静态属性|静态方法
这些属性/方法是和prototype同级的,所以类的实例没法找到这些属性/方法
Cat.type=“猫”
let xiaohua = new Cat(‘xiaohua’);
xiaohua.type 到xiaohua.__proto__(Cat.prototype)找,找不到,因为type和prototype是同级关系。
对象包装器
附
class改造为原生写法
class Animal { eat(){console.log(‘吃’);}}
=>function Animal(){} Animal.prototype.eat = function(){console.log(‘吃’);}
