關於javascript中this指向的總結
瀏覽器環境
在全域性作用域中,this的指向是window物件
console.log(this);
//Window物件
console.log(this === window);
//true
複製程式碼
ES5函式中this的指向
在
非嚴格模式下,函式中的this指向window物件,因為此時函式fn是window的一個屬性,所以執行fn時,fn中的this指向window。其實this的指向就是指向函式的
執行時環境。
var fn = function () {
console.log(this);
console.log(this === window);
}
fn();
//Window物件
//true
複製程式碼
在
嚴格模式下,若不使用window呼叫函式,函式中的this指向undefined;使用window呼叫時,指向的時window物件。
var fn = function () {
'use strict'
console.log(this);
console.log(this === window)
}
fn();
//undfined
//false
window.fn();
//Window物件
//true
複製程式碼
在
嚴格模式下有一種例外的情況,就是在定時器中的this,此時無論使用window呼叫還是不使用window呼叫,this都指向window。
var fn = function () {
'use strict'
setTimeout(functioin(){
console.log(this);
console.log(this === window);
},1000)
}
fn();
//Window物件
//true
複製程式碼
在ES6中箭頭函式this的指向
在ES6中箭頭函式this的指向取決於
定義時環境中的this指向一致
var fun = () => {
console.log(this);
console.log(this === window);
}
fun();
//Window物件
//true
//定義箭頭函式時,就是這個過程:()=>{...}所在的環境是window,所以執行fun()時,箭頭函式內部的this指向window
複製程式碼
var obj = {
name:'Jay',
age:25,
fn:()=>{console.log(this)},
fun:function(){
console.log(this)
}
};
//在定義fn時,fn內部this的指向就是定義obj物件時所在的環境,obj所在的環境是window,所以呼叫obj.fn()時,返回的this就是Window物件
obj.fn(); //Window物件
obj.fun();//{name: "Jay", age: 25, fn: ƒ, fun: ƒ}
複製程式碼
var name = 'Kobe';
var obj = {
name:'Jay',
age:25,
fn1:function(){
return function(){
console.log(this.name);
}
},
fn2:() =>{
return () => {
console.log(this.name);
}
}
};
var fnn1 = obj.fn1();
var fnn2 = obj.fn2();
fnn1();//Kobe
fnn2();//Kobe
複製程式碼
在DOM事件中的this指向
DOM事件處理函式中this的指向是觸發該事件的物件
<div id='app'>App</div>
<script>
var $id = document.querySelector('#app');
$id.onclick = function () {
console.log(this);
}
</script>
//當點選App時,console.log(this),列印出來的值時 <div id='app'>App</div>
複製程式碼
建構函式中的this指向
建構函式中的this的指向是通過建構函式所建立出的物件例項
function Person (){
this.name = 'Jay',
this.age = 25;
console.log(this);
}
var p1 = new Person();
//Person {name: "Jay", age: 25}
複製程式碼
改變this的指向
可以使用call()、apply()、bind()改變函式內部this的指向(ES6中的箭頭函式除外)。其中call()和apply()在傳入要繫結的this指向時,立即執行。bind()在傳入要繫結的this指向時,並不執行,需要再次呼叫才會執行。
使用call()改變this的指向
var obj = {
name:'Jay',
age:25
};
function fn(){
console.log(this === obj);
console.log(this);
}
fn.call(obj);
//true
//{name: "Jay", age: 25}
複製程式碼
使用apply()改變this的指向
var obj = {
name:'Jay',
age:25
};
function fn(){
console.log(this === obj);
console.log(this);
}
fn.apply(obj);
//true
//{name: "Jay", age: 25}
複製程式碼
使用bind()改變this的指向
var obj = {
name:'Jay',
age:25
};
function fn(){
console.log(this===obj);
console.log(this);
}
//fn.bind(obj);不會立即執行,需要再次呼叫才會執行。
var fn1 = fn.bind(obj);
fn1();
//true
//{name: "Jay", age: 25}
複製程式碼
需要注意的是,當使用call()、apply()、bind()改變函式內部this的指向時,如果傳入的不是一個物件,會呼叫相對的建構函式,進行隱式型別裝換。
function fn(){
console.log(typeof this === 'object');
console.log(this);
}
fn.apply('I am a string');
//true
//String{"I am a string"}
複製程式碼