参考:http://blog.itpub.net/29900383/viewspace-1827359/
__proto__是每个对象都具有的属性(在W3C标准的浏览器中,我们才可以直接访问);prototype是每个function对象都具有的属性;然而,constructor确是原型对象而非普通实例对象具有的属性,系统自动为原型对象预添加的。
const log = console.log;
function Person(pname) {
this.name = pname;
}
let p = new Person("hhh");
log(p);
问题1:原型对象是怎么来的?什么是原型的继承??
答:其实,在系统载入定义的(任何函数)function Person时,会同时执行:Person.prototype = new Object(); Person.prototype.constructor = Person; 两者的关系的建立是系统底层自动完成的。因此原型对象Person.prototype的所有初始属性都是从Object中继承而来,而Person类的实例对象的初始属性再继承自原型对象,即也是从Object中继承而来,此乃原型继承。是故,可以理解为:Object类是所有类的父类。
如下一个例子:
Object.prototype.appleCount = 1000;//所有实例对象都会具有appCount属性!!!
console.log(p1.appleCount);//打印:1000
问题2:当实例对象和其原型具有部分同名属性时,js引擎会如何选择?
当实例对象和其原型具有部分同名属性时的一种情况:
var base = {
name: "base",
getName: function() {
console.log(this.name); //会打印
}
}
var p1 = {
name: "p1",
}
p1.__proto__ = base;
p1.getName(); //!!!!打印出 p1
这里有点类似于java中的:覆盖!!!可以理解为:父类的引用指向子类的对象!!
js对象产生对象的底层模拟:
//首先我们有一个Person函数:
function Person(){this.name = "luozhixiao";}
//1)当加载函数Person时,创建Person函数对象,然后执行:
Person.prototype = {};
Person.prototype.constructor = Person;
//2)当我们执行:new Person() 创建类对象时,底层实现模拟如下:
var __Person_Obj__ = {};
__Person_Obj__.__proto__ = Person.prototype;//这里是重点!
Person.apply(__Person_Obj__);