js – this , call , bind , apply
在 js 中,常見的涵式調用共有六種,各涵式的this指向也不同:
1.普通涵數 => this 指向 window
function fn(){
console.log("普通涵數 this ==> ",this)
}
fn();
2.物件的方法 => this 指向 obj
var obj = {
sayHi:function(){
console.log("物件涵數 this==>",this)
}
}
obj.sayHi();
3.構造涵數 => this 指向 andyLui 實例
function Star(){
console.log("構造涵數this ==> ",this)
}
var andyLui = new Star();
4.綁定事件涵數 => this 指向 btn
var btn = document.querySelector('button')
btn.addEventListener('click',function(){
console.log("綁定事件涵數this==> ",this)
})
5. 定時器函數 => this 指向 window
setTimeout(function(){
console.log("定時器函數this==>",this)
},1000)
6. 立即執行函數 => this 指向 window
(function(){
console.log("立即執行函數this==>",this)
})()
以上雖然得知當前 this 的指向,但this指向是可以改變的,向常用的就有 bind, apply, call 等方法。
call( )
call 可以調用函數,也可以改變 this 指向。
var o ={
name:'andy'
}
function fn(a,b){
console.log(this,a+b)
}
fn.call()
當我們這時候直接寫 fn.call( ) 時, this 是指向 window,如果我們要指向 o 這物件就需要改成
fn.call(o,1,2)
一般來說, call ( ) 會常用於繼承的情況,讓子類繼承父類的屬性。
function Father(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex ;
}
function Son (name,age,sex){
Father.call(this,name,age,sex)
}
var cow = new Son("牛牛",20,'boy')
apply( )
apply 和 call 一樣,也是用來改變函數內部 this 指向,但傳遞參數是用 陣列方式傳遞。
var o ={
name:'andy'
}
function fn(arry){
console.log(this)
console.log(arry) // 'pink'
}
//call調用函數
fn.apply(o,['pink'])
例如可以處理陣列相關最大值
var arr =[1,66,30,99,28]
var max = Math.max.apply(Math,arr)
console.log("最大值",max)
個人覺得 aplly 跟 call 有點像把別人既有功能拿來用。在傳參數中,第一個參數都是要把 this 只向誰(誰調用這個方法的人),像call中的例子,因為孩子要繼承或調用父類的屬性,所以 this 指向 Son。 則 call 的例子,是Math 要去調用 max 方法,找出陣列最大值,所以 this 會指向 Math。
bind( )
bind 可以改變函數內部 this 指向,但不會調用,當bind後,它會回傳一個已經改變this指向的新函數。
var o ={
name:'andy'
}
function fn(a,b){
console.log(this)
console.log(a+b)
}
//bind
const f = fn.bind(o,1,2);
f()
bind 常見使用例子