JavaScript OOP:带或不带“原型”的方法定义

时间:2012-05-08 14:06:22

标签: javascript oop methods prototype

这是代码,

function Person() {
    function  myMethod() {
        alert ('hello');
    }
    this.method = myMethod;
}

相当于:

function Person() {    }
Person.prototype.method2  = function() {
    alert ('hello');
};

如果是,我应该使用哪种方法定义以及为什么?

5 个答案:

答案 0 :(得分:13)

它们在您的简单示例中功能相同,但幕后工作方式却截然不同。函数上的prototype属性实际上是“原型模板”。它说“无论何时制作一个对象,我都被用作对象的构造函数,给它们这个对象作为它们的原型”。

因此,在第二个示例中创建的所有Person共享method2方法的同一副本。

在第一个示例中,每次解释器遇到function关键字时,它都会创建一个新的函数对象。因此,在第一个示例中,Person的每个实例都有自己的myMethod方法副本。绝大多数时候这无关紧要。但是这第一种方法使用更多的内存,有时这很重要。

在更有趣的案例中,它们在功能上并不相同。在第一个示例中,myMethod可以访问Person中定义的局部变量,但第二个示例不能作为一个区别。

答案 1 :(得分:2)

在第一个方案中,当您创建新人var person1 = new Person();时,它将拥有自己的myMethod副本。如果您创建100个Person对象,则每个对象都有自己的此方法副本。

使用原型,每个新的Person对象将共享方法定义。这样的内存效率更高,因为只有一个方法副本。

如果您计划使用多个Person对象,第二种方式更好..但如果只有少数Person对象,那就没那么重要了。

答案 2 :(得分:1)

它并不完全等同。

在这两种情况下,您都可以在全局命名空间中定义一个函数(构造函数)Person()

在第一种情况下,在myMethod()函数内的闭包中定义一个新函数Person()。通常,在函数/构造函数myMethod()完成后,Person()函数将不可用。但是,在这种情况下,您将其分配给this.method。因此,当您运行构造函数

var myPerson = new Person();

创建一个新对象,然后调用Person()函数并将this设置为新对象。因此,您的新对象会收到method字段,并绑定myMethod函数。

在第二种情况下,method2内定义了Person.prototype。在这种情况下,当你打电话

var myPerson = new Person();

在新对象中不会直接定义字段(因为您在函数this中对Person不执行任何操作)。但是,每个对象都包含对其原型的引用。如果通过调用Person()创建对象,则此引用设置为Person.prototype。因此,您的对象最终将包含method2,虽然不是直接本身,但在原型中。所以当你打电话时

myPerson.method2();

解释器在method2对象中查找myPerson并找不到任何内容,然后查看myPerson的原型,Person.prototype并查找method2 ,所以它称之为。

长话短说:在第一个构造函数创建方法时,每次调用构造函数时,都会创建一个新方法并将其插入到新对象中。在第二种情况下,该方法存储在原型中,因此您创建的每个对象都将引用您方法的同一实例。

答案 3 :(得分:0)

不,他们不等同。虽然,他们是相似的。第一种方法将为每个创建的myMethod创建一个新函数new Person()

第二种方法将有一个由method2“共享”的函数Person's

答案 4 :(得分:0)

它们具有相似的功能,但您应该使用第二种方法(原型),因为当您使用new Person()创建对象时,每个对象将共享相同的method2,但使用第一种方法,每个新对象将让它拥有自己的myMethod()消耗moe记忆。

前几天我问了一个类似的问题并得到了 this answer