目錄
1.this究竟是什么
2.綁定this的方法
3.caller逗抑、arguments和callee
1.this究竟是什么
this總是指向一個調(diào)用當前屬性或方法所在的對象,它在不同的運行環(huán)境(屬性和方法的調(diào)用者)指向的環(huán)境(對象)不同寒亥,也就是說this的指向是動態(tài)的锋八,但是無論this的指向是誰,只要清楚屬性和方法的調(diào)用者是誰那么this就指向誰护盈。
//在瀏覽器全局環(huán)境下,即window對象下
var print = function(){
console.log(this)
}
print()//this指向Window羞酗,因為這是Window對象調(diào)用了print方法
//在特定對象的環(huán)境下
var o = {
print: function(){
console.log(this)
}
}
o.print()//this指向o腐宋,因為這是o對象調(diào)用print方法
2.綁定this的方法
this的動態(tài)切換,固然為JavaScript創(chuàng)造了巨大的靈活性檀轨,但有時胸竞,需要把this固定下來,避免出現(xiàn)意想不到的情況参萄。JavaScript提供了call卫枝、apply、bind這三個方法讹挎,來切換/固定this的指向校赤。
- function.prototype.call()
函數(shù)實例的call方法可以指定函數(shù)內(nèi)部this的指向,即函數(shù)執(zhí)行時所在的作用域
var obj = {};
var fn = function(){
return this
}
fn() === this // true
fn.call(obj) === obj // true
fn()執(zhí)行時所在的作用域是全局環(huán)境筒溃,所以this是window马篮,而fn.call(obj)則是在對象obj環(huán)境下執(zhí)行的,所以此時的this指向obj怜奖。
fn.call(null) === this
fn.call(undefined) === this
fn.call === this
call方法內(nèi)部的參數(shù)如果為空浑测、null和undefined,則默認傳入全局對象歪玲。
var obj = {};
var add = function(x,y){
return x+y
}
add.call(obj,2,3)
call方法還可以接受多個參數(shù)迁央。call的第一個參數(shù)就是this所要指向的那個對象,后面的參數(shù)則是函數(shù)調(diào)用時所需的參數(shù)滥崩。
-
function.prototype.apply()
apply方法的作用與call方法類似岖圈,也是改變this指向,然后再調(diào)用該函數(shù)夭委。唯一的區(qū)別就是幅狮,它接收一個數(shù)組作為函數(shù)執(zhí)行時的參數(shù)募强。
function fn(x,y){
return x+y
}
fn.call(null,1,1)//2
fn.apply(null,[1,1])//2
fn函數(shù)本來接受兩個參數(shù),使用apply方法以后崇摄,就變成可以接受一個數(shù)組作為參數(shù)擎值。
【注】
結(jié)合apply和數(shù)組,我們可以寫一個小代碼找出數(shù)組最大或最小元素逐抑;
var arr = [3,5,7,10,2,8];
//未利用apply方法
var min = arr[0];
for (var i = 0;i<arr.length;i++){
if(arr[i]< min){
min = arr[i]
}
}
console.log(min)//2
//使用apply方法
Math.min.apply(null,arr)//2
-
function.prototype.bind()
bind方法用于將函數(shù)體內(nèi)的this綁定到某個對象鸠儿,然后返回一個新函數(shù),原理和call方法類似厕氨。
3.caller进每、callee和arguments
-
caller
當函數(shù)outer調(diào)用函數(shù)inner時,被調(diào)用的函數(shù)inner會自動生成一個caller屬性命斧,指向調(diào)用它的函數(shù)對象田晚。
如果該函數(shù)未被調(diào)用或是不是被其他函數(shù)調(diào)用,則caller為null国葬。
function outer(){
console.log(outer.caller);
function inner(){
console.log(inner.caller);
};
inner()
}
outer()
//null
//function outer(){}
- arguments
在函數(shù)被調(diào)用時贤徒,會在該函數(shù)內(nèi)部生成一個名為arguments的類數(shù)組的隱藏對象,可以使用[]運算符獲取函數(shù)調(diào)用時傳遞的實參汇四,只有函數(shù)被調(diào)用時接奈,arguments對象才會創(chuàng)建。
function fn(a,b){
console.log(arguments);
}
fn(1,2)//[1,2]
-
callee
當函數(shù)被調(diào)用時通孽,它的arguments.callee對象就會指向自身,由于arguments在函數(shù)被調(diào)用時才有效序宦,因此arguments.callee在函數(shù)未調(diào)用時是不存在的。
function fn(){
console.log(arguments.callee());
}
fn()//fn(){}
【注】
本次筆記整理自阮一峰JavaScript標準參考教程和饑人谷筆記