我想下面的代码可以把问题解释清楚。
// 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);
8条答案
按热度按时间thtygnil1#
更简单、更清洁的方式,没有“工厂”
qvsjd97n2#
这不管用吗?
我不明白为什么你不能用
new
。oiopk7p53#
如果你真的不想使用
new
关键字,并且你不介意只支持Firefox,你可以自己设置原型,但这并没有什么意义,因为你可以直接使用Dave欣顿的答案。hujrc8aj4#
我想独立于浏览器的解决方案会更好
yhuiod9q5#
因为JavaScript没有类,所以让我改写一下您的问题:如何在不使用new关键字的情况下基于现有对象创建新对象?
这里有一个不使用“new”的方法,严格来说它不是“new instance of”,但这是我能想到的唯一不使用“new”的方法(也不使用任何ECMAScript 5特性)。
你可以花点心思来设置原型,但是这样会遇到跨浏览器的问题,我尽量让这个简单一些,你也可以使用“hasOwnProperty”来过滤你要添加到新对象中的属性。
还有其他一些方法可以使用“new”,但却隐藏了它。下面是借用JavaScript: The Good Parts by Douglas Crockford中的Object.create函数的一种方法:
EcmaScript5有Object.create方法,它可以更好地实现这一点,但只有较新的浏览器(例如IE9,FF4)才支持,但您可以使用polyfill(一些填补漏洞的东西),如ES5 Shim,来获得旧浏览器的实现。(参见John Resig's article on new ES5 features including Object.create)。
在ES5中,您可以这样做:
希望能有所帮助
afdcj2ne6#
另一种方式:
rvpgvaaj7#
为了更准确地回答这个问题,即如何让
myClass()
返回new myClass()
...这是不可能的,下面是原因...您必须这样做,以确保类名存在,并且您正在捕获对
myClass()
的调用(使用apply功能,来自Proxy
/trap/handler-land):或:
这个方法不起作用的原因是,当你试图评估以上两种情况时,会产生以下输出:
Uncaught TypeError: class constructors must be invoked with 'new'
因此,JavaScript实际上不允许这样做,因为您已经将其声明为
class
类型,但是,您当然可以使用一个单独命名的函数为您创建一个新示例,就像answer above中那样,或者更简单:或者,解决这个问题的另一种方法是不使用
class
本身,而是使用function
或常规JS对象{}
,就像早期的JavaScript一样。btqmn9zl8#
您还可以使用
eval
。当然,
eval
存在安全问题,但是它真的与其他动态示例化不同吗?