javascript JSLint 错误:意外的“这个”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30314944/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JSLint Error: Unexpected 'this'
提问by jdw
Having trouble understanding why JSLint is surprised by my use of this
in the following code:
无法理解为什么 JSLint 对我this
在以下代码中的使用感到惊讶:
function testConstr (x) {
'use strict';
this.joker = "Whyyy sooo seriousss?";
this.x = x;
}
For both property assignments, JSLint says: Unexpected 'this'.How do I correct my code?
对于这两个属性分配,JSLint 说:意外的“这个”。如何更正我的代码?
采纳答案by Oriol
Your code mightbe perfectly correct (it might also be problematic, depending on how you call testConstr
).
您的代码可能完全正确(也可能有问题,具体取决于您如何调用testConstr
)。
My suggestion is: tell JSLint to shut up
我的建议是:告诉 JSLint 闭嘴
Or don't use JSLint at all.
或者根本不使用 JSLint。
回答by ruffin
So in other words, JSLint doesn't automatically expect me to use a constructor pattern?
You know, I think you're right. Your question bugged me, and I signed up for Crockford's JSLint discussion groupand asked. He replied, but ignored the solution I'm going to present, below, which I thinkmeans that it's okay, the same way JSLint doesn't complain if something passes muster.
你知道,我认为你是对的。你的问题困扰了我,我注册了Crockford 的 JSLint 讨论组并询问了. 他回答,但忽略了我将在下面提出的解决方案,我认为这意味着没关系,就像如果某些事情通过了 JSLint 不会抱怨一样。
(I'm still waiting for an updated Good Parts, though.)
(不过,我仍在等待更新的Good Parts。)
That caveat aside, here's what I'd suggest doing for OO JavaScript that passes Beta JSLint (as of today, anyhow).
抛开这个警告,这是我建议为通过 Beta JSLint 的 OO JavaScript 做的事情(无论如何,截至今天)。
I'm going to rewrite an example from MDN's page, "Introduction to Object Oriented Programming," which itself uses this
liberally.
我将重写 MDN 页面“面向对象编程简介”中的一个示例,该页面本身被大量使用this
。
With this
和 this
Here's the original, unlintedMDN example from the section linked, above:
这是上面链接部分中原始的、未标记的MDN 示例:
var Person = function (firstName) {
this.firstName = firstName;
};
Person.prototype.sayHello = function() {
console.log("Hello, I'm " + this.firstName);
};
var person1 = new Person("Alice");
var person2 = new Person("Bob");
// call the Person sayHello method.
person1.sayHello(); // logs "Hello, I'm Alice"
person2.sayHello(); // logs "Hello, I'm Bob"
That follows the conventions we know and love.
这遵循我们所知道和喜爱的惯例。
Without this
没有 this
It's pretty easy to figure out how to make "constructors" that don't follow that pattern, but we lose use of prototype
, if I'm not missing something, and have to include all of the object's methods in our constructor that we want allof our Peep
s to share.
很容易弄清楚如何制作不遵循该模式的“构造函数”,但是prototype
如果我没有遗漏某些东西,我们就失去了使用,并且必须在构造函数中包含我们想要的所有对象的方法我们Peep
的分享。
/*jslint white:true, devel:true */
var Peep = function(firstName) {
"use strict";
var peep = {};
peep.firstName = firstName;
peep.innerSayHello = function() {
console.log("Hello, I'm " + peep.firstName + ".");
};
return peep;
};
var peep1 = new Peep("Bob");
var peep2 = new Peep("Doug");
peep1.innerSayHello();
peep2.innerSayHello();
So there's a lintable alternative. That does, other than the return peep;
and the inner definition of methods, make JavaScript act like many OO-first languages you might encounter. It's not wrong, at least.
所以有一个 lintable 替代品。除了return peep;
方法的内部定义之外,这确实使 JavaScript 的行为类似于您可能遇到的许多面向对象优先的语言。至少没有错。
Not having access to prototype
isn't horrible; it's really bad news to change prototype
somewhere that's not right beside the constructor, as your code would go to spaghetti. "Some Person
s have sayGoodbye()
and some don't, depending on if we'd amended the prototype at the point of their construction." That's awful. So this alternative convention has its advantages.
prototype
无法访问并不可怕;prototype
在构造函数旁边的某个地方进行更改真的是个坏消息,因为您的代码会变成意大利面。“有些人Person
有sayGoodbye()
,有些人没有,这取决于我们是否在他们建造的时候修改了原型。”这太糟糕了。所以这个替代约定有它的优点。
You can still, of course, add functions to a single instantiation of Peep
later, but I'm not sure how you'd access firstName
without using this
, so perhaps he wants us to stop munging objects after construction.
当然,您仍然可以将函数添加到以后的单个实例中Peep
,但我不确定firstName
不使用时如何访问this
,所以也许他希望我们在构造后停止处理对象。
person1.sayGoodbye = function (other) {
console.log("Goodbye, " + other + ".");
};
(I mean, we could also still monkey-patch Peep
to change it mid-process, but that's horrible, stupid programming. Usually.)
(我的意思是,我们仍然可以在过程中使用猴子补丁Peep
来改变它,但那是可怕的、愚蠢的编程。通常。)
Inheritance (without this
)
继承(无this
)
And inheritance is easy enough, I think.
我认为继承很容易。
var PeepWithGoodbye = function (firstName) {
"use strict";
var peepWithGoodbye = new Peep(firstName);
peepWithGoodbye.innerSayGoodbye = function (otherPeep) {
if (undefined === otherPeep) {
otherPeep = { firstName: "you" };
}
console.log("This is " + firstName
+ " saying goodbye to " + otherPeep.firstName + ".");
};
return peepWithGoodbye;
};
var pwg1 = new PeepWithGoodbye("Fred");
pwg1.innerSayHello(); // Hello, I'm Fred.
pwg1.innerSayGoodbye(peep1); // This is Fred saying goodbye to Bob.
pwg1.innerSayGoodbye(); // This is Fred saying goodbye to you.
EDIT:See also this answerwhere the asker later found Crockford's suggested means of creating OO javascript. I'm trying to convince that guy to delete that Q&A and move the A here. If he doesn't, I'll probably add his stuff and community wiki it here.
编辑:另请参阅此答案,其中提问者后来找到了 Crockford 建议的创建 OO javascript 的方法。我试图说服那个人删除那个问答并将 A 移到这里。如果他不这样做,我可能会在这里添加他的东西和社区维基。
EDIT:See this from MDNfor why it works:
编辑:见从MDN这个为什么它的工作原理:
(Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)
(通常构造函数不返回值,但如果他们想覆盖正常的对象创建过程,他们可以选择这样做。)
回答by Lee
'use strict';
var SudoConstructor = (function () {
/* We need bind, < IE9 needs a (tiny) polyfill */
function protoEsqDeclare(sudoThis) {
return sudoThis;
}
function protoEsqSet(sudoThis, newValA, newValB) {
sudoThis.valA = newValA;
sudoThis.valB = newValB;
}
function instanceCreator(valA, valB) {
var sudoThis = {
valA: valA,
valB: valB
};
return {
declare: protoEsqDeclare.bind(null, sudoThis),
set: protoEsqSet.bind(null, sudoThis)
};
}
return instanceCreator;
}());
回答by zerkms
In a strict mode this
reference is set to undefined
.
在严格模式下,this
引用设置为undefined
.
So both your statements will cause reading properties of the undefined
object, which will lead to an exception.
所以你的两个语句都会导致读取undefined
对象的属性,从而导致异常。
How do I correct my code?
如何更正我的代码?
Remove both those lines.
删除这两行。
UPD: what I state above is how JSLint treats your code, not how I do that.
UPD:我上面所说的是 JSLint 如何处理您的代码,而不是我如何处理。
回答by DavidRR
JSLint says: Unexpected 'this'. How do I correct my code?
JSLint 说: 意外的“这个”。如何更正我的代码?
There is no need to correct your code.
无需更正您的代码。
In the help page for JSLint, in the section for the /*jslint*/
directive, a "Tolerate this
" option has been added to the table of available options:
在JSLint的帮助页面中,在/*jslint*/
指令部分中,“容忍this
”选项已添加到可用选项表中:
+---------------+------+---------------------------------+
| Tolerate this | this | true if this should be allowed. |
+---------------+------+---------------------------------+
So, to suppress complaints about the use of this
, place the following directive into your source file before the first statement:
因此,为了抑制对使用 的抱怨this
,请将以下指令放入源文件中的第一条语句之前:
/*jslint
this
*/
(Note that other /*jslint*/
options may follow this
by inserting a comma between options. See the JSLint help page.)
(请注意,其他/*jslint*/
选项this
后面可能会在选项之间插入逗号。请参阅 JSLint 帮助页面。)
Also see the answer by @Oriolto enable the "Tolerate this
"option in the user interface for JSLint.
另请参阅@Oriol 的答案,以在 JSLint 的用户界面中启用“容忍this
”选项。
回答by Leon Segal
An old question I know, but in case it helps anyone, I was watching a talkby Douglas Crockford in which he says (at about 23mins) that he took it out because an attacker could run a method as a function and get access to the global scope with the 'this' keyword.
我知道一个老问题,但如果它对任何人有帮助,我正在观看Douglas Crockford的演讲,他说(大约 23 分钟)他将其删除,因为攻击者可以将方法作为函数运行并访问带有“this”关键字的全局范围。
He says it also meant not using Object.create anymore either - a feature he helped introduce to the language!
他说这也意味着不再使用 Object.create - 他帮助引入了该语言的功能!