原型链
JavaScript 规定,所有对象都有自己的原型对象(prototype)。一方面,任何一个对象,都可以充当其他对象的原型;另一方面,由于原型对象也是对象,所以它也有自己的原型。因此,就会形成一个“原型链”(prototype chain):对象到原型,再到原型的原型……
如果一层层地上溯,所有对象的原型最终都可以上溯到Object.prototype,即Object构造函数的prototype属性。也就是说,所有对象都继承了Object.prototype的属性。这就是所有对象都有valueOf和toString方法的原因,因为这是从Object.prototype继承的。
那么,Object.prototype对象有没有它的原型呢?回答是Object.prototype的原型是null。null没有任何属性和方法,也没有自己的原型。因此,原型链的尽头就是null。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// 构造函数
function A(){
this.age = 11;
this.method = function (){
console.log("this is A’s function");
}
}
// 模拟类
let a1 = new A();
// 访问属性
console.log(a1.age); // 11
// 访问方法
a1.method(); // this is A’s function
// 这种声明属性和方法的缺点就是多个实例不能共享方法
let a2 = new A();
console.log(a1.method === a2.method); // false
// 如何实现共享
// 使用对象的原型属性 prototype
A.prototype.one = function(){
console.log("this is A's one function");
}
let a3 = new A();
let a4 = new A();
console.log(a3.one === a4.one); //true
// 当实例对象中本来存在属性 age = 11,
// 后面再通过 prototype.age = 12 设置原型属性
// 是不会覆盖掉原来的 age = 11 的
// 方法也一样
A.prototype.age = 12;
A.prototype.method = function(){
console.log("this is other method");
}
let a5 = new A();
console.log(a5.age); // 11
a5.method();
// 构造函数之间的继承
function B(){
this.age = 15;
}
// 方法一:
// 可以继承构造方法A “原有” 的所有属性和方法
B.prototype = new A();
let b1 = new B();
console.log("b1 constructor:", b1.constructor);
console.log("b1 instanceof A:",b1 instanceof A);
console.log("b1.age:",b1.age); // 11
b1.method(); // this is A’s function
b1.one(); // this is A's one function
// 方法二: 推荐
// 可以继承构造方法A的所有属性和方法
function C(){
}
C.prototype = Object.create(A.prototype);
let c1 = new C();
console.log("c1 constructor:", c1.constructor);
console.log("c1 instanceof A:",c1 instanceof A);
console.log(c1.age); // 12
c1.method(); // this is other method
c1.one(); // this is A's one function
// 方法三:
//
function D(){
this.name = 'D';
}
D.prototype = A.prototype;
D.prototype.age = 13;
//该操作会改变构造方法A的原型
D.prototype.constructor = D
let a6 = new A();
console.log("a6.age:",a6.age);
let d1 = new D();
console.log("d1 instanceof A:",d1 instanceof A);
console.log(d1.age); // 12
d1.method(); // this is other method
d1.one(); // this is A's one function
// 多重继承
function E() {
A.call(this);
D.call(this);
}
E.prototype = Object.create(A.prototype);
Object.assign(E.prototype, D.prototype);
E.prototype.constructor = E;
let e1 = new E();
console.log(e1.age); // 11
console.log(e1.name); // D
</script>
</body>
</html>
参考:https://wangdoc.com/javascript/oop/prototype.html#%E5%8E%9F%E5%9E%8B%E9%93%BE