讓人頭疼的this
阿新 • • 發佈:2018-11-06
this是什麼
this是函式執行時所在的環境變數,是call的第一個引數。
以及你需要注意的是,this這個鬼東西動不動就會變成window。
怎麼找this
作為物件方法呼叫
var obj = {
'fn': function(){
console.log(this)
}
}
obj.fn()
此時打印出來的this指的是obj這個物件。在函式作為物件方法呼叫的時候,this指的是呼叫這個函式的物件。
全域性函式呼叫
所謂全域性函式呼叫,區分於作為物件方法呼叫。
function fn(){ console.log(this) } fn()
此時打印出來的是window。在函式作為全域性函式呼叫的時候,this指的是window。
如果是在嚴格模式下,則預設是undefined。
'use strict'
function fn(){
console.log(this)
}
fn() //undefined
作為建構函式呼叫
function A(){
return this
}
var a = new A()
console.log(a)
此時的this指的是這個新new出來的物件。雖然這樣看起來理所當然,但是好像情況變複雜的話就容易出問題。暫且不提。
如果你搞不清楚上邊的三種情況,那麼請記住,this是call的第一個引數。
確切地說,call、apply以及bind的第一個引數。關於call、apply和bind的區別很多地方都有寫,這裡簡單提一下,call和apply都是直接呼叫該函式,不同的是call把所有引數一次傳進去,而apply的話,第一個引數是this,第二個引數是函式內部真正需要傳遞的引數構成的陣列(或者是一個偽陣列)。而bind的話,是繫結this並返回一個函式,不會直接進行函式呼叫。
var obj1 = {name: 'wcy'} var obj2 = {name: 'whw'} function fn(){ console.log(this) } var fn2 = fn.bind(obj1) fn2.call(obj2) //此時即使你傳入了obj2,得到的結果也是obj1,因為fn2的this已經被bind綁定了。
如果把call呼叫套在上邊的方法中的話,那麼我們可以不需要分類更簡單粗暴地得到this的值。
var obj = {
'fn': function(){
console.log(this)
}
}
var obj1 = {name: 'wcy'}
var obj2 = {name: 'whw'}
var fn2 = obj.fn
obj.fn.call()
fn2.call() //call不寫引數,在非嚴格模式下預設值是window,this指向window。在嚴格模式下預設沒有傳引數,所以是undefined。
obj.fn.call(obj) //call的第一個引數是obj,所以this是obj
fn2.call(obj1) //call的第一個引數是obj1,所以this是obj1
那麼,如果call的第一個引數傳的就是this呢?比如下面這樣
function X(){
return object = {
name: 'object',
fn1(x){
x.fn2.call(this) //這裡傳入的this指的就是當前的物件,也就是object。如果你不使用call呼叫的話,那麼呼叫的是options中的fn2,輸出結果也是options物件。
},
fn2(){
console.log('A')
console.log(this) //A
}
}
}
var options = {
name: 'options',
fn1(){},
fn2(){
console.log('B')
console.log(this) //B
}
}
var x = X()
x.fn1(options) //此時輸出的結果應該是B object物件