0

JavaScript 可以通过多种方式创建对象。

我尝试使用以下代码来避免使用 new 关键字来创建 A 类的新对象。

我的问题是这里的 A.prototype.init() 是否等于 new A()?这对练习有好处吗?为什么?

function A(){
}
A.prototype.init=function(){
    return this;
}

var a = A.prototype.init();
console.log(a);

var a1=new A();
console.log(a1);

jsfiddle

4

3 回答 3

2

您所做的只是返回A.prototype对象。您并没有真正初始化任何东西,也没有使用结果。

console.log(A.prototype === A.prototype.init()); // true

因此,除非您有特定用途,否则我会说,不,这不是一个好习惯。


不确定为什么要避免new,但无论如何,您可以更改构造函数,以便可以在有或没有的情况下调用它,new并且仍然像构造函数一样工作。

function A() {
    var ths = Object.create(A.prototype);

    ths.foo = "bar";

    return ths;
}

现在,如果您使用new. A.prototype不管怎样,你都会得到一个继承自的新对象。

您仍然可以使用.init()方法,但您不妨将逻辑放在构造函数中。


此外,您可以轻松创建一个工厂来处理那一点样板代码。

function Ctor(fn) {
    return function() {
        var ths = Object.create(fn.prototype);
        fn.apply(ths, arguments);
        return ths;
    };
}

所以现在你会像这样创建你的构造函数:

var A = Ctor(function() {
    this.foo = "bar";
});
于 2013-09-17T02:55:47.327 回答
1

您可以new通过使用模块模式封装代码并返回调用构造函数的函数来避免,换句话说:

var A = (function ClassA() {

  // Constructor
  function A(prop) {
    this.prop = prop; // instance property
    this._init();
  }

  // Public methods
  A.prototype = {
    _init: function() {

    }
  };

  // Mini factory to create new instances
  return function(prop) {
    return new A(prop); // well, only one `new`
  };
}());

现在您可以创建新实例而无需new

var a = A('foo'); //=> A { prop: "foo", init: function }
于 2013-09-17T03:00:18.450 回答
0

通常,您可以使用以下命令捕获直接函数调用instanceof

function MyConstructor (a, b, c) {
    if (!(this instanceof MyConstructor)) {
        return new MyConstructor(a, b, c);
    }
    // ...
}

但是没有充分的理由避免使用new. Object.create和其他替代方案可能会对性能产生重大影响。

于 2013-09-17T03:20:11.820 回答