this
是不同的JavaScript比在像C++或Java的其他語言。第一個示例中的this
的值將始終是全局對象(window
,在瀏覽器上)。第二個示例中的this
是第一個警報的jsn
對象,第二個示例的window
。這是因爲this
完全由確定通過如何調用一個函數,而不是它的定義。
如果在調用函數時沒有做任何特別的事情,則this
是全局對象。當您通過對象屬性(jsn.func()
)調用函數時,將this
設置爲屬性來自的對象。 (但不要錯誤的印象,func
是不是專門綁定到jsn
; JavaScript沒有方法,只是功能; details。)f1
然後返回一個函數,它在最後alert
內調用;由於該調用不是通過對象屬性,因此將this
設置爲全局對象。
一些例子:
// Simple function
function foo() {
alert(this === window);
}
foo(); // true, within the call, `this` === `window`
// Object example, and twist at the end
var obj = {
func: function() {
alert(this === obj);
},
};
obj.func(); // true, within the call, `this` === `obj`
obj["func"](); // true, within the call, `this` === `obj`
var f = obj.func; // Not calling it, just getting a reference to the function
f(); // false, within the call `this` !== `obj` (`this` === `window`)
// Creating functions on the fly, returning them, and how that has
// nothing whatsoever to do with how `this` gets set:
var obj = {
func: function() {
return function() {
alert("I'm a generated function");
alert(this === obj);
};
}
};
obj.func()(); // alerts the "I'm a generated function", then false; `this` !== `obj`
obj.bar = obj.func();
obj.bar(); // alerts the "I'm a generated function", then true; `this` === `obj`
有控制什麼this
是一個函數內的第二種方法:使用JavaScript函數的.call
或.apply
特點:
var obj = {
func: function() {
alert(this === obj);
}
};
function foo(a, b) {
alert(this === obj); // Yes, really obj; see below
alert(a);
alert(b);
}
foo(1, 2); // alerts false (`this` !== `obj`), then 1, then 2
obj.func(); // alerts true, `this` === `obj`
foo.call(obj, 3, 4); // alerts true (`this` === `obj`), then 3, then 4
foo.apply(obj, [5, 6]); // alerts true (`this` === `obj`), then 5, then 6
正如你所看到的,第一個參數爲call
或apply
是在函數調用中使this
的對象。 call
和apply
之間的唯一區別是指定參數以傳遞到目標函數:使用call
,您只需在第一個參數後面提供參數;與適用,你提供他們作爲一個數組。
最後,還有第三種方法:new
關鍵字。 JavaScript具有構造函數的概念。構造函數的目的是創建以特定方式初始化的對象的實例。這裏有一個例子:
function Foo(b) {
this.bar = b;
}
var f = new Foo();
從技術上講,任何功能可以作爲一個構造函數。該公約旨在提供與大寫字母開頭的new
名稱一起使用的功能,以加強我們以特殊方式稱呼它們。
通過new
調用函數將創建一個新的對象實例,並在該函數調用中使該對象成爲this
的值。所以
function Foo(b) {
alert(this === window);
}
var f = new Foo(); // alerts false, `this` !== `window` (it points to the new object created for the call)
var f = Foo(); // alerts true, `this` === `window` because we didn't use `new`
正如你所看到的,以正確的方式調用一個函數是很重要的。如果它的設計與new
一起使用,請通過new
致電;如果不是,不要。
(new
不僅僅是創建一個空白對象,創建的對象還有一些其他方面的設置,我不會在這裏詳細討論,但我不想留下印象所有它所做的就是創建一個新的對象實例。)
**題外話**:你'jsn' VARNAME建議你在來思考[ JSON(http://json.org)。但那不是JSON,這是JavaScript Object Literal Notation。 (JSON是對象文字符號的一個子集;它需要雙引號,並且沒有函數或未定義,並且只支持十進制[不是十六進制或八進制]。)人們會混淆這兩個a * lot * :-),所以我認爲這值得一提。 – 2010-12-17 08:27:19