Javascript &引用;这";指的是别的什么?
当我运行此代码时:Javascript &引用;这";指的是别的什么?,javascript,Javascript,当我运行此代码时: var Test = function() { return this.stuff; }; Test.stuff = 'Neat!'; document.write(Test() || 'Not neat.'); 为什么我会“不整洁”?为什么我不能使用this.stuff访问stuff属性?您从全局上下文调用了Test,因此this引用全局对象,因此this.stuff引用全局变量stuff,它是未定义的,是错误的。这就是您看到不整洁的原因。 您可以使它显示整洁
var Test = function() {
return this.stuff;
};
Test.stuff = 'Neat!';
document.write(Test() || 'Not neat.');
为什么我会“不整洁”?为什么我不能使用
this.stuff
访问stuff属性?您从全局上下文调用了Test
,因此this
引用全局对象,因此this.stuff
引用全局变量stuff
,它是未定义的,是错误的。这就是您看到不整洁的原因。
您可以使它显示整洁代码>如下所示:
看
附录
这里有一种方法可以让这个作为一个封闭对象工作:
这里我们通过一个目标对象调用Test
类方法和变量位于prototype属性上:
Test.prototype.stuff = 'Neat!'
构造函数函数(我假设这是您想要的,考虑到大写字母和this
)应该使用new
操作符调用:
new Test()
它们不应该返回值(您应该使用默认值返回this
)
至于您的实际需要,您可以直接访问函数及其属性
function Test(){
return Test.stuff;
}
然而,我不是一个滥用名称空间函数的狂热者。我更喜欢使用名称空间对象来进行操作
//in a real case I would probably use the module pattern for private variables
//but whatever...
var Namespace = {};
Namespace.stuff = 'Neat!';
Namespace.F = function(){
console.log(Namespace.stuff);
};
stuff属性已分配给函数,但从全局。。。这两个是独立的实体这就是您所做的:
var Test = function() { //Test is a Function object
return this.stuff; //this is a pointer to an object, not Test
};
Test.stuff = 'Neat!'; //Add a property to Test
document.write(Test() || 'Not neat.'); //this has no property stuff
将代码的最后一行更改为:
document.write(Test.call(Test) || 'Not neat.'); //this now points to Test
代码不起作用的原因是this
指针指向:
当函数调用以new
关键字作为前缀时创建的构造函数实例。(例如,var foo=new foo();//this in foo指向foo[为了解释]
)
传递给调用
和应用
的对象用作第一个参数
您想做的是:
var Test = function Temp() { //Test is a Function object, alias Temp
return Temp.stuff; //Temp is the same as Test, only locally
};
Test.stuff = 'Neat!'; //Add a property to Test
document.write(Test() || 'Not neat.'); //writes Neat!
如果你喜欢这个答案,就投票吧。干杯。虽然其他人已经发布了发生这种情况的原因(对这个
的理解是不正确的),但这里有一个解决方案可以可靠地工作
更新:正如Raynos所指出的,在ECMAScript第5版中,使用参数是无效的。被调用方
(它将抛出一个类型错误)。因此,如果使用这种方法,应谨慎行事。(使用[correct]ECMAScript第5版引擎时,没有理由在绑定到新作用域的函数的名称上使用参数。被调用方
——请参见答案的结尾。)
另一种方法是使用闭包:
var Test = (function () {
function fn () {
// closure over fn, which names this function-object
return fn.stuff
}
fn.stuff = 'Neat!' // here
return fn // do not combine with function declaration!
})()
Test.stuff = 'Neat!' // or here
alert(Test() || 'Not neat.') // Neat!
或者,直接对变量进行闭包:
var Test = (function () {
var stuff = 'Neat!'
return function () {
// variable closure, no property
return stuff
}
})()
alert(Test() || 'Not neat.') // Neat!
或者。。。很多方面
快乐编码
Aadit M Shah指出的另一种方法是使用函数标识符引用当前函数:
var Test = function Temp () {
return Temp.stuff
}
Test.stuff = 'Neat!'
alert(Test() || 'Not neat.') // Neat! (But see below.)
正如Aadit所指出的,根据第99页:
FunctionExpression中的标识符可以从FunctionExpression的FunctionBody内部引用到
允许函数递归地调用自身。但是,与FunctionDeclaration不同,FunctionExpression中的标识符不能从中引用,也不会影响包含FunctionExpression的范围
然而,一些浏览器(至少IE9)没有正确地实现这一点(我不确定上述行为是否在第三版中定义良好)。考虑:
var x = function y () { return y }; y = 42; x();
在IE9中,它将产生42,在FF8中,它将产生函数对象。IE9在这里是不正确的,因为它在封闭范围中引入了y
,这是ECMAScript禁止用于函数表达式的变量。下面是一个上下文示例,说明了这种错误的实现如何导致不同的结果:
var Test = function Temp () {
return Temp.stuff
}
Test.stuff = "Neat!"
Temp = {}
alert(Test() || 'Not neat.') // 'Not neat.' in IE9, 'Neat!' in FF8
你到底想在这里做什么?我实际上想使用类似jQuery对象的类(不实例化):Test('do something');Test.default=500;Test(‘用500做点什么’)
@AlicanC这里有一篇由johnresig写的关于这个话题的帖子@皮特:那篇文章很好,但是是2007年的。我现在在jQuery1.7的源代码中找不到arguments.calee的任何用法。也许他们采用了一种新的方法?我似乎不明白。@AlicanC-据我所知,您真正想要的是一种类似于我在回答中描述的模式(即var Test=function Temp(){return Temp.stuff;};
)。它很快,也很优雅。另外,即使人们以后更改代码,比如Test=5代码>,它不会打断您的代码,因为函数的内部名称(即Temp
)仍然指向函数本身。它不能从外部修改。希望这有帮助。干杯。使用arguments.callee和直接重复函数名有什么区别?@missingno Preference:)我已经使用了这两种方法,这取决于我想做什么,以及“它”与其余代码的匹配程度。我想不出一个“普遍的”优势或劣势,但如果我忽略了什么,我也不会感到惊讶。只是小心不要“太聪明”。。。请注意,在全局上下文中,is与var Test=function(){return Test.stuff}
不同,因为Test
实际上可能是window.Test
,一个属性,而不是封闭变量。有人以后可能会用Test=function(){}
破坏一些东西。。。永远不知道:)我不喜欢使用参数。被调用方
。我也不喜欢使用var Test=function(){return Test.stuff;}代码>。两者都是访问数据的缓慢方法。这是因为被调用方
是参数
的一种方法,而解释器会花费更多的时间来访问它。类似地,Test
在本地范围内不存在。因此,解释器必须向上移动才能在父作用域中找到它。相反,我更喜欢以下方法:var Test=function Temp(){return Temp.stuff;}代码>。这里的Temp
是一个al
var Test = (function () {
var stuff = 'Neat!'
return function () {
// variable closure, no property
return stuff
}
})()
alert(Test() || 'Not neat.') // Neat!
var Test = function Temp () {
return Temp.stuff
}
Test.stuff = 'Neat!'
alert(Test() || 'Not neat.') // Neat! (But see below.)
var x = function y () { return y }; y = 42; x();
var Test = function Temp () {
return Temp.stuff
}
Test.stuff = "Neat!"
Temp = {}
alert(Test() || 'Not neat.') // 'Not neat.' in IE9, 'Neat!' in FF8