JSLint Error: Unexpected 'this'
JSLint Error: Unexpected 'this'
无法理解为什么 JSLint 对我在以下代码中使用 this
感到惊讶:
function testConstr (x) {
'use strict';
this.joker = "Whyyy sooo seriousss?";
this.x = x;
}
对于两个 属性 作业,JSLint 说:意外 'this'。 如何更正我的代码?
在严格模式下 this
引用设置为 undefined
。
所以你的两个语句都会导致读取 undefined
对象的属性,这将导致异常。
How do I correct my code?
删除这两行。
UPD:我上面所说的是 JSLint 如何处理您的代码,而不是我如何处理代码。
您的代码 可能 完全正确(它也可能有问题,具体取决于您如何调用 testConstr
)。
我的建议是:让 JSLint 闭嘴
或者根本不使用 JSLint。
你知道,我认为你是对的。你的问题打扰了我,我注册了 Crockford's JSLint discussion group and asked。他回答了,但忽略了我将在下面提出的解决方案,我 认为 意味着没关系,就像 JSLint 在某些事情通过召集时不会抱怨一样。
(不过,我还在等待更新 Good Parts。)
抛开这个警告,这是我建议为通过 Beta JSLint 的 OO JavaScript 做的事情(无论如何,从今天开始)。
我将重写 MDN 页面“Introduction to Object Oriented Programming”中的示例,该页面本身大量使用 this
。
和this
这是来自上面链接部分的原始 unlinted 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();
所以有一个 lintable 替代方案。确实如此,除了 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.
编辑: 另见 提问者后来在其中找到了 Crockford 建议的创建 OO 的方法 javascript。我试图说服那个人删除那个问答并将 A 移到这里。如果他不这样做,我可能会在这里添加他的东西和社区维基。
编辑: 请参阅 this from 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.)
JSLint says: Unexpected 'this'. How do I correct my code?
无需更正您的代码。
在 help page for JSLint 中,在 /*jslint*/
指令部分,“Tolerate this
" 选项已添加到 table 个可用选项中:
+---------------+------+---------------------------------+
| Tolerate this | this | true if this should be allowed. |
+---------------+------+---------------------------------+
因此,要抑制对使用 this
的抱怨,请将以下指令放入您的源文件中第一条语句之前:
/*jslint
this
*/
(请注意,其他 /*jslint*/
选项可以通过在选项之间插入逗号来跟在 this
之后。请参阅 JSLint 帮助页面。)
另请参阅 以在 JSLint 的用户界面中启用 "Tolerate this
" 选项。
'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;
}());
我知道一个老问题,但如果它对任何人有帮助,我正在观看 Douglas Crockford 的 talk,他在其中说(大约 23 分钟)他将其删除,因为攻击者可以 运行 作为函数的方法,并使用 'this' 关键字访问全局范围。
他说这也意味着不再使用 Object.create - 他帮助引入该语言的一项功能!
无法理解为什么 JSLint 对我在以下代码中使用 this
感到惊讶:
function testConstr (x) {
'use strict';
this.joker = "Whyyy sooo seriousss?";
this.x = x;
}
对于两个 属性 作业,JSLint 说:意外 'this'。 如何更正我的代码?
在严格模式下 this
引用设置为 undefined
。
所以你的两个语句都会导致读取 undefined
对象的属性,这将导致异常。
How do I correct my code?
删除这两行。
UPD:我上面所说的是 JSLint 如何处理您的代码,而不是我如何处理代码。
您的代码 可能 完全正确(它也可能有问题,具体取决于您如何调用 testConstr
)。
我的建议是:让 JSLint 闭嘴
或者根本不使用 JSLint。
你知道,我认为你是对的。你的问题打扰了我,我注册了 Crockford's JSLint discussion group and asked。他回答了,但忽略了我将在下面提出的解决方案,我 认为 意味着没关系,就像 JSLint 在某些事情通过召集时不会抱怨一样。
(不过,我还在等待更新 Good Parts。)
抛开这个警告,这是我建议为通过 Beta JSLint 的 OO JavaScript 做的事情(无论如何,从今天开始)。
我将重写 MDN 页面“Introduction to Object Oriented Programming”中的示例,该页面本身大量使用 this
。
和this
这是来自上面链接部分的原始 unlinted 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();
所以有一个 lintable 替代方案。确实如此,除了 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.
编辑: 另见
编辑: 请参阅 this from 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.)
JSLint says: Unexpected 'this'. How do I correct my code?
无需更正您的代码。
在 help page for JSLint 中,在 /*jslint*/
指令部分,“Tolerate this
" 选项已添加到 table 个可用选项中:
+---------------+------+---------------------------------+
| Tolerate this | this | true if this should be allowed. |
+---------------+------+---------------------------------+
因此,要抑制对使用 this
的抱怨,请将以下指令放入您的源文件中第一条语句之前:
/*jslint
this
*/
(请注意,其他 /*jslint*/
选项可以通过在选项之间插入逗号来跟在 this
之后。请参阅 JSLint 帮助页面。)
另请参阅 this
" 选项。
'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;
}());
我知道一个老问题,但如果它对任何人有帮助,我正在观看 Douglas Crockford 的 talk,他在其中说(大约 23 分钟)他将其删除,因为攻击者可以 运行 作为函数的方法,并使用 'this' 关键字访问全局范围。
他说这也意味着不再使用 Object.create - 他帮助引入该语言的一项功能!