原型分为隐式原型(prototype)和显式原型(__proto__)
- 显式原型:全部函数且仅限函数有prototype属性,只不过不是构造函数,prototype属性没有意义
- 隐式原型:所有引用类型都有__proto__属性,数组、函数、对象...
function A () {
this.name = 'a';
}
A.prototype.print = function () {
console.log('print is called');
}
const B = new A();
B.print();
// 输出:print is called
实例B调用print,会现先查找当前实例,没有找到print方法;
实例B和A之间存在一个隐式链接,实例B的__proto__属性会指向A.prototype,__proto__就起到了“链”的作用,通过原型链实例B也可以调用A.prototype上的函数。
function A () {
this.name = 'a';
}
A.prototype.name = 'x';
const B = new A();
console.log(B.name);
// 输出:a
Object.prototype.age = 18;
const C = new A();
console.log(C.age);
// 输出:18
console.log(C.gender);
// 输出:undefined
原型链遵循就近原则,当前实例有name属性时,会使用当前实例的属性,当当前实例不存在age属性时,会根据__proto__向上查找,直到找到Object.prototype,如果仍然不存在则返回undefined