看到很多資料說,哪個物件呼叫了這個函數,這個函數中的 this 就指向這個物件。
下面這個例子中,foo這個函數,是透過 foo()這個語句呼叫的,為什麼this 會指向全域?並沒有 Window.foo( )這樣由全域物件呼叫呀?
求教,多謝!
var x = 10;
var obj = {
x: 20,
f: function () {
var foo = function (){
console.log(this.x);
}
foo();
}
};
obj.f(); //10
给我你的怀抱2017-06-26 10:54:59
樓上講的有點問題,foo不是全域變量,簡單點來判斷(非嚴格模式)就是:
1.當一個函數沒有被指定上級對象的時候,this指向window
2.當一個函數有被指定上級物件的時候,this只指向最靠近的上級(父)物件
如foo.fn.o() , o裡面的this指向fn
高洛峰2017-06-26 10:54:59
是這樣子的,我寫在註解裡面
var x = 10;
var obj = {
x: 20,
f: function () {
var foo = function (){
console.log(this.x);//你这是把函数赋值给一个 foo的变量。此时的 foo 是全局的,所以下面调用 foo()这里是10嘛
}
foo();
}
};
obj.f(); // 这个调用 f 函数,因为 f(),并没有返回出去什么,所以这里是 undefined
代言2017-06-26 10:54:59
對於內部函數
,即聲明在另一個函數體內的函數,都會綁定到全域物件
上,這是JavaScript的設計缺陷
,正確的設計方式是內部函數的this應該綁定到其外層函數對應的物件上,所以導致以上問題。
為了規避這個設計缺陷,可以用變數取代
的方法,約定俗成,可以使用self
或that
,程式碼如下:
var x = 10;
var obj = {
x: 20,
f: function () {
var self = this;
var foo = function (){
console.log(self.x);
}
foo();
}
};
obj.f();
PHP中文网2017-06-26 10:54:59
先搞清楚一個道理:
1: window也是一個對象,它是一個特別的對象,它代表全局。 當你以以下方式呼叫一個函數的時候:
function foo(){....}
foo();//
第二行的這種呼叫方式(函數前面沒有一個你自己定義的object),我們叫做'全域調用'。其實等同於window.foo()。所以你看出來了嗎?在全域呼叫函數,其實是在物件上呼叫函數的一個特例,因為這時候的物件是window.
2: 那為什麼上面的程式碼是在全域呼叫了foo(),而不是在obj上面呢?我把程式碼改一下,讓他輸出20:
var x = 10;
var obj = {
x: 20,
f: function () {
console.log(this.x);
}
};
obj.f();//20
對比一下,兩段程式碼,找找它們的不同。
曾经蜡笔没有小新2017-06-26 10:54:59
你可以把程式碼改寫為這樣子的:
var x = 10;
var obj = {
x: 20,
f: function () {
var foo = function (){
console.log(this.x);
}
foo.call(null) // 等价于foo.call(window)
}
};
obj.f.call(obj); //10 结果不变
透過上面的例子,你可以這樣理解 當呼叫一個函數的時候,JavaScript解析器是按照call或apply這樣的形式去呼叫的。 透過這樣的方式來為函數中的this指定一個值。這兩個方法的第一個參數就是foo方法被呼叫時其內部this的值,如果call方法的第一個參數為null、undefined時,就會預設把全域物件當作第一個參數(你可以試試試foo.call()、foo.call(null)、foo.call(undefined))