[英]JSLint Error: Unexpected 'this'
唔明为什么JSLint的是我使用的惊讶this
在下面的代码:
function testConstr (x) { 'use strict'; this.joker = "Whyyy sooo seriousss?"; this.x = x; }
对于这两个属性分配,JSLint都说: 意外的'this'。 如何更正我的代码?
您的代码可能是完全正确的(取决于您如何调用testConstr
,这也可能有问题)。
我的建议是:告诉JSLint闭嘴
或根本不使用JSLint。
你知道,我认为你是对的。 您的问题困扰着我,我加入了Crockford的JSLint讨论小组并提出了问题 。 他回答,但忽略了我将在下面介绍的解决方案,我认为这意味着可以,就像JSLint不会抱怨时一样。
(不过,我仍在等待更新的Good Parts 。)
除了警告,这是我建议对通过Beta JSLint的OO JavaScript进行的操作(无论如何,到目前为止)。
我将在MDN的页面“ 面向对象编程简介 ”中重写一个示例,该页面本身就使用了this
。
this
这是上面链接部分中原始的, 不受限制的 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"
那遵循我们知道和喜爱的惯例。
this
弄清楚如何制作不遵循该模式的“构造函数”非常容易,但是如果我没有遗漏任何东西,我们就必须放弃使用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();
因此,有一种可替代的方案。 除了return peep;
以外,还可以return peep;
以及方法的内部定义,使JavaScript就像您可能会遇到的许多面向对象的语言一样。 至少没有错 。
无法访问prototype
并不可怕。 在构造器旁边不正确的地方更改prototype
确实是一个坏消息,因为您的代码将进入意大利面条。 “ 有些Person
的是sayGoodbye()
,有些人没有的,这取决于我们是否在构造时修改了原型。 ”那太糟糕了。 因此,该替代约定具有其优点。
当然,您仍然可以稍后在Peep
的单个实例中添加函数,但是我不确定如果不使用this
,您将如何访问firstName
,因此也许他希望我们在构造后停止对对象的操作。
person1.sayGoodbye = function (other) {
console.log("Goodbye, " + other + ".");
};
(我的意思是,我们还可以在中间过程中使用猴子补丁Peep
进行更改,但这是可怕的,愚蠢的编程。 通常。 )
this
) 我认为继承很容易。
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.
编辑:另请参阅此答案 ,询问者后来发现克罗克福德建议的创建OO JavaScript的方法。 我试图说服那个人删除该问答,并将A移到此处。 如果他没有,我可能会在这里添加他的东西和社区Wiki。
编辑: 从MDN看到它的工作原理:
(通常,构造函数不返回值,但是如果他们想覆盖常规的对象创建过程,则可以选择这样做。)
'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;
}());
在严格模式下, this
引用设置为undefined
。
因此,您的两条语句都将导致读取undefined
对象的属性,这将导致异常。
如何更正我的代码?
删除这两行。
UPD:我上面说的是JSLint如何对待您的代码,而不是我如何处理。
JSLint说:意外的“ this”。 如何更正我的代码?
无需更正您的代码。
在JSLint的帮助页面中 ,在/*jslint*/
指令的部分中,“ 容忍this
”选项已添加到可用选项表中:
+---------------+------+---------------------------------+
| Tolerate this | this | true if this should be allowed. |
+---------------+------+---------------------------------+
因此,为避免对使用this
抱怨,请将以下指令放入源文件中的第一条语句之前:
/*jslint
this
*/
(请注意,其他/*jslint*/
选项可能遵循this
插入选项之间用逗号。见JSLint的帮助页面。)
另请参阅@Oriol的答案,以在JSLint的用户界面中启用“ Tolerate this
”选项。
我知道一个老问题,但是如果它对任何人都有帮助,我正在观看道格拉斯·克罗克福德(Douglas Crockford)的一次演讲 ,他在演讲中说(大约23分钟),他将其删除了,因为攻击者可以将方法作为函数运行并可以访问使用'this'关键字的全局范围。
他说这也意味着不再使用Object.create了-他帮助该语言引入了一项功能!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.