return与new关键字Constructor模式之间的区别是什么?

时间:2016-06-27 18:35:49

标签: javascript object javascript-objects

考虑以下代码:

var Animal = function(name) {
  return {
    name: name,
    speak: function() { return "My name is " + name; }
  };
};

var cat = Animal("Kitty");

我的问题是:上述代码与以下代码之间在性能,约定或最佳实践方面有何不同:

var Animal = function(name) {
  this.name = name,
  this.speak = function() { return "My name is " + name; }
};

var cat = new Animal("Another Kitty");

哪一个更好? new关键字有哪些用例?

2 个答案:

答案 0 :(得分:1)

当您考虑原型(以及它们控制的所有内容,如继承)时,它们完全不同。例如:

var SimpleAnimal = function(name) {
  return {
    name: name,
    speak: function() { return "My name is " + name; }
  };
};

var RealAnimal = function(name) {
  this.name = name,
  this.speak = function() { return "My name is " + name; }
};

var simpleCat = SimpleAnimal("Kitty");
var realCat = new RealAnimal("Another Kitty");

console.log(simpleCat instanceof SimpleAnimal, realCat instanceof RealAnimal); // simple is not an instance of the constructor
console.log(simpleCat.constructor, realCat.constructor); // because it uses the object literal constructor

缺少原型(和继承)意味着您的对象不会接收在类原型上定义的任何方法:

var SimpleAnimal = function(name) {
  return {
    name: name,
    speak: function() {
      return "My name is " + name;
    }
  };
};

SimpleAnimal.prototype.roar = function() {
  console.log("roar!");
};

var RealAnimal = function(name) {
  this.name = name,
    this.speak = function() {
      return "My name is " + name;
    }
};

RealAnimal.prototype.roar = function() {
  console.log("roar!");
};

var simpleCat = SimpleAnimal("Kitty");
var realCat = new RealAnimal("Another Kitty");

try { simpleCat.roar(); } catch (e) { console.error(e); }
realCat.roar();

答案 1 :(得分:1)

第一个版本返回一个简单的Object,第二个版本创建一个新的Animal。

第一个版本适用于小型数据对象。他们可以存储不同的价值观,而这几乎就是它。他们不需要大量的记忆。

第二个是更大的物体。您可以将原型附加到它们并使用"这个"用于访问对象属性的关键字。因为每个对象都具有相同的属性,所以它们比第一种方法占用更多的空间。

让我们采取以下措施并创建一个矢量对象。使用第一种方法,您可以执行以下操作:

function createVector(x, y) {
    return {
        x: x,
        y: y
    };
}

//Add to vectors together
function add(vec1, vec2) {
    return {x: vec1.x + vec2.x, y: vec1.y + vec2.y};
}

add(createVector(1, 1), createVector(1, 2)); //return {x: 2, y: 3}

这可能非常有用,但是如果你想拥有多种类型的矢量(3维,4维等等)呢?您需要为加法器函数指定一个单独的名称,这不是很好。这是第二种方法的用武之地。它可以将函数分成不同的名称空间:

function Vector2(x, y) {
    this.x = x;
    this.y = y;
}

//Add vectors together:
Vector2.prototype.add = function(vec) {
    this.x += vec.x;
    this.y += vec.y;
};

new Vector2(1, 1).add(new Vector2(1, 2)); //{x: x, y: y}

这样,您可以创建多个矢量类型,并且每个矢量类型都可以具有单独的添加功能,而不会相互干扰。

您应该根据您想要达到的目标使用它们。