在JS中围绕原型进行包装

时间:2013-04-03 20:39:50

标签: javascript prototype

我一直在努力理解JS中原型的概念,但出于某种原因,我发现它真的令人费解。为什么以及何时使用原型?

这之间有什么区别(来自MDN example):

function Person(gender) {
  this.gender = gender;
}

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

而且:

function Person(gender) {
  this.gender = gender;

  this.sayHello = function() {
    alert('hello');
  };
}

我想我明白了如何使用它们,但我不知道为什么要使用它们。也许我错过了一些东西 - 划伤那个 - 很明显我错过了什么!

有人可以解释一下这两个例子之间的区别以及为什么我应该使用另一个例子?

谢谢!

4 个答案:

答案 0 :(得分:1)

使用原型示例创建new Person()时,它不会使用person对象将sayHello()加载到内存中。

相反,它会在需要/调用时立即将它添加到对象中,并且只在它被加载时才加载一次。

使用大量对象时,可以为用户节省大量内存。

答案 1 :(得分:1)

类和继承。而不是花一两个小时自己解释它我强烈建议通过这个小tutorial.我跳过原型的部分,并以一种有趣的方式解释它。

答案 2 :(得分:1)

Person是一个构造函数,每次创建一个新实例时都会执行它。构造函数只是函数,函数只是JavaScript中的对象。函数可以具有属性f.a = 1,就像基本对象一样:o = {a: 1}

当您将函数添加为对象的属性时,它被称为方法。因此,通过在构造函数中定义Person的方法,可以在实例化时重新定义它们。正如已经指出的那样,这是额外的工作。

通过使用函数的prototype属性预先定义方法,方法只定义一次。

在原型上定义方法的另一个好处是它们变得静态。静态方法不需要实例对象。例如,可以在数组实例上调用数组切片方法:[1,2,3].slice(1)。但是如果我们没有数组实例,我们仍然可以从Array对象的原型中访问和调用slice方法:Array.prototype.slice.call(arguments)

编辑:静态方法更常见的是Object.method,不一定是原型的属性。应该澄清的是,实例方法.slice()是静态调用的。

答案 3 :(得分:1)

原型对于继承很重要。如果你不需要继承,那么确实没有区别。但是,请考虑一下:

function Person(gender) {
 this.gender = gender;

 this.sayHello = function() {
  alert('hello');
 };
}

function User(){

}

User如何成为Person?这里真的没有简单的方法。但是,这可以通过原型实现:

<强> jsFiddle Demo

function Person(name) {
 this.name = name;
}

Person.prototype.sayHello = function() {
  alert(this.name);
 };

function User(name){
 this.constructor(name);
}

User.prototype = new Person();

var u = new User("joe");
u.sayHello();//alerts joe

现在,我们可以更进一步,并在使用这样的原型时覆盖为用户打招呼的功能:

<强> jsFiddle Demo

User.prototype.sayHello = function(){ 
 alert("Username: " + this.name);
}