JavaScript的:如何在不使用new关键字创建类的新实例?([removed] How to

2019-08-19 11:36发布

我想下面的代码将会使问题清晰。

// My class
var Class = function() { console.log("Constructor"); };
Class.prototype = { method: function() { console.log("Method");} }

// Creating an instance with new
var object1 = new Class();
object1.method();
console.log("New returned", object1);

// How to write a factory which can't use the new keyword?
function factory(clazz) {
    // Assume this function can't see "Class", but only sees its parameter "clazz".
    return clazz.call(); // Calls the constructor, but no new object is created
    return clazz.new();  // Doesn't work because there is new() method
};

var object2 = factory(Class);
object2.method();
console.log("Factory returned", object2);

Answer 1:

没有这方面的工作?

function factory(class_) {
    return new class_();
}

我不明白你为什么不能用new



Answer 2:

一种更简单,更清洁,无“工厂”的方式

function Person(name) {
  if (!(this instanceof Person)) return new Person(name);
  this.name = name;
}

var p1 = new Person('Fred');
var p2 = Person('Barney');

p1 instanceof Person  //=> true
p2 instanceof Person  //=> true


Answer 3:

如果你真的不想使用new关键字,你不介意只支持Firefox,可以自己设置的原型。 有没有真正的任何一点这虽然,因为你可以使用戴夫韩丁的答案。

// This is essentially what the new keyword does
function factory(clazz) {
    var obj = {};
    obj.__proto__ = clazz.prototype;
    var result = clazz.call(obj);
    return (typeof result !== 'undefined') ? result : obj;
};


Answer 4:

我想独立于浏览器的解决方案会更好

function empty() {}

function factory(clazz /*, some more arguments for constructor */) {
    empty.prototype = clazz.prototype;
    var obj = new empty();
    clazz.apply(obj, Array.prototype.slice.call(arguments, 1));
    return obj;
}


Answer 5:

因为JavaScript没有课,让我改写你的问题:如何在不使用new关键字创建基于现有对象的新对象?

这里不使用“新”的方法。 这不是严格意义上的“新情况”,但它是我能想到的,不使用“新”的唯一方法(和不使用任何的ECMAScript 5功能)。

//a very basic version that doesn't use 'new'
function factory(clazz) {
    var o = {};
    for (var prop in clazz) {
        o[prop] = clazz[prop];
    }
    return o;
};

//test
var clazz = { prop1: "hello clazz" };
var testObj1 = factory(clazz);
console.log(testObj1.prop1);    //"hello clazz" 

你可以得到看中,并设置原型,但随后你进入跨浏览器的问题,我想保持这种简单。 您可能还需要使用“hasOwnProperty”筛选您添加到新的对象,它的属性。

有迹象表明,用“新”,而是那种隐藏其他方式。 这是一个从功能的Object.create借用JavaScript的:由Douglas Crockford的好的部分 :

//Another version the does use 'new' but in a limited sense
function factory(clazz) {
    var F = function() {};
    F.prototype = clazz;
    return new F();
};

//Test
var orig = { prop1: "hello orig" };
var testObj2 = factory(orig);
console.log(testObj2.prop1);  //"hello orig"

EcmaScript的5拥有的Object.create方法,它会做这么多更好,但仅在新的浏览器支持(例如,IE9,FF4),但你可以使用填充工具 (的东西,在夹缝中填充),如ES5垫片 ,以获得对旧版浏览器的实现。 (见约翰Resig的新ES5文章功能,包括的Object.create )。

在ES5你可以做这样的:

//using Object.create - doesn't use "new"
var baseObj = { prop1: "hello base" };
var testObj3 = Object.create(baseObj);
console.log(testObj3.prop1);

我希望帮助



Answer 6:

其他方式:

var factory = function(clazz /*, arguments*/) {
    var args = [].slice.call(arguments, 1);
    return new function() { 
        clazz.apply(this, args)
    }
}


文章来源: JavaScript: How to create a new instance of a class without using the new keyword?