推荐答案
constructor 属性是一个指向创建该对象的构造函数的属性。它存在于所有通过构造函数创建的对象上,默认情况下指向该对象的构造函数。这使得我们可以通过实例对象反向获取创建它的构造函数。
instanceof 操作符用于检测构造函数的 prototype 属性是否存在于某个实例对象的原型链上。它的原理是沿着实例对象的原型链向上查找,直到找到匹配的 prototype 属性,如果找到则返回 true,否则返回 false。
本题详细解读
constructor 属性详解
默认指向
每个函数(除了箭头函数)都有一个 prototype 属性,这个 prototype 属性本身是一个对象,并且这个对象有一个 constructor 属性,默认指向该函数本身。当我们使用 new 关键字调用一个构造函数创建实例时,新创建的实例对象会继承构造函数原型上的属性和方法,同时,实例对象自身也会拥有一个 __proto__ (非标准,但浏览器普遍实现,ES6 推荐使用 Object.getPrototypeOf())属性,指向构造函数的 prototype 对象。因此,实例对象可以通过 __proto__ 访问原型对象,并继承原型对象上的 constructor 属性,从而实现可以通过实例对象访问构造函数。
代码示例
// www.javascriptcn.com code example
function Person(name) {
this.name = name;
}
let person1 = new Person('Alice');
console.log(person1.constructor === Person); // true
console.log(Person.prototype.constructor === Person) // true
let person2 = {};
person2.constructor === Object // true,默认对象constructor指向Object
console.log(person1.__proto__.constructor === Person) // true
// 修改原型之后,constructor默认指向也会变化
Person.prototype = {
sayHello: function() {
console.log('hello')
}
}
let person3 = new Person('Bob');
console.log(person3.constructor === Object) // true, 修改prototype指向后,constructor指向Object
// 可以手动纠正constructor
Person.prototype.constructor = Person;
let person4 = new Person('Tom');
console.log(person4.constructor === Person) // true重要性
- 类型检测:虽然
typeof在检测对象时返回"object",constructor可以提供更具体的类型信息。 - 对象创建:可以通过
constructor获取构造函数,进而使用new关键字创建新的实例对象(虽然不常用)。 - 继承关系:在原型链继承中,
constructor是一个重要的属性,有助于维护正确的继承关系。
instanceof 操作符详解
原型链查找
instanceof 操作符的本质是在判断实例对象的原型链上是否存在构造函数的 prototype 属性。它会沿着实例对象的 __proto__ 链向上查找,直到找到目标原型对象,或者到达原型链顶端(null)。
代码示例
// www.javascriptcn.com code example
function Animal() {}
function Dog() {}
Dog.prototype = new Animal();
let myDog = new Dog();
console.log(myDog instanceof Dog); // true, myDog.__proto__ === Dog.prototype
console.log(myDog instanceof Animal); // true, myDog.__proto__.__proto__ === Animal.prototype
console.log(myDog instanceof Object); // true, 沿着原型链向上查找,直到null
console.log([] instanceof Array); // true
console.log([] instanceof Object); // true
console.log(123 instanceof Number) //false
console.log(new Number(123) instanceof Number) // true
注意事项
instanceof主要用于检测对象类型,不能用于检测原始类型(比如string,number,boolean)。instanceof的结果与对象的原型链有关,如果修改了原型链,可能会影响instanceof的判断。- 可以通过Symbol.hasInstance自定义instanceof行为。
- 使用
Object.create(null)创建的对象没有原型链,instanceof操作符会对这些对象返回false。