显式原型与隐式原型
-
prototype
: 显式原型 -
__proto__
: 隐式原型 -
所有函数都有
prototype
属性, 这个属性是一个对象 -
构造函数(比如: User)的
prototype
对象默认有一个constructor
属性, 这个constructor
属性指向prototype
属性所在的构造函数(User) -
通过
new
构造函数的到的实例对象(比如: u1)都有一个__proto__
属性, 这个属性是一个对象, 实例对象(u1)的__proto__
属性指向构造函数(User)的prototype
属性
[图片上传失败...(image-a20030-1573994009396)]
// User: 构造函数
// u1: 实例对象
function User () {
// code...
}
let u1 = new User();
console.log(User.prototype === u1.__proto__); // true
console.log(User.prototype.constructor === User); // true
JS 数组的原型链
[图片上传失败...(image-9b9bae-1573994009396)]
JS Date的原型链
[图片上传失败...(image-dc09a-1573994009396)]
JS对象原型链检索规则
- 一个对象调用属性时, 首先自身查找对应的属性
- 如果自身有对应的属性, 则返回该该属性对应的值
- 如果自身没有对应得属性, 则向上级原型对象中查找,
- 如果原型对象中有, 则返回对应属性的值
- 如果没有再依次向上级查找, 找到就立即返回对应属性的值
- 如果到原型链的末端都没有找到就返回
undefined
// ---- 实例代码1 -----
function Person (name) {
this.name = name;
}
Person.prototype.age = 10;
let p1 = new Person("tom");
console.log(p1.name); // tom: 自身的name属性
console.log(p1.age); // 10: 原型链上的 age 属性
console.log(p1.toString()); // [object Object]: 依次向上查找, 最终找到了Object的 toString() 方法
console.log(p1.sex); // undefined: 原型链上没有这个属性
// ---- 实例代码2 -----
function One() {}
function Two() {}
Two.prototype.toString = function () {
return "Two 原型上的 toString 方法";
}
function Three() {
this.toString = function() {
return "Three 实例对象上的 toString 方法";
}
}
Three.prototype.toString = function () {
return "Three 原型上的 toString 方法";
}
let obj1 = new One();
let obj2 = new Two();
let obj3 = new Three();
console.log( obj1.toString() ); // [object Object]: 这是Object上的toString方法
console.log( obj2.toString() ); // Two 原型上的 toString 方法
console.log( obj3.toString() ); // Three 实例对象上的 toString 方法
综上所述, 总结一句话就是: JS对象原型链检索规则是
就近原则
网友评论