构造函数、原型对象、构造器是一体的关系,同时产生;
实例中的隐藏属性__proto__指向原型对象;
原型对象是这四种关系的纽带。
原型对象是动态的,不论在何处变化,实例中可以立即体现出来。
var Person = function(name) { this.name = name; }; var p1 = new Person("Nicholas"); Person.prototype.say = function() { console.log(this.name); }; /* * 原型对象具有动态性 * 不论在何处添加的属性,可以立即在实例中调用 */ p1.say(); // Nicholas /* * 有构造函数必有原型对象 * 有原型对象,其中必有构造器属性 * 原型对象中的特殊属性构造器指向构造函数本身 */ console.log(Person.prototype.constructor === Person); // true /* * 实例中的原型属性指向构造函数的原型对象 * 实例中的指针仅指向原型对象,而不指向构造函数 */ console.log(p1.__proto__ === Person.prototype); // true
重写整个原型会使其失去动态性,丢失构造器
var Person = function(name) { this.name = name; }; /* * 这种写法使原型不再具有动态性 * 且丢失了Person.prototype.constructor */ Person.prototype = { say: function() { console.log(this.name); } }; // 实例必须在原型对象声明之后才能调用原型中的方法 var p1 = new Person("Nicholas"); p1.say(); // Nicholas console.log(Person.prototype.constructor === Person); // false console.log(p1.__proto__ === Person.prototype); // true
Douglas Object.create
// Douglas Object.create 这是基于原型的继承 if (typeof Object.create !== "function") { Object.create = function (obj) { var F = function () {}; F.prototype = obj; return new F(); }; } var person = { name: "lily", friends: ["poly", "lucy"] }; // 整个person对象成为了person2的原型对象 var person2 = Object.create(person); person2.name = "Lilei"; // 修改了原型对象,也既是person对象 person2.friends.push("Hanmeimei"); console.log(person.friends); // ["poly", "lucy", "Hanmeimei"]