什么是constructor
•JavaScript中constructor属性指向创建当前对象的构造函数,该属性是存在原型里的,且是不可靠的 JavaScript中constructor属性
function test() {}
const obj = new test();
console.log(obj.hasOwnProperty('constructor')); // false
console.log(obj.__proto__.hasOwnProperty('constructor')); // true
console.log(obj.__proto__ === test.prototype); // true
console.log(test.prototype.hasOwnProperty('constructor')); // true
/** 堆代码 duidaima.com */
/** constructor是不可靠的 */
function Foo() {}
Foo.prototype = {};
const foo = new Foo();
console.log(foo.constructor === Object); // true,可以看出不是Foo了
•constructor也是一种用于创建和初始化class[3]创建的对象的特殊方法 Class构造方法[4]
几个典型的constructor:
(async function(){})().constructor === Promise
// 浏览器环境下
this.constructor.constructor === Function
window.constructor.constructor === Function
// 堆代码 duidaima.com
// node环境下
this.constructor.constructor === Function
global.constructor.constructor === Function
JS Proxy getPrototypeOf()
handler.getPrototypeOf()是一个代理方法,当读取代理对象的原型时,该方法就会被调用。语法:
const p = new Proxy(obj, {
getPrototypeOf(target) { // target 被代理的目标对象。
...
}
});
当 getPrototypeOf 方法被调用时,this 指向的是它所属的处理器对象,getPrototypeOf 方法的返回值必须是一个对象或者 null。在 JavaScript 中,有下面这五种操作(方法/属性/运算符)可以触发 JS 引擎读取一个对象的原型,也就是可以触发 getPrototypeOf() 代理方法的运行:
•Object.getPrototypeOf()
•Reflect.getPrototypeOf()
•proto
•Object.prototype.isPrototypeOf()
•instanceof
如果遇到了下面两种情况,JS 引擎会抛出 TypeError 异常:
•getPrototypeOf() 方法返回的不是对象也不是 null。
•目标对象是不可扩展的,且 getPrototypeOf() 方法返回的原型不是目标对象本身的原型。
基本用法:
const obj = {};
const proto = {};
const handler = {
getPrototypeOf(target) {
console.log(target === obj); // true
console.log(this === handler); // true
return proto;
}
};
var p = new Proxy(obj, handler); // obj是被代理的对象,也就是handler.getPrototypeOf的target参数
console.log(Object.getPrototypeOf(p) === proto); // true
5 种触发 getPrototypeOf 代理方法的方式:
const obj = {};
const p = new Proxy(obj, {
getPrototypeOf(target) {
return Array.prototype;
}
});
console.log(
Object.getPrototypeOf(p) === Array.prototype, // true
Reflect.getPrototypeOf(p) === Array.prototype, // true
p.__proto__ === Array.prototype, // true
Array.prototype.isPrototypeOf(p), // true
p instanceof Array // true
);
两种异常的情况:
// getPrototypeOf() 方法返回的不是对象也不是 null
const obj = {};
const p = new Proxy(obj, {
getPrototypeOf(target) {
return "foo";
}
});
Object.getPrototypeOf(p); // TypeError: "foo" is not an object or null
// 目标对象是不可扩展的,且 getPrototypeOf() 方法返回的原型不是目标对象本身的原型
const obj = Object.preventExtensions({}); // obj不可扩展
const p = new Proxy(obj, {
getPrototypeOf(target) {
return {};
}
});
Object.getPrototypeOf(p); // TypeError: expected same prototype value
// 如果对上面的代码做如下的改造就没问题
const obj = Object.preventExtensions({}); // obj不可扩展
const p = new Proxy(obj, {
getPrototypeOf(target) { // target就是上面的obj
return obj.__proto__; // 返回的是目标对象本身的原型
}
});
Object.getPrototypeOf(p); // 不报错