變態(tài)的this

前言

影響因素

  • 調(diào)用時輸入的參數(shù) params
  • 定義時的環(huán)境env

聲明一個函數(shù)

const f1 = new Function('x', 'y', 'return x+y')

function f2(x, y) {return x + y}

const f3 = function (x, y) {return x + y}

const f4 = (x, y) => x + y

其中f1 不常用,f2是聲明一個函數(shù)f2,const f3 和 const f4這兩個都不屬于函數(shù)聲明的部分,為什么要加上,因為f3 里面的函數(shù)是一個匿名函數(shù),如果沒有const f3 那么這個匿名函數(shù)聲明之后就找不到這個匿名函數(shù)了,所以必須聲明之后馬上賦值。f4 是最新的語法叫做箭頭函數(shù),括號里面的是參數(shù),然后返回x+y

f1、f2、f3是ES6之前的語法,支持this/arguments/new
而f4是ES6 新出的語法,不支持this/arguments/new

箭頭函數(shù)為何不支持this

const f =()=>console.log(this)

f() //Window

f.call({name:'小紅'}) //Window

image.png

看一下前言中函數(shù)的影響因素,一個是調(diào)用的參數(shù),一個是定義的環(huán)境。
在箭頭函數(shù)里面,this就是一個環(huán)境。

//代碼1
const a=233
const f2 =() => console.log(a)
//代碼2 
console.log(this)
const f1 =() -> console.log(this)

image.png

箭頭函數(shù)如何處理a ,就如何處理this

箭頭函數(shù)把this當做外部的變量,僅此而已,但是非箭頭函數(shù)的this有很多的特殊處理

箭頭函數(shù)不支持 this 指的就是箭頭函數(shù)對this與其他的變量一視同仁,不會特殊對待

非箭頭函數(shù)的this

死記方法

  • this是上下文
  • 全局環(huán)境執(zhí)行函數(shù)時,this是全局對象
  • 調(diào)用對象的方法時,this是該對象
  • 函數(shù)里調(diào)用函數(shù)時,this是全局對象
  • 箭頭函數(shù)里的this,不看調(diào)用,看定義(靜態(tài)作用域)
  • 還有人說箭頭函數(shù)里的this指向外面的this
  • 用new調(diào)用函數(shù)時,this是新增對象
  • 可以用call/apply/bind指定this

this是參數(shù)還是環(huán)境?

答:this是一個參數(shù),它是一個隱性參數(shù)

this的確定

顯式this
  • fn.call(asThis,1,2)
  • fn.bind(asThis,1,2)()
  • fn.method.call(obj,'hi')
隱式this
  • fn(1,2) // fn.call(undefined,1,2)
  • obj.method('hi') // obj.method.call('obj','hi')
  • array0 //array[0].call('array','hi')
image.png
image.png

最后一個圖怎么理解?
array是一個數(shù)組,[f,"2"],array[0]是一個函數(shù)f,然后加上括號就是調(diào)用這個函數(shù)f ,所以最后打印出來的this就是 array ,p1就是傳入的參數(shù)hi。

測試一下

button.onclick =function (e){
        console.log(this)  //this是參數(shù),答 button 是錯誤的
}

正確答案就是 不知道

第一種情況,用戶點擊按鈕

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<button id="a">按鈕</button>
</body>
    <script>
              var button =document.getElementById('a')
              
              button.onclick=function (e){
                    console.log(this)
              }
             
  </script>
</html>
image.png

答案的結(jié)果是button ,為什么會說這個答案是錯的呢?因為這里面沒有說用戶點擊這個按鈕,只是說了這段代碼

第二種情況 將button.onclick賦值給另一個變量,在調(diào)用

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<button id="a">按鈕</button>
</body>
    <script>
              var button =document.getElementById('a')
              
              button.onclick=function (e){
                    console.log(this)
              }
             
              var f =button.onclick
              f()
  </script>
</html>
image.png
image.png

解析:第一個就是不能確定this,第二個就是看調(diào)用的是誰

如何回答:這個this的值是無法確定,我們要看這次是如何調(diào)用的,如果是用戶點擊這個按鈕,那么瀏覽器就一定會把button作為參數(shù)傳進去。如果是通過其他方式調(diào)用的,就看它是怎么調(diào)用的。比如說:它聲明一個變量 f 等于這個 button.onclick ,然后調(diào)用,那么這次的瀏覽器就會把window作為參數(shù)傳入進去。如果你用其他方式,比如說 f.call('xiaohong'),那么瀏覽器傳入的就是字符串String

看下一個題目:

let length = 10

function fn() {
    console.log(this.length)
}

let obj = {
    length: 5,
    method(fn) {
        fn()
        arguments[0]()
    }
}

obj.method(fn, 1)

看不懂!看下一個代碼,將里面的 arguments[0]() 暫時去掉

let length = 10

function fn() {
    console.log(this.length)  //this 就是window ,window.length 就是看有多少個窗口或者iframe
}

let obj = {
    length: 5,
    method(fn) {
        fn.call(undefined)  //fn()
    }
}

obj.method(fn, 1)

這個時候很確定這里面的this指的就是Window

let length = 10

function fn() {
    console.log(this.length)
}

let obj = {
    length: 5,
    method(fn) {
        arguments[0]() 
    }
}

obj.method(fn, 1)

將里面的 arguments[0]() 改為 arguments[0].call(arguments),傳進去的this可以確定是一個數(shù)組,那么arguments[0] 也就是執(zhí)行fn,可以改為arguments.0.call(arguments) 所以就是fn.0.call(arguments) 最后就是fn.call(arguments) ,又因為obj.method(fn, 1)輸入了兩個參數(shù),因此里面的arguments 代表的就是實參的長度,所以這里輸出的是2

總結(jié)

規(guī)則

this是call的第一個參數(shù)
new 重新設(shè)計了this、箭頭函數(shù)不接受this

記憶點

  • 函數(shù)的返回值由參數(shù)和環(huán)境確定
  • this是參數(shù),arguments也是參數(shù)
  • 全局變量和自由變量是環(huán)境
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容