javascript 有自己独特的属性查询机制(依靠原型链)
当调用对象的属性时会一步一步链式往上查找直到找到属性或到顶层对象(null),如:
function A(){}
const a = new A()
A是一个构造函数,a是通过构造函数生成的一个实例,函数在js中本身也是一个对象
函数有prototype属性(对象)
对象有constructor和原型对象(__proto__属性或者通过Object.getPrototypeOf函数获取的对象)
对象的原型对象指向该对象构造函数的prototype属性
# 构造函数拥有默认的prototype属性,属性是一个对象{constructor:指向自己, [一些其他扩展属性]},该prototype属性用于在通过new关键字创建对象时生成对象的父对象,所以通过new关键词创建的对象会有一个constructor属性指向创建自身的函数,但这个函数是不可靠的(构造函数在创建的时候可以任意修改prototype属性)。
1. 所以 A 有默认的prototype = {constructor:A},通过A生成的a的父对象也就等于{constructor:A},当我们使用a.constructor时,由于自身没有该属性,所以查找父对象{constructor:A}获得;
2. 由于函数本身是个对象,且是由Function创建,所以A的父对象为{constructor:Function};
3. 像{constructor:A},{constructor:Function} 这种对象默认是由Object()创建,所以这类对象的父对象为Object.prototype;
4. Object()这个函数也是由Function创建,所以父对象为{constructor:Function};
5. 如果获取对象属性没有,会沿着原型链层层往上找,知道找到或者到达顶层;
如下:
表格1(A) | ||
键 | 值 | |
A.prototype | 对象 | |
A.constructor | Function | 见表格5 |
Object.getPrototypeOf(A) | Function.prototype | 见表格6 |
表格2(A.prototype) | ||
键 | 值 | |
A.prototype.constructor | A | 见表格1 |
Object.getPrototypeOf(A.prototype) | Object.prototype | 见表格3 |
表格3(Object.prototype) | ||
键 | 值 | |
Object.prototype.constructor | Object | 见表格4 |
Object.getPrototypeOf(Object.prototype) | null |
表格4(Object) | ||
键 | 值 | |
Object.prototype | 对象 | |
Object.constructor | Function | 见表格5 |
Object.getPrototypeOf(Object) | Function.prototype | 见表格6 |
表格5(Function) | ||
键 | 值 | |
Function.prototype | 对象 | |
Function.constructor | Function | 见表格5 |
Object.getPrototypeOf(Function) | Function.prototype | 见表格6 |
表格6(Function.prototype) | ||
键 | 值 | |
Function.prototype.constructor | Function | 见表格5 |
Object.getPrototypeOf(Function.prototype) | Object.prototype | 见表格3 |
表格7(a) | ||
键 | 值 | |
a.constructor | A | 见表格1 |
Object.getPrototypeOf(a) | A.prototype | 见表格2 |
function A(){}; const a = new A();
console.log(a.constructor === A);
console.log(Object.getPrototypeOf(a) === A.prototype);
console.log(A.constructor===Function); console.log(Object.getPrototypeOf(A) === Function.prototype);
console.log(A.prototype.constructor === A); console.log(Object.getPrototypeOf(A.prototype) === Object.prototype);
console.log(Object.prototype.constructor === Object); console.log(Object.getPrototypeOf(Object.prototype) === null);
console.log(Object.constructor === Function); console.log(Object.getPrototypeOf(Object) === Function.prototype);
console.log(Function.constructor === Function);
console.log(Object.getPrototypeOf(Function) === Function.prototype);
console.log(Function.prototype.constructor === Function);
console.log(Object.getPrototypeOf(Function.prototype) === Object.prototype);