错误之处,欢迎指正。
1. 原型和原型链
- 所有函数都有
prototype
这个属性,这个属性指向该函数的原型。原型是一个对象格式。 - 所有对象都有
__proto__
这个属性,这个属性指向该对象的构造函数的原型。注意:使用__proto__
是不被推荐的一种方式,推荐使用Object
上的静态方法Object.getPrototypeOf(obj)
来获取该对象的构造函数的原型。 - 函数也是对象,函数也具有
__proto__
这个属性,指向构造函数Function
的原型。 -
Function
可以理解为是javascript
帮我们写好的,Function.__proto__ === Function.prototype
Object.prototype.__proto__ === null
- 当调用一个对象/函数上的属性时,先去自身找,如果自身没有,去
__proto__
上找(构造该对象的构造函数的原型,xxx.__proto__
),如果构造函数的原型上没有,去该构造函数的原型的__proto__
上找(构造函数的原型的构造函数的原型xxx.__proto__.__proto__
),一直到找到,或者返回null
为止。
2. 例题
const F = function () {}; //构造函数F
const obj = new F(); //构造函数F构造的对象obj
Object.prototype.a = 'chris';
Function.prototype.b = '22';
console.log(obj.a);
console.log(obj.b);
console.log(F.a);
console.log(F.b);
- 首先看
obj.a
,obj
是一个对象,它自身没有a
这个属性,那么去它的构造函数原型(obj.__proto__
)上寻找,它的构造函数是F
,那么该构造函数的原型是F.prototype
,然而依然没有,那么继续找F.prototype.__proto__
,F.prototype
是一个对象,它的构造函数是Object
,因此,找到了Object.prototype
,所以obj.a
输出的是chris
。 - 再看
obj.b
,这里就不再赘述了,从Object.prototype
开始说,在这里依然没找到b
,那么继续向上找Object.prototype.__proto__
,此时返回了null
,所以obj.b
输出的是undefined
。 -
F.a
和F.b
,F
是一个函数,它自身没有a
和b
这两个属性,那么去它的构造函数原型(F.__proto__
)上寻找,它的构造函数是Function
,那么该构造函数的原型是Function.prototype
,然而依然没有a
,但是此时找到了b
,所以F.b
输出的是22
,那么继续找Function.prototype.__proto__
,Function.prototype
是一个对象,它的构造函数是Object
,因此,找到了Object.prototype
,所以F.a
输出的是chris
。
3. 和原型相关的关键字和属性
- instanceof
const obj = {};
function a() {};
console.log(obj instanceof Object); //true
console.log(obj instanceof Function); //false
console.log(a instanceof Object); //true
console.log(a instanceof Function); //true
简单来说,可以把instanceof
当做“是”,例如上述:
“obj
是个对象”,就正确;“obj
是个方法”,很明显这是不正确的。实际上,instanceof
是判断obj
的原型链上是否有Object
的原型。
isPrototypeOf
const obj = {};
function a() {}
console.log(Object.prototype.isPrototypeOf(obj)); //true
console.log(Function.prototype.isPrototypeOf(obj)); //false
console.log(Object.prototype.isPrototypeOf(a)); //true
console.log(Function.prototype.isPrototypeOf(a)); //true
通过isPrototypeOf
来判断obj
的原型链上是否有object
的原型。
hasOwnProperty
Object.prototype.age = '22';
const obj = {
name: 'chris'
}
console.log(obj.name); //chris
console.log(obj.age); //22
console.log(obj.hasOwnProperty('name')); //true
console.log(obj.hasOwnProperty('age')); //false
判断是自身的属性,还是原型上的属性。
Object.create()
Object.prototype.name = 'chris';
const obj = Object.create(Object.prototype);
console.log(obj.name); //chris
以Object.prototype
为obj
的隐式原型创建obj
。