目录
JavaScript中的原型与继承
一. 基本概念
JavaScript 中的对象是通过 “原型” 来继承的。每个对象都有一个原型,它是另一个对象。当你访问一个属性时,如果对象本身没有这个属性,就会去原型上找,一层层向上,直到找到为止,这就是 原型链。
二. 主要内容
1. 对象和原型
每个 JavaScript 对象都有一个“隐藏属性” [Prototype]
(通常通过 proto
访问),它指向另一个对象。这个被指向的对象叫“原型”。
const animal = {
eats: true
};
const rabbit = {
jumps: true
};
rabbit.__proto__ = animal;
console.log(rabbit.eats); // true,继承自 animal
console.log(rabbit.jumps); // true,自己的属性
2. 原型链
如果原型也有原型,就形成了一条链:
rabbit → animal → Object.prototype → null
查找属性时会一层层往上找,直到:
-
找到为止,返回值
-
到达
null
,返回undefined
3. 函数的 .prototype
属性(构造函数)
当你使用构造函数(或者类)创建对象时,JavaScript 会自动把对象的 proto
设置为构造函数的 .prototype
。
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function() {
console.log(`Hi, I'm ${this.name}`);
};
const alice = new Person('Alice');
alice.sayHi(); // Hi, I'm Alice
原理图:
alice.__proto__ === Person.prototype
所以 alice
可以访问 sayHi
方法。
4. ES6 的 class
class Animal {
speak() {
console.log('I can speak');
}
}
class Dog extends Animal {
bark() {
console.log('Woof!');
}
}
const d = new Dog();
d.bark(); // Woof!
d.speak(); // I can speak
实际等价于:
Dog.prototype.__proto__ = Animal.prototype;
三. 总结重点
四. 示例
原型链输出题
function A() {
this.value = 1;
}
A.prototype.getValue = function () {
return this.value;
};
function B() {
A.call(this);
}
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;
const obj1 = new B();
const obj2 = new A();
A.prototype.value = 100;
console.log(obj1.getValue()); // ?
console.log(obj2.getValue()); // ?
console.log(obj1.value); // ?
console.log(obj2.value); // ?
提示(可以从这里思考):
1. obj1
和 obj2
都是怎么来的?
2. 谁的 value
是自己身上的?谁是从原型里找的?
3. 修改 A.prototype.value = 100
对谁有影响?
步骤解析:
第一步:构造对象
const obj1 = new B(); // 触发 B 构造函数 → A.call(this)
const obj2 = new A(); // 触发 A 构造函数
所以 obj1.value = 1
(通过 A.call(this) 赋值),obj2.value = 1
(A 构造函数赋值)。
第二步:原型链分析
obj1 --> B.prototype --> A.prototype --> Object.prototype
obj2 --> A.prototype --> Object.prototype
getValue()
是定义在 A.prototype 上,两个对象都能通过原型链访问到。
第三步:A.prototype.value = 100;
这 不会影响 obj1.value 或 obj2.value,因为它们自己已经有了 value = 1
的属性。
输出结果分析
console.log(obj1.getValue());
-
obj1.getValue()
→ A.prototype.getValue -
this.value
中的this
是指obj1
-
obj1
自己有value = 1
,所以输出:1
输出:1
console.log(obj2.getValue());
-
obj2.getValue()
→ A.prototype.getValue -
this.value
中的this
是obj2
-
obj2
自己也有value = 1
输出:1
console.log(obj1.value);
-
obj1
自己的value
是1
,所以直接返回
输出:1
console.log(obj2.value);
-
同样,
obj2.value = 1
是实例自己的属性
输出:1
原型链结构图
最终结果:
1
1
1
1