改變this指向了解一下

首先呢,我們知道return可以改變this指向

function Fn(name){
    this.name=name;
    return {};//undefined,改變了this的指向,指向該未定義對(duì)象
}
var fn=new Fn("maomin");
console.log(fn.name);



另一種是我們常用的方法,就是給將this賦值給一個(gè)變量。

function fn1(age) {
    var that=this;
    that.age=age;
    console.log(this.age)//21
}
fn1("21");



但是上面的方法太low了。
接下來(lái)我們說(shuō)一下關(guān)于改變this指向的三種高大上方法:

    call()
    (1)可以改變匿名函數(shù)this指向

var box=document.querySelector("#box");
box.onclick = function(){
  (function(){
    console.log(this); //box
  }).call(this);
};



(2)可以繼承方法

function Fn8(name,girlfriend) {
    this.name=name;
    this.girlfriend=girlfriend;
}
function Fn9(name,girlfriend) {
    Fn8.call(this,name,girlfriend);//第一個(gè)傳的是一個(gè)對(duì)象,就是你要借用的那個(gè)對(duì)象,除了第一個(gè)參數(shù)后面的參數(shù)將作為實(shí)際參數(shù)傳入到函數(shù)中。
    console.log(this.name,this.girlfriend);//maomin, xqm
}
var fn9=new Fn9("maomin","xqm");


(3)主動(dòng)執(zhí)行函數(shù)

function fnn() {
    var arr=[this.index,2,3]
    console.log(arr);//123
}
var val={index:1};
fnn.call(val);
//call就是挨個(gè)傳值,apply傳一個(gè)數(shù)組,bind也是挨個(gè)傳值,但和call和bind還有多少不同,使用call和apply會(huì)直接執(zhí)行這個(gè)函數(shù),而bind并不會(huì)而是將綁定好的this重新返回一個(gè)新函數(shù),什么時(shí)候調(diào)用由你自己決定。



2.bind()
bind 的其中一個(gè)用法就是:綁定函數(shù),使其無(wú)論怎么樣調(diào)用都用相同的 this。

var obj={
    ofn:function(){
        console.log(this);//obj
    }
}
obj.ofn();



那如果這樣呢
var ofn1=obj.ofn;
ofn1();//然而這時(shí),console.log(this);打印出來(lái)則是window。ofn1只是將obj對(duì)象中的方法復(fù)制過(guò)來(lái),但是this指向變了。ofn1()可以看作成window.ofn1()
為了改變這種現(xiàn)狀,可以用bind().
(1).

var objj={
    ofnn:function(){
        console.log(this);
    }
}
var oB=objj.ofnn;
oB.bind(objj)();//ofnn



(2).

 var obj = {
     num: 100,
     numFun: function(){
         console.log(this.num);//100
     }
 }
 var numFunCopy = obj.numFun;
 numFunCopy.bind(obj)();

var mName={name:"我是測(cè)試的值1"};
var nName={
    name:"我是測(cè)試的值2",
    say:function(){
        console.log(this.name);//我是測(cè)試的值1
    }.bind(mName)
}
nName.say();



3.apply()

function f(x, y){
console.log(x + y);
}
f.apply(null, [1, 1]) // 2


apply方法的第一個(gè)參數(shù)也是this所要指向的那個(gè)對(duì)象,如果設(shè)為null或undefined,則等同于指定全局對(duì)象。
第二個(gè)參數(shù)則是一個(gè)數(shù)組,該數(shù)組的所有成員依次作為參數(shù),傳入原函數(shù)。 原函數(shù)的參數(shù),在call方法中必須一個(gè)個(gè)添加,但是在apply方法中,必須以數(shù)組形式添加。

var a = [24,30,2,33,1]
Math.max.apply(null,a) //33  數(shù)組中最大值



總結(jié):

    call 、 apply 、bind 均能改變this 指向
    apply 每次執(zhí)行產(chǎn)生一個(gè)新函數(shù),call、apply 不會(huì)
    call ,bind 接收多個(gè)參數(shù)綁定到函數(shù),參數(shù)單一傳入,apply 接收方式為數(shù)組



作者:Vam的金豆之路

主要領(lǐng)域:前端開(kāi)發(fā)

我的微信:maomin9761

微信公眾號(hào):前端歷劫之路