函數(shù)的調(diào)用方式?jīng)Q定了 this的指向不同:
1. 普通函數(shù)調(diào)用噪伊,此時this?指向window
function fn(){
console.log(this);// window
? ? }
fn();//? window.fn(),此處默認(rèn)省略window
2. 構(gòu)造函數(shù)調(diào)用簿煌, 此時this 指向實例對象
function Person(age, name){
this.age = age;
this.name = name
console.log(this)// 此處 this 分別指向 Person 的實例對象 p1 p2
? ? }
varp1 =newPerson(18,'zs')
varp2 =newPerson(18,'ww')
3. 對象方法調(diào)用, 此時this指向該方法所屬的對象
var obj = {
fn:function(){
console.log(this);// obj
? ? ? }
? ? }
? ? obj.fn();
4.通過事件綁定的方法鉴吹, 此時 this指向綁定事件的對象
btn.onclick =function(){
console.log(this);// btn
? ? }
5. 定時器函數(shù)姨伟, 此時this指向window
setInterval(function(){
console.log(this);// window
},1000);
以上五個方面 就是對函數(shù)內(nèi)部 this指向的基本整理
關(guān)于this 的終極總結(jié) :函數(shù)內(nèi)部的 this 是由調(diào)用時確定其指向,匿名函數(shù)的this指向window豆励。
二.?接下來一起來看一下如何使用bind,call,apply改變this的指向夺荒,以及他們各自一些小的應(yīng)用
1.bind()會創(chuàng)建一個新的函數(shù)(稱為綁定函數(shù)),與被調(diào)用函數(shù)有相同的函數(shù)體良蒸,當(dāng)目標(biāo)函數(shù)被調(diào)用時this的值綁定到bind()的第一個參數(shù)上技扼,如下面demo 此時this指向對象o
?語法: fn.bind(thisArg[, arg1[, arg2[, ...]]])? ?
?參數(shù):thisArg?當(dāng)綁定函數(shù)被調(diào)用時,該參數(shù)會作為原函數(shù)運行時的 this 指向诚啃。當(dāng)使用new 操作符調(diào)用綁定函數(shù)時淮摔,該參數(shù)無效。?
? ? arg1,arg2..? 當(dāng)綁定函數(shù)被調(diào)用時始赎,這些參數(shù)將置于實參之前傳遞給被綁定的方法
返回值:返回由指定的this值和初始化參數(shù)改造的原函數(shù)拷貝和橙。
var obj = {name:'obj'};
obj.fn =function(){
console.log(this)
? ? };
var o = {name:'o'};
var rel = obj.fn.bind(o);
rel();// 等價 obj.fn.bind(o)()
2.call()??方法調(diào)用一個函數(shù), 其具有一個指定的this 值和分別地提供的參數(shù)(參數(shù)的列表)。
?語法: fn.call(thisArg[, arg1[, arg2[, ...]]])? ?
?參數(shù):thisArg?該參數(shù)會作為函數(shù)運行時的this指向造垛。(如果指定了 null 或者 undefined 則內(nèi)部 this 指向 window)
arg1,arg2..? 指定的參數(shù)列表
var obj = {name:'obj'};
obj.fn =function(){
console.log(this)
? ? };
var o = {name:'o'};
obj.fn.call(o)//? 與bind的區(qū)別是魔招,call直接調(diào)用函數(shù)
3.apply()?方法調(diào)用一個函數(shù), 其具有一個指定的 this 值,以及作為一個數(shù)組(或類似數(shù)組的對象)提供的參數(shù)五辽。
?語法: fn.apply(thisArg[argArray])? ?
?參數(shù):thisArg argArray
apply() 與call()非常相似办斑,不同之處在于提供參數(shù)的方式,apply()使用參數(shù)數(shù)組,而不是參數(shù)列表
var obj = {name:'obj'};
obj.fn =function(a, b){
? ? ? ? a = b;
console.log(this)
? ? };
var o = {name:'o'};
obj.fn.apply(o, [1,3])
相信已經(jīng)對 bind乡翅,call鳞疲,apply 有一定的認(rèn)識了,接下來看幾個案例
案例一 :
?需求: 調(diào)用該對象 fun 方法時 改變其 this指向? 打印出 obj 的 name
var obj =? {
name:'zs',
fun:function(){
setInterval(function(){
console.log(this.name);
}.bind(this),1000);// 利用 bind 不調(diào)用函數(shù)特性此處this指向 obj
? ? ? ? ? ? }
? ? ? ? };
? ? ? ? obj.fun();
案例二:
var obj = {
0:10,
1:20,
2:30,
length:3
? ? ? ? };
Array.prototype.push.call(obj,40);
console.dir(obj);//0:10,1:20,2:30,3:40,length:4
案例三:
var arr = [4,5,6,8,11,44];
Math.max.apply(Math, arr);// 可以利用apply 第二個參數(shù)是數(shù)組蠕蚜。