简体   繁体   English

关键字“new”在JavaScript中有什么副作用?

[英]What side effects does the keyword 'new' have in JavaScript?

I'm working on a plug-in for jQuery and I'm getting this JSLint error: 我正在研究jQuery的插件,我收到了这个JSLint错误:

Problem at line 80 character 45: Do not use 'new' for side effects.

(new jQuery.fasterTrim(this, options));

I haven't had much luck finding info on this JSLint error or on any side effects that new might have. 我没有太多运气找到有关此JSLint错误的信息或new可能产生的任何副作用。

I've tried Googling for "Do not use 'new' for side effects." 我试过谷歌搜索 “不要使用'新'副作用。” and got 0 results. 得到0结果。 Binging gives me 2 results but they both just reference the JSLint source. Binging给了我2个结果,但它们都只引用了JSLint源代码。 Hopefully this question will change that. 希望这个问题会改变这一点。 :-) :-)

Update #1: Here's more source for the context: 更新#1:以下是上下文的更多来源:

  jQuery.fn.fasterTrim = function(options) {
    return this.each(function() {
      (new jQuery.fasterTrim(this, options));
    });
  };

Update #2: I used the Starter jQuery plug-in generator as a template for my plug-in, which has that code in it. 更新#2:我使用Starter jQuery插件生成器作为我的插件的模板,其中包含该代码。

JsLint itself gives you the reason: JsLint本身就是你的理由:

Constructors are functions that are designed to be used with the new prefix. 构造函数是旨在与新前缀一起使用的函数。 The new prefix creates a new object based on the function's prototype, and binds that object to the function's implied this parameter. 新前缀基于函数的原型创建一个新对象,并将该对象绑定到函数的隐含此参数。 If you neglect to use the new prefix, no new object will be made and this will be bound to the global object. 如果忽略使用新前缀,则不会创建新对象,并且这将绑定到全局对象。 This is a serious mistake. 这是一个严重的错误。

JSLint enforces the convention that constructor functions be given names with initial uppercase. JSLint强制执行构造函数为初始大写的名称的约定。 JSLint does not expect to see a function invocation with an initial uppercase name unless it has the new prefix. 除非具有新的前缀,否则JSLint不希望看到具有初始大写名称的函数调用。 JSLint does not expect to see the new prefix used with functions whose names do not start with initial uppercase. JSLint不期望看到与名称不以初始大写开头的函数一起使用的新前缀。 This can be controlled with the newcap option. 这可以使用newcap选项进行控制。

JSLint does not expect to see the wrapper forms new Number, new String, new Boolean. JSLint不希望看到包装器形成新的Number,new String,new Boolean。

JSLint does not expect to see new Object (use {} instead). JSLint不期望看到新的Object(而是使用{})。

JSLint does not expect to see new Array (use [] instead). JSLint不希望看到新的数组(改为使用[])。

Travis, I am the developer behind the Starter site. 特拉维斯,我是Starter网站的开发者。

@Pointy hit the nail on the head. @Pointy击中了头部。 The reason the Starter code is written that way is because we do need a new object, we just don't need to store a reference to it at that point. 以这种方式编写Starter代码的原因是因为我们确实需要一个新对象,所以我们不需要在那时存储对它的引用。

Simply changing the command from 只需更改命令即可

(new jQuery.fasterTrim(this, options)); 

to

var fT = new jQuery.fasterTrim(this, options);

will appease JSLint as you have found. 你会发现安抚JSLint。

The Starter plugin setup follows the jQuery UI pattern of storing a reference to the object in the data set for the element. Starter插件设置遵循jQuery UI模式,即在元素的data集中存储对象的引用。 So this is what is happening: 所以这就是发生的事情:

  1. New object is created (via new) 创建新对象(通过新)
  2. The instance is attached to the DOM element using jQuery's data : $(el).data('FasterTrim', this) 该实例使用jQuery的data附加到DOM元素: $(el).data('FasterTrim', this)

There is no use for the object that is returned, and thus no var declaration made. 返回的对象没有用处,因此没有进行var声明。 I will look into changing the declaration and cleaning up the output to pass JSLint out of the box. 我将研究更改声明和清理输出以开箱即用的JSLint。

A little more background : 更多背景

The benefit to storing the object using data is that we can access the object later at any time by calling: $("#your_selector").data('FasterTrim') . 使用data存储对象的好处是我们可以随时通过调用: $("#your_selector").data('FasterTrim')来访问对象。 However, if your plugin does not need to be accessed mid stream that way (Meaning, it gets set up in a single call and offers no future interaction) then storing a reference is not needed. 但是,如果你的插件不需要在流中途访问(意思是,它在一次调用中设置并且不提供将来的交互),则不需要存储引用。

Let me know if you need more info. 如果您需要更多信息,请告诉我。

It's complaining because you're calling "new" but then throwing away the returned object, I bet. 这是抱怨,因为你打电话给“新”但随后扔掉了退回的物品,我敢打赌。 Why is that code using "new"? 为什么该代码使用“新”? In other words, why isn't it just 换句话说,为什么不是这样

jQuery.fasterTrim(this, options);

edit OK, well that "Starter" tool generates the code that way because it really does want a new object created, and yes it really is to take advantage of side effects. 编辑确定,“Starter”工具生成代码,因为它确实需要创建一个新对象,是的,它确实是利用副作用。 The constructor code that "Starter" generates stashes a reference to the new object on the affected element, using the jQuery "data" facility. “Starter”生成的构造函数代码使用jQuery“data”工具存储对受影响元素上的新对象的引用。

You are using new to perform some action instead of to create an object and return it. 您正在使用new来执行某些操作,而不是创建对象并将其返回。 JSLint considers this an invalid use of new . JSLint认为这是对new的无效使用。

You should either use it like this: 你应该像这样使用它:

var x = new SomeConstructor();

Or perform some action like this: 或者像这样执行一些操作:

SomeMethod();

But never use new to perform an action like this: 但是永远不要用new来执行这样的动作:

new SomeCosntructor(args);

Doing so is considered using new for side effects because you aren't using it to create an object. 这样做被认为是使用new作为副作用,因为您没有使用它来创建对象。

Basically JavaScript tends to be a slow beast, so creating a new object just to call a function is quite inefficient. 基本上JavaScript往往是一个缓慢的野兽,因此创建一个新对象只是为了调用一个函数是非常低效的。 The function is static anyway. 无论如何,该功能是静态的。

$.fasterTrim(this, options);

From jQuery fasterTrim source code : 来自jQuery fasterTrim源代码

 * Usage: 
 * 
 * $(element).fasterTrim(options);  // returns jQuery object
 * $.fasterTrim.trim(" string ", options);  // returns trimmed string

To answer the question, "Do not use new for side effects" means: 要回答这个问题,“不要使用新的副作用”意味着:

Do not use new for what the constructor will do to its parameters but to create an object, side effects in constructors are baaaad! 不要使用new作为构造函数将对其参数执行的操作,而是创建一个对象,构造函数中的副作用是baaaad!

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

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