JavaScript 通过避免新关键字来创建新对象

javascript create new object by avoiding new keywords

本文关键字:创建 新对象 对象 关键字 JavaScript      更新时间:2023-09-26

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

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

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

function A(){
}
A.prototype.init=function(){
    return this;
}
var a = A.prototype.init();
console.log(a);
var a1=new A();
console.log(a1);

斯菲德尔

您所做的只是返回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";
});

通过使用模块模式封装代码并返回调用构造函数的函数,可以避免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 }

通常您可以使用instanceof捕获直接函数调用:

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

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