前言
影響因素
-
調(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
看一下前言中函數(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)
箭頭函數(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')
最后一個(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>
答案的結(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>
解析:第一個(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)境