上篇大致讲解了 this 在不同状况的指向,这篇会来讲讲使用 call/apply/bind 来绑定 this, 以及在严格模式下 this 指向会有所不同。
当我们遇上某些需求,要求 XX 函式中的 this
是某个特定物件,这时便会使用 call()
、 apply()
、bind()
来调整特性函式中的 this
。
这三个方法和 filter()
、 forEach()
一样是藉由原型提供的,因此这三个方法,不需要任何设定便可使用,这边先来看看范例
var name = 'Ryder'
function showName() {
console.log(this.name)
}
showName()
这是上一篇文章中 this 指向 window 的一个范例,这边试者使用 call()
方法,并且将一个新增的物件当作参数传入,如:
var name = 'Ryder'
var obj = {
name : 'Jack'
}
function showName(item1,item2,item3) {
console.log(this.name,item1,item2,item3) // Jack, test, {}, [0,1,2]
}
showName.call(obj,'test', {}, [0,1,2])
结果 showName
中的 this
会变成指向 obj
要注意的是使用 showName.call(obj)
他会立刻就回传,这是因为 call()
这个方法是使用後,会立刻执行函式,并且修正函式中的 this
,顺带一题在 call()
第一个参数是用来绑定函式中 this
的,第一个参数後面的参数,则都是传递给原本函示的参数。
apply()
与 call()
差异则是刚刚提到的 第一个参数後面的参数部分, 其他地方完全一致,call()
第一个参数後面的参数,是接受任何型别的参数 ,而 apply()
则只能使用第二个参数,并且只能接受阵列写法的参数,如果是阵列以外的都会跳错。
var name = 'Ryder'
var obj = {
name : 'Jack'
}
function showName(item1,item2,item3){
console.log(this.name,item1,item2,item3)
}
showName.apply(obj,['test',{}, [0,1,2] ]) // Jack, test, {}, [0,1,2]
showName.apply(obj,'test', {}, [0,1,2]) // 跳错
bind()
算是比较常用的,和 call()
、 apply()
不同,使用後函示并不会立刻执行,而是会回传要替换 this 的函式,因此我们会需要再使用 ()
呼叫替换後的函式,而参数部分则和 call()
接受任何形式的参数。
var name = 'Ryder'
var obj = {
name : 'Jack'
}
function showName(item1,item2,item3){
console.log(this.name,item1,item2,item3)
}
var test = showName.bind(obj)
test('test', {}, [0,1,2])
关於 call()
、 apply()
、 bind() 还有一点要提的是,使用第一个参数绑定 this 时,若如果我们传入的是纯值,那麽被替换的 tihs
会是以建构式的方式建立。
function Fn1(){
console.log(this) //String {'test'}
}
Fn1.bind('test')()
而传入 undefined
他则会替换成 window
function Fn1(){
console.log(this) // Window
}
Fn1.call(undefined)
关於这一点 MDN 也有解释:
注意,它可能是一个无法在函数内看到的值:若这个函数是在非严苛模式( non-strict mode ), null 、undefined 将会被置换成全域变数,而原生型态的值将会被封装
由於 JavaScript 这个语言特性,算是相对宽松,因此 ES5 新增 严格模式,用来规范 JavaScript 写法,并对程序码做一些限制。
若要使用严格模式会需要再该执行环境添加 'use strict'
的字串,如果我们直接在全域使用 'use strict'
基本上就是全部的程序码都会变为严格模式。
而我们本次介绍的 this
在严格模式下,部分的指向也会有所变动,那麽严格模式下 this
有甚麽更动?
主要有三点:
window
,严格模式下一律都会被转为 undefined
。call()
、 apply()
、 bind()
对 this
值做绑定时,若绑定的是纯值, this
的值会是建构式,严格模式下则会是纯值本身。call()
、 apply()
、 bind()
对 this
值做绑定时,绑定的是 undefined
、Null
,this
会是 window,严格模式下则会是传入的 undefined
、Null
。简易呼叫的范例:
var name = 'Ryder'
var array = [1,2,3]
function Fn() {
'use strict'
console.log(this) // undefined
}
Fn()
array.forEach(function(){
'use strict'
console.log(this) //undefined *3
})
this
绑定 undefined
、与纯值的范例
function Fn1(){
'use strict'
console.log(this) // undefined
}
Fn1.call(undefined)
function Fn2(){
'use strict'
console.log(this) // 'test'
}
Fn2.call('test')
JavaScript 核心篇 (六角学院)
今天要介绍的是legion,根据官方介绍,它是斯巴达的叉子 Legion, a fork of SE...
前言 昨天我们安装好Android Studio, 并且建立了一个专案叫做AIFER。 现在我们尝试...
Colab连结 虽然 Tensorflow 提供了几个预训练模型让我们可以很快的完成训练任务,但是有...
上一篇我们的基因体时代-AI, Data和生物资讯 Day08-合成生物学与机器学习分享合成生物学领...
预编译发生在何时? 执行全域前一刻,做全域的预编译;执行function前一刻,做function的...