改变[object] .prototype与[object]的嵌套函数

时间:2014-07-18 10:07:39

标签: javascript oop prototypal-inheritance

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 + '"');
};

有区别吗?

3 个答案:

答案 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)

区别在于记忆占用。

在你的情况下,使用或不使用原型不会改变,因为你只有一个人。

但是如果你创造了大量的金额,每个金额都有自己的说法功能,而不是原型,这个功能将被共享。