This tutorial on prototypical inheritance使用以下代码作为Constructable对象的示例:
var Person = function (name) {
this.name = name;
};
var tom = new Person('tom');
但接着说,如果他们想要更改Person
构建的tom
对象,那么应该通过更改Person.prototype
来完成:
Person.prototype.say = function (words) {
alert(this.name + ' says "' + words + '"');
};
但为什么原型(Person
)必须改变?为什么不直接更改Person
:
Person.say = function (words) {
alert(this.name + ' says "' + words + '"');
};
有区别吗?
答案 0 :(得分:2)
在将函数视为构造函数时,函数和返回的对象之间存在重要区别。
Person.say = function()
实际上并没有为函数赋予属性,这是它自己的对象,这对生成的对象没有影响,它继承了Person的原型,被构造函数调用本身内的任何更改所覆盖(因此为什么this.name
仍有效。)
var Person = function (name) {
this.name = name;
};
var tom = new Person('tom');
console.log(tom.__proto__);
// Object {}
Person.prototype.say = function (words) {
alert(this.name + ' says "' + words + '"');
};
console.log(tom.__proto__);
// Object {say: function}
当您在tom
上调用方法时如果tom
没有该方法,则会查看原型,看看是否有方法,您不是要将方法添加到{{ 1}}永远只有它继承的原型。
答案 1 :(得分:1)
以下代码将say
函数绑定到对象原型。创建Person
实例时,将针对this
实例中的数据调用该函数。
Person.prototype.say = function (words) {
alert(this.name + ' says "' + words + '"');
};
以下代码以静态方式将say
函数绑定到对象(因此,每个实例不可用)
Person.say = function (words) {
alert(this.name + ' says "' + words + '"');
};
以下替代方案是这个,它是一个每实例函数,但不绑定到原型,而是按照创建name
的方式创建每个实例的say函数。
仅供参考,不推荐使用此方法(我只是为了完整性而添加此方法) - 建议将实例函数绑定到原型:
var Person = function(name) {
this.name = name;
this.say = function(words) {
alert(this.name + " says " + words);
};
};
Prototype vs Per-instance:
将函数绑定到原型(Person.prototype.say = function...
)会消耗更少的内存,因为在对象的所有实例之间共享一个函数。
每个实例的绑定函数(this.say = function...
)消耗更多内存,因为为每个创建的实例创建了一个函数(没有共享),尽管这样做的优点是能够访问私有成员,这是不可能的使用原型绑定函数。
<强>概述:强>
静态绑定:Person.say = function() { ... }
原型绑定:Person.prototype.say - function() { ... }
实例绑定:function Person() { this.say = function() { ... } ... }
答案 2 :(得分:0)
区别在于记忆占用。
在你的情况下,使用或不使用原型不会改变,因为你只有一个人。
但是如果你创造了大量的金额,每个金额都有自己的说法功能,而不是原型,这个功能将被共享。