|
|
|
|
@ -0,0 +1,143 @@
|
|
|
|
|
## constructor 属性的详细解释
|
|
|
|
|
|
|
|
|
|
### 基本概念
|
|
|
|
|
|
|
|
|
|
**constructor** 是原型对象上的一个属性,它指向创建当前实例对象的构造函数。
|
|
|
|
|
|
|
|
|
|
### 各层级的 constructor 指向
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
Person.prototype.constructor → Person
|
|
|
|
|
Function.prototype.constructor → Function
|
|
|
|
|
Object.prototype.constructor → Object
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 实际示例
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
function Person(name) {
|
|
|
|
|
this.name = name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const p1 = new Person("张三");
|
|
|
|
|
|
|
|
|
|
// 验证 constructor 指向
|
|
|
|
|
console.log(p1.constructor === Person); // true
|
|
|
|
|
console.log(Person.prototype.constructor === Person); // true
|
|
|
|
|
console.log(Function.prototype.constructor === Function); // true
|
|
|
|
|
console.log(Object.prototype.constructor === Object); // true
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 完整的 constructor 链式关系
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
p1.constructor → Person.prototype.constructor → Person
|
|
|
|
|
|
|
|
|
|
Person.constructor → Function.prototype.constructor → Function
|
|
|
|
|
|
|
|
|
|
Function.constructor → Function.prototype.constructor → Function
|
|
|
|
|
(Function 的构造函数是它自身)
|
|
|
|
|
|
|
|
|
|
Object.constructor → Function.prototype.constructor → Function
|
|
|
|
|
(Object 的构造函数是 Function)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### constructor 属性的工作原理
|
|
|
|
|
|
|
|
|
|
1. **原型继承机制**:
|
|
|
|
|
```javascript
|
|
|
|
|
// 当访问 p1.constructor 时:
|
|
|
|
|
// 1. p1 对象本身没有 constructor 属性
|
|
|
|
|
// 2. 沿着原型链查找:p1.__proto__ → Person.prototype
|
|
|
|
|
// 3. 在 Person.prototype 上找到 constructor 属性
|
|
|
|
|
// 4. 该 constructor 指向 Person 函数
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
2. **constructor 的重写**:
|
|
|
|
|
```javascript
|
|
|
|
|
function Person() {}
|
|
|
|
|
|
|
|
|
|
// 默认情况下
|
|
|
|
|
console.log(Person.prototype.constructor === Person); // true
|
|
|
|
|
|
|
|
|
|
// 如果重写 prototype
|
|
|
|
|
Person.prototype = {
|
|
|
|
|
// 必须手动指定 constructor,否则会丢失
|
|
|
|
|
constructor: Person,
|
|
|
|
|
sayHello: function() {}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 如果不手动指定 constructor
|
|
|
|
|
Person.prototype = {
|
|
|
|
|
sayHello: function() {}
|
|
|
|
|
};
|
|
|
|
|
console.log(Person.prototype.constructor === Person); // false
|
|
|
|
|
console.log(Person.prototype.constructor === Object); // true
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 实际应用场景
|
|
|
|
|
|
|
|
|
|
1. **类型判断**:
|
|
|
|
|
```javascript
|
|
|
|
|
const arr = [];
|
|
|
|
|
console.log(arr.constructor === Array); // true
|
|
|
|
|
|
|
|
|
|
const obj = {};
|
|
|
|
|
console.log(obj.constructor === Object); // true
|
|
|
|
|
|
|
|
|
|
const num = 123;
|
|
|
|
|
console.log(num.constructor === Number); // true
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
2. **实例创建**:
|
|
|
|
|
```javascript
|
|
|
|
|
function Person(name) {
|
|
|
|
|
this.name = name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const p1 = new Person("张三");
|
|
|
|
|
|
|
|
|
|
// 通过 constructor 创建新实例
|
|
|
|
|
const p2 = new p1.constructor("李四");
|
|
|
|
|
console.log(p2.name); // "李四"
|
|
|
|
|
console.log(p2 instanceof Person); // true
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
3. **原型链中的 constructor**:
|
|
|
|
|
```javascript
|
|
|
|
|
function Animal() {}
|
|
|
|
|
function Dog() {}
|
|
|
|
|
|
|
|
|
|
// 设置继承关系
|
|
|
|
|
Dog.prototype = Object.create(Animal.prototype);
|
|
|
|
|
|
|
|
|
|
// 修复 constructor 指向
|
|
|
|
|
Dog.prototype.constructor = Dog;
|
|
|
|
|
|
|
|
|
|
const dog = new Dog();
|
|
|
|
|
console.log(dog.constructor === Dog); // true
|
|
|
|
|
console.log(dog instanceof Dog); // true
|
|
|
|
|
console.log(dog instanceof Animal); // true
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 总结要点
|
|
|
|
|
|
|
|
|
|
1. **constructor 的位置**:在原型对象上,不在实例对象上
|
|
|
|
|
2. **默认指向**:指向创建该原型对象的构造函数
|
|
|
|
|
3. **可修改性**:constructor 属性可以被修改或覆盖
|
|
|
|
|
4. **查找路径**:实例对象访问 constructor 时会沿着原型链查找
|
|
|
|
|
5. **特殊案例**:
|
|
|
|
|
- `Function.prototype.constructor` 指向 `Function`
|
|
|
|
|
- `Object.prototype.constructor` 指向 `Object`
|
|
|
|
|
- 函数对象的构造函数是 `Function`
|
|
|
|
|
- 对象实例的构造函数是创建它的函数
|
|
|
|
|
|
|
|
|
|
### 内存示意图
|
|
|
|
|
```
|
|
|
|
|
p1 (实例) Person.prototype Function.prototype
|
|
|
|
|
┌─────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
|
|
|
│ │ __proto__ → │ constructor │ → Person │
|
|
|
|
|
│ ├──────────────→ │ │ │ constructor │ → Function
|
|
|
|
|
│ │ │ other props... │ │ │
|
|
|
|
|
└─────────┘ └─────────────────┘ └─────────────────┘
|
|
|
|
|
```
|