1.在普通模式下和嚴格模式下,this指向不同,普通模式下this指向window全局變量,而嚴格模式指向undefined
2. 下面看這道題,會輸出什麼?
var length = 10;
function fn(){
console.log(this.length);
}
var obj = {
length:5,
method:function(fn){
fn();
arguments[0]();
}
}
obj.method(fn,1);
在嚴格模式下,輸出10的那次的fn的this實際是undefined,在非嚴格模式下才成爲了global,並且由於JavaScript允許傳入任意個參數而不影響調用,因此傳入的參數比定義的參數多也沒有問題,雖然函數內部並不需要這些參數
至於第二的arguments[0]()的輸出,你就想一下,arguments[0]就是fn,相當於arguments['fn'](實際上只能用index來獲得,這麼寫是方便你理解),這個this是arguments.
其實綁定this的,除了顯式的bind,apply,call,就是通過object.foo或者object['foo']來綁定
3.綁定this的幾個方法,綁定this的,除了顯式的apply,bind,call(俗稱ABC方法),就是通過object.foo或者object['foo']來綁定
function foo(a, b, c) {}
var bar = {};
foo.apply(bar, [1, 2, 3]); // 數組將會被擴展,如下所示
foo.call(bar, 1, 2, 3); // 傳遞到foo的參數是:a = 1, b = 2, c = 3
bind的返回值是函數,並且
②後面的參數的使用也有區別
function f(a,b,c){ console.log(a,b,c); } var f_Extend = f.bind(null,"extend_A") f("A","B","C") //這裏會輸出--> A B C f_Extend("A","B","C") //這裏會輸出--> extend_A A B f_Extend("B","C") //這裏會輸出--> extend_A B C f.call(null,"extend_A") //這裏會輸出--> extend_A undefined undefined
這個區別不是很好理解
call 是 把第二個及以後的參數作爲f方法的實參傳進去,
而bind 雖說也是獲取第二個及以後的參數用於之後方法的執行,但是f_Extend中傳入的實參則是在bind中傳入參數的基礎上往後排的。
4.this 指向
* 全局範圍內,當在全部範圍內使用
this
,它將會指向全局對象。
* 作爲一個對象的方法調用的時候,this 指向那個對象,比如 obj.fn()
* 作爲一個普通函數(或者匿名函數)調用的時候,指向全局對象 window,比如 fn(),(這題屬於這種情況,就算你把函數定義在裏面也一樣...)
* 構造函數中 this 指向實例化的對象
* 還有使用 call 和 apply 動態改變 this 的指向
舉幾個《JavaScript 高級程序設計》上第七章的栗子...
1. 不符合預期的閉包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
var
name = "The Window" ; var
object = { name: "My Object" , getNameFunc: function () { return function () { return
this .name; }; } }; alert(object.getNameFunc()()); // The Window (非嚴格模式下), // 此處有兩個括號,因爲 object.getNameFunc() 是一個匿名函數, // 後一個括號是匿名函數調用。 |
爲什麼匿名函數沒有取得其包含作用域(或外部作用域)的 this 對象呢?
前面曾經提到過,每個函數在被調用時都會自動取得兩個特殊變量:this 和 arguments。而內部函數在搜索這兩個變量時,只會搜索到其 AO 爲止,所以永遠不能直接訪問到外部函數中的 this 和 arguments。
不過若是我們將外部作用域中的 this 對象保存在一個閉包能夠訪問到的變量裏,就可以讓閉包訪問到該對象了:
2. 符合預期的閉包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
var
name = "The Window" ; var
object = { name: "My Object" , getNameFunc: function () { var that =
this ; // 使用 that 保存外部函數的 this //(防止被內部函數的 this 屏蔽) return function () { return that.name;
// 由於訪問的是內部 AO 中沒有的變量 that, // 所以在 SC 中外部的 AO 上搜索, // 得到外部函數的 this。 }; } }; alert(object.getNameFunc()()); // My Object |
結論:在對象的方法的內部函數(可以認爲是二級函數)不會自動指向當前的對象,即就是在對象的內部函數裏面調用的函數,並不會自動繼承指向對象的this指針,而是指向window或者undefined
請看js祕密花園中的
this