變態(tài)的this

前言

影響因素

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

聲明一個(gè)函數(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是聲明一個(gè)函數(shù)f2孵延,const f3 和 const f4這兩個(gè)都不屬于函數(shù)聲明的部分运挫,為什么要加上状共,因?yàn)閒3 里面的函數(shù)是一個(gè)匿名函數(shù),如果沒(méi)有const f3 那么這個(gè)匿名函數(shù)聲明之后就找不到這個(gè)匿名函數(shù)了谁帕,所以必須聲明之后馬上賦值峡继。f4 是最新的語(yǔ)法叫做箭頭函數(shù),括號(hào)里面的是參數(shù)匈挖,然后返回x+y

f1碾牌、f2、f3是ES6之前的語(yǔ)法关划,支持this/arguments/new
而f4是ES6 新出的語(yǔ)法小染,不支持this/arguments/new

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

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

f() //Window

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

image.png

看一下前言中函數(shù)的影響因素,一個(gè)是調(diào)用的參數(shù)贮折,一個(gè)是定義的環(huán)境裤翩。
在箭頭函數(shù)里面,this就是一個(gè)環(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當(dāng)做外部的變量,僅此而已每庆,但是非箭頭函數(shù)的this有很多的特殊處理

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

非箭頭函數(shù)的this

死記方法

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

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

答:this是一個(gè)參數(shù)胚嘲,它是一個(gè)隱性參數(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

最后一個(gè)圖怎么理解作儿?
array是一個(gè)數(shù)組,[f,"2"],array[0]是一個(gè)函數(shù)f馋劈,然后加上括號(hào)就是調(diào)用這個(gè)函數(shù)f 攻锰,所以最后打印出來(lái)的this就是 array 晾嘶,p1就是傳入的參數(shù)hi。

測(cè)試一下

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

正確答案就是 不知道

第一種情況垒迂,用戶點(diǎn)擊按鈕

<!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 ,為什么會(huì)說(shuō)這個(gè)答案是錯(cuò)的呢妒蛇?因?yàn)檫@里面沒(méi)有說(shuō)用戶點(diǎn)擊這個(gè)按鈕娇斑,只是說(shuō)了這段代碼

第二種情況 將button.onclick賦值給另一個(gè)變量,在調(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

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

如何回答:這個(gè)this的值是無(wú)法確定,我們要看這次是如何調(diào)用的唯竹,如果是用戶點(diǎn)擊這個(gè)按鈕乐导,那么瀏覽器就一定會(huì)把button作為參數(shù)傳進(jìn)去。如果是通過(guò)其他方式調(diào)用的浸颓,就看它是怎么調(diào)用的物臂。比如說(shuō):它聲明一個(gè)變量 f 等于這個(gè) button.onclick ,然后調(diào)用,那么這次的瀏覽器就會(huì)把window作為參數(shù)傳入進(jìn)去产上。如果你用其他方式棵磷,比如說(shuō) f.call('xiaohong'),那么瀏覽器傳入的就是字符串String

看下一個(gè)題目:

let length = 10

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

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

obj.method(fn, 1)

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

let length = 10

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

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

obj.method(fn, 1)

這個(gè)時(shí)候很確定這里面的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),傳進(jìn)去的this可以確定是一個(gè)數(shù)組谢鹊,那么arguments[0] 也就是執(zhí)行fn算吩,可以改為arguments.0.call(arguments) 所以就是fn.0.call(arguments) 最后就是fn.call(arguments) ,又因?yàn)閛bj.method(fn, 1)輸入了兩個(gè)參數(shù)佃扼,因此里面的arguments 代表的就是實(shí)參的長(zhǎng)度偎巢,所以這里輸出的是2

總結(jié)

規(guī)則

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

記憶點(diǎn)

  • 函數(shù)的返回值由參數(shù)和環(huán)境確定
  • this是參數(shù)兼耀,arguments也是參數(shù)
  • 全局變量和自由變量是環(huán)境
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末压昼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子瘤运,更是在濱河造成了極大的恐慌窍霞,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尽超,死亡現(xiàn)場(chǎng)離奇詭異官撼,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)似谁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門傲绣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)掠哥,“玉大人,你說(shuō)我怎么就攤上這事秃诵⌒螅” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵菠净,是天一觀的道長(zhǎng)禁舷。 經(jīng)常有香客問(wèn)我,道長(zhǎng)毅往,這世上最難降的妖魔是什么牵咙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮攀唯,結(jié)果婚禮上洁桌,老公的妹妹穿的比我還像新娘。我一直安慰自己侯嘀,他們只是感情好另凌,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著戒幔,像睡著了一般吠谢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诗茎,一...
    開(kāi)封第一講書(shū)人閱讀 49,772評(píng)論 1 290
  • 那天工坊,我揣著相機(jī)與錄音,去河邊找鬼错沃。 笑死栅组,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的枢析。 我是一名探鬼主播玉掸,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼醒叁!你這毒婦竟也來(lái)了司浪?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤把沼,失蹤者是張志新(化名)和其女友劉穎啊易,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體饮睬,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡租谈,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片割去。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡窟却,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出呻逆,到底是詐尸還是另有隱情夸赫,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布咖城,位于F島的核電站茬腿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏宜雀。R本人自食惡果不足惜切平,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辐董。 院中可真熱鬧揭绑,春花似錦、人聲如沸郎哭。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)夸研。三九已至,卻和暖如春依鸥,著一層夾襖步出監(jiān)牢的瞬間亥至,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工贱迟, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留姐扮,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓衣吠,卻偏偏與公主長(zhǎng)得像茶敏,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子缚俏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容