當我運行這段代碼:「這個」是指別的嗎?
var Test = function() {
return this.stuff;
};
Test.stuff = 'Neat!';
document.write(Test() || 'Not neat.');
爲什麼我得到 '不利落。'?爲什麼我不能使用this.stuff
訪問stuff資源?
當我運行這段代碼:「這個」是指別的嗎?
var Test = function() {
return this.stuff;
};
Test.stuff = 'Neat!';
document.write(Test() || 'Not neat.');
爲什麼我得到 '不利落。'?爲什麼我不能使用this.stuff
訪問stuff資源?
雖然其他人已經發布了爲什麼發生這種情況(對this
的理解不正確),但下面是一個可以可靠工作的解決方案。
更新:在ECMAScript的第5版作爲Raynos指出,when using strict mode functions,它是無效使用arguments.callee
(它會拋出一個TypeError)。因此,如果使用這種方法,應謹慎行事。 (當使用[正確] ECMAScript的第5版的發動機,沒有理由使用arguments.callee
在給它綁定到新的範圍函數的名字 - 一看便知結束。)
var Test = function() {
// arguments.callee is the current function, if any
return arguments.callee.stuff
}
Test.stuff = 'Neat!'
alert(Test() || 'Not neat.') // Neat!
另一種是用一個封閉:
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中號沙指出另一種方法是使用函數標識符來指代當前函數:
var Test = function Temp() {
return Temp.stuff
}
Test.stuff = 'Neat!'
alert(Test() || 'Not neat.') // Neat! (But see below.)
作爲Aadit所指出的,這是有效的,因爲每ECMAScript 5th edition specification第99頁:
在FunctionExpression標識符可以從FunctionExpression的函數體內部參考 允許函數的n遞歸地調用它自己。但是,與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
使用arguments.callee和直接重複函數名稱會有什麼區別? – hugomg
@missingno偏好? :)我已經使用了兩個,這取決於我想要做什麼以及它如何與代碼的其餘部分「吻合」。我無法想出一個「普遍」的優勢或劣勢,無論從我的頭頂開始,但如果我忽略了某些東西,我不會感到驚訝。注意不要太「聰明」......注意,與全局上下文中的'var Test = function(){return Test.stuff}'不同*因爲'Test'可能真的是'窗口.Test',一個屬性,而不是一個封閉的變量。有人可能會在後面用'Test = function(){}'來破壞事情... ...永遠不知道:) – 2011-11-12 04:32:28
我不喜歡使用'arguments.callee'。我也不喜歡使用'var Test = function(){return Test.stuff; };'。兩者都是訪問數據的緩慢方法。這是因爲'callee'是'arguments'的一種方法,解釋器花更多的時間來訪問它。同樣,'Test'在本地範圍內不存在。因此,解釋者必須向上行進以將其定位在父範圍內。相反,我更喜歡以下方法:'var Test = function Temp(){return Temp.stuff; };'。這裏'Temp'是'Test'的別名,它存在於本地範圍內。這是一個更快,更優雅的解決方案。 ;) –
您從全球範圍內被稱爲Test
,所以this
指的是全局對象,所以this.stuff
指的是全局變量stuff
這是undefined
這是falsy。這就是爲什麼你看到"Not neat."
你可以把它顯示Neat!
這樣的:
window.stuff = 'Neat!';
var Test = function() {
return this.stuff;
};
alert(Test() || 'Not neat.');
附錄
這裏有一個方法可以讓this
工作作爲封閉物體:
var Test = function() {
return this.stuff;
};
var example = {
g: Test,
stuff: "Pretty neat"
};
alert(example.g() || 'Not neat.');
這裏我們通過一個目標對象調用Test
。
類方法和變量走在原型屬性:
Test.prototype.stuff = 'Neat!'
構造函數(我假設這是你想要的,鑑於死刑案件和this
)應調用與new
操作:
new Test()
,他們不應該返回一個值(而應該使用返回this
默認)
function Test(){
this.instanceVariable = 17;
//no return!
}
至於你的真正需要,你可以訪問的功能和它的性能直接再
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(); //the this in Foo points to foo [for the sake of explanation]
)。call
和apply
的對象作爲第一個參數。你想要做的,而不是什麼是一樣的東西:
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!
給予好評這個答案,如果你喜歡它。乾杯。
你在這裏試圖做什麼? – hugomg