開開森森學前端之this

前言

你們好,今天咱們來探究下this,咱們都清楚一句話:this的指向取決因而誰調用它,接下來咱們來看幾個例子。javascript

獨立函數調用

var a = 2;
function foo(){
  console.log(this.a);
}
foo();//答案是多少呢
複製代碼

解析:

這是最多見的獨立函數調用。是誰調用了它?固然是window,window.foo嘛。因此this指向了window,window.a天然是2因此輸出2java

對象調用

var a = 3;
function foo(){
  console.log(this.a);
}
var obj = {
  a:2,
  foo:foo
};
obj.foo();  //答案是多少呢
複製代碼

解析:

是誰調用了foo函數?是obj。因此this指向了objthis.a天然是等於obj.a,等於2因此輸出2面試

對象賦值調用

var a = 3;
function foo(){
  console.log(this.a);
}
var obj = {
  a:2,
  foo:foo
};
var func = obj.foo;
func ();   //答案是多少呢
複製代碼

解析:

這道題輸出3,這道題和剛剛上面的第二題有區別,func是對obj.foo的一個引用,實際上引用的仍是foo函數自己,因此func()foo()沒兩樣,所以this指向的是window。打印出3也是符合this的指向取決因而誰調用它這個觀點的。app

call調用

function foo(){
  console.log(this.a);
}
var obj = {
  a:2
};
foo.call(obj);   //答案是多少呢
複製代碼

解析:

callapply會強制將this綁定到第一個參數上,foo.call(obj)能夠理解爲foo函數讓obj來調用,因此this會指向obj因此輸出2函數

new調用

var a = 2;
function foo(){
  this.a = 3;
}
var bar = new foo();
console.log(a);  //答案是多少呢
console.log(bar.a);  //答案是多少呢
複製代碼

解析

這裏的foo函數是經過new操做符調用的,它會自動執行如下步驟ui

一、建立一個全新的對象this

二、這個新對象會執行[[Prototype]]鏈接spa

三、這個新對象會綁定到函數調用的thiscode

四、若是函數沒有返回其餘對象,那麼new表達式會自動返回這個新的對象 因此new來調用foo的時候,this指向了新的對象bar。所以this.a修改的是bar的屬性。對象

因此a輸出2,bar.a輸出3

setTimeout調用

function foo(){
  setTimeout(function(){
    console.log(this.a);
  })
}
var obj = {
  a:2
};
foo.call(obj);  //undefined
複製代碼

解析

輸出的undefined,那是由於setTimeout傳進的函數實際上是window在調用。而a沒有被定義,因此輸出undefined

setTimeout配合箭頭函數調用

function foo(){
  setTimeout(()=>{
    console.log(this.a);
  })
}
var obj = {
  a:2
};
foo.call(obj);  //答案是多少呢
複製代碼

解析

使用箭頭函數後,打印出的值就成了2。它的this是屬於foo()函數的做用域,而foo又是被obj調用的,因此會輸出2。 如今大多數this問題應該都能解釋了。

可是有一點要注意,嚴格模式下thisundefined

嚴格模式的this

var a = 2;
function foo(){
 "use strict"
  console.log(this.a);
}
foo()  //Uncaught TypeError: Cannot read property 'a' of undefined
複製代碼

總結

好了,今天咱們講了this相關面試題,你們能夠多加練習,掌握了this的大多數用法以及狀況的話,那麼對於大多數題目應該是無壓力的,固然我也但願你們能夠把this用到實際工做中,而不是爲了面試而面試!

相關文章
相關標籤/搜索