前言
遵循ECMAScript标准,
someObject.[[Prototype]]
符号是用于指向someObject
的原型。从 ECMAScript 6 开始,[[Prototype]]
可以通过Object.getPrototypeOf()
和Object.setPrototypeOf()
访问器来访问。这个等同于 JavaScript 的非标准但许多浏览器实现的属性__proto__
。 但它不应该与构造函数func
的prototype
属性相混淆。被构造函数创建的实例对象的[[Prototype]]
指向func
的prototype
属性。Object.prototype
属性表示Object
的原型对象。
- 注意: 不同的浏览器,输出的
__proto__
也不一样,[[Prototype]]
与__ proto__
是一个东西, 在火狐浏览器还叫<prototype>
..
1、先理解MDN这两句话
1、当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象(object)都有一个私有属性(称之为 proto )指向它的构造函数的原型对象(prototype)。
- 用代码来理解第一句话
//构造对象Person
function Person (name){
this.name = name
}
let personA = new Person('A') //对象personA
console.dir(Person) //构造函数有 __proto__, prototype属性
console.log(personA) //对象有 __proto__属性
console.log(personA.__proto__ === Person.prototype) //true, 对象的__proto__指向构造函数的prototype
2、该原型对象(prototype)也有一个自己的原型对象(proto),层层向上直到一个对象的原型对象为
null
。根据定义,null
没有原型,并作为这个原型链中的最后一个环节。几乎所有 JavaScript 中的对象都是位于原型链顶端的Object
的实例。
- 万物兼对象,对象顶端兼为null
2、继承
属性继承
当我们知道Person.protoType === personA.__proto__的时候,我们就可以完成继承了
//对象personA继承 构造函数的Peron
//构造函数Person
function Person (name){
this.name = name
}
//对象personA
let personA = new Person('A')
//给构造函数的prototype上新增两个属性country和age
Person.prototype.country = 'china'
Person.prototype.age = 0
//给对象增加age属性
personA.age = 12
console.log(personA.country) //china
console.log(personA.age) // 12 ,由此可知,对象的自己属性优先与自己__proto__的属性
总结
- 对象先会去自己属性上找值,如果没有,就会从
__proto__
上找值
继承方法 摘自MDN
var o = {
a: 2,
m: function(){
return this.a + 1;
}
};
console.log(o.m()); // 3
// 当调用 o.m 时,'this' 指向了 o.
var p = Object.create(o);
// p是一个继承自 o 的对象
p.a = 4; // 创建 p 的自身属性 'a'
console.log(p.m()); // 5
// 调用 p.m 时,'this' 指向了 p
// 又因为 p 继承了 o 的 m 函数
// 所以,此时的 'this.a' 即 p.a,就是 p 的自身属性 'a'
原型链
- 我们只要记住,对象的
__proto__
永远指向他的上一级的prototype
function Fn(name) {
this.name = name
}
let f = new Fn('David')
console.log(f.__proto__ === Fn.prototype) //true
console.log(Fn.prototype.__proto__ === Object.prototype) //true
console.log(Object.prototype.__proto__ === null) //对象兼空