函數(shù)的調(diào)用方式?jīng)Q定了 this的指向不同:
1. 普通函數(shù)調(diào)用,此時(shí)this?指向window
function fn(){
console.log(this);// window
? ? }
fn();//? window.fn(),此處默認(rèn)省略window
2. 構(gòu)造函數(shù)調(diào)用, 此時(shí)this 指向實(shí)例對(duì)象
function Person(age, name){
this.age = age;
this.name = name
console.log(this)// 此處 this 分別指向 Person 的實(shí)例對(duì)象 p1 p2
? ? }
varp1 =newPerson(18,'zs')
varp2 =newPerson(18,'ww')
3. 對(duì)象方法調(diào)用, 此時(shí)this指向該方法所屬的對(duì)象
var obj = {
fn:function(){
console.log(this);// obj
? ? ? }
? ? }
? ? obj.fn();
4.通過事件綁定的方法, 此時(shí) this指向綁定事件的對(duì)象
btn.onclick =function(){
console.log(this);// btn
? ? }
5. 定時(shí)器函數(shù), 此時(shí)this指向window
setInterval(function(){
console.log(this);// window
},1000);
以上五個(gè)方面 就是對(duì)函數(shù)內(nèi)部 this指向的基本整理
關(guān)于this 的終極總結(jié) :函數(shù)內(nèi)部的 this 是由調(diào)用時(shí)確定其指向,匿名函數(shù)的this指向window。
二.?接下來一起來看一下如何使用bind,call,apply改變this的指向,以及他們各自一些小的應(yīng)用
1.bind()會(huì)創(chuàng)建一個(gè)新的函數(shù)(稱為綁定函數(shù)),與被調(diào)用函數(shù)有相同的函數(shù)體,當(dāng)目標(biāo)函數(shù)被調(diào)用時(shí)this的值綁定到bind()的第一個(gè)參數(shù)上,如下面demo 此時(shí)this指向對(duì)象o
?語法: fn.bind(thisArg[, arg1[, arg2[, ...]]])? ?
?參數(shù):thisArg?當(dāng)綁定函數(shù)被調(diào)用時(shí),該參數(shù)會(huì)作為原函數(shù)運(yùn)行時(shí)的 this 指向。當(dāng)使用new 操作符調(diào)用綁定函數(shù)時(shí),該參數(shù)無效。?
? ? arg1,arg2..? 當(dāng)綁定函數(shù)被調(diào)用時(shí),這些參數(shù)將置于實(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();// 等價(jià) obj.fn.bind(o)()
2.call()??方法調(diào)用一個(gè)函數(shù), 其具有一個(gè)指定的this 值和分別地提供的參數(shù)(參數(shù)的列表)。
?語法: fn.call(thisArg[, arg1[, arg2[, ...]]])? ?
?參數(shù):thisArg?該參數(shù)會(huì)作為函數(shù)運(yùn)行時(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)用一個(gè)函數(shù), 其具有一個(gè)指定的 this 值,以及作為一個(gè)數(shù)組(或類似數(shù)組的對(duì)象)提供的參數(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)對(duì) bind,call,apply 有一定的認(rèn)識(shí)了,接下來看幾個(gè)案例
案例一 :
?需求: 調(diào)用該對(duì)象 fun 方法時(shí) 改變其 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 第二個(gè)參數(shù)是數(shù)組。