简体   繁体   English

将JavaScript构造函数作为函数调用是否存在问题(没有新的?)

[英]Are there problems with calling JavaScript constructors as functions(without new?)

Recently, I have got into a habit of calling things like RegExp, String, Number, Object, TypeError, etc without "new". 最近,我习惯于在没有“new”的情况下调用RegExp,String,Number,Object,TypeError等。

eg: 例如:

throw (TypeError("Error"));
var regex = RegExp('^word$');

I know that this is bad for cases when "this" context is needed, since without "new", "this" wreaks havoc on your global scope unless you wrap your code in 'use strict', in which case it raises an error that you are trying to mutate 'undefined'. 我知道这对于需要“this”上下文的情况是不好的,因为没有“new”,“this”会对你的全局范围造成严重破坏,除非你将代码包装在'use strict'中,在这种情况下它会引发一个错误你试图改变'undefined'。 (I am not sure that this works in very very old browsers). (我不确定这是否适用于非常老的浏览器)。

eg: 例如:

var constructor = function() {
    // 'use strict'; /* uncomment this line to avoid the behavior and be warned */
    this.state = 'working as intended';
};

var foo = constructor();
console.log(foo.state); // undefined
console.log(window.state); // we just polluted our global scope.

whereas

var constructor = function() {
    this.state = 'working as intended';
};

var foo = new constructor;
console.log(foo.state); // "working as intended"
console.log(window.state); // we are clean.

But in cases like the ones above, is it okay to do this, or are there problems I am setting myself up for if I get into a habit of doing this? 但是在如上所述的情况下,这样做是否可以,或者如果我养成了这样做的习惯,我是否会遇到问题?

Thanks ahead of time. 提前谢谢。

Be aware the result can be different. 请注意结果可能不同。

For example, the Number constructor creates Number objects, but when called as a function it only does type coercion to primitive Number. 例如, Number构造函数创建Number对象,但是当作为函数调用时,它只会将coercion类型设置为原始Number。

new Number(123); // Number { 123 }
Number(123); // 123

But yes, there are lots of the cases in which it doesn't matter whether you use new or not. 但是,有很多情况下,无论你是否使用new无关紧要。 They exist because of backwards compatibility, but with recently introduced constructors like Set or Map do require new . 它们存在是因为向后兼容,但最近引入的构造函数如SetMap确实需要new

In general, I would recommend using new when you want to create a new object. 一般情况下,我建议您在创建新对象时使用new Then, 然后,

  • If you only want to do type coercion, you must call Boolean , Number or String without new . 如果您只想进行类型强制,则必须在不使用new情况下调用BooleanNumberString
  • For the same reason, if you want coerce to Object type, I wouldn't use new , but it doesn't matter. 出于同样的原因,如果你想强制对象类型,我不会使用new ,但没关系。
  • If you want to create a primitive which doesn't have literal syntax, you must call Symbol without new . 如果要创建不具有文字语法的基元,则必须在不使用new情况下调用Symbol
  • If you want to create an object wrapper of a primitive value, you must call Boolean , Number , String or Symbol with new . 如果要创建原始值的对象包装器,则必须使用new调用BooleanNumberStringSymbol
  • If you want to instantiate an old constructor like Array , Object , RegExp , Error , etc., I would use new , but it doesn't matter. 如果你想实例化一个旧的构造函数,如ArrayObjectRegExpError等,我会使用new ,但没关系。
  • If you want to instantiate a recently introduced constructor like Set , Map , WeakSet , WeakMap , typed arrays, etc., you must call it with new . 如果要实例化最近引入的构造函数,如SetMapWeakSetWeakMap ,类型化数组等,则必须使用new调用它。

For the old constructors that it doesn't matter, it's like they call themselves with new if you omit it. 对于那些无关紧要的旧构造函数,如果省略它就像是用new表示自己。 For example, for RegExp , 例如,对于RegExp

When RegExp is called as a function rather than as a constructor, it creates and initializes a new RegExp object. RegExp作为函数而不是构造函数调用时,它会创建并初始化一个新的RegExp对象。 Thus the function call RegExp(…) is equivalent to the object creation expression new RegExp(…) with the same arguments. 因此,函数调用RegExp(…)等效于具有相同参数的对象创建表达式new RegExp(…)

As documented in another answer , some built in constructors are written to be able to be called as functions. 另一个答案所述 ,一些内置构造函数被编写为能够被称为函数。 So as long as you aren't polluting your global namespace, I believe you should be fine with the example you listed. 因此,只要您没有污染全局命名空间,我相信您应该对您列出的示例感到满意。

That being said, in most cases, I wouldn't get used to this habit; 话虽如此,在大多数情况下,我不会习惯这种习惯; the new operator adds to code clarity, which is more important than brevity. new运算符增加了代码清晰度,这比简洁更重要。 The ability to use native constructors without the new operator is also inconsistently applied across constructors. 在没有new运算符的情况下使用本机构造函数的能力也不一致地应用于构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM