方法、this的講解、apply&call&bind的理解

方法與函數(shù)

在一個對象中綁定函數(shù),稱為這個對象的方法。



this的各種坑!??!

1. 先來個正常的,this指向執(zhí)行環(huán)境的對象

var xiaoming = {
    name: '小明',
    birth: 1990,
    age: function () {
        var y = new Date().getFullYear();
        return y - this.birth;
    }
};
xiaoming.age; // function xiaoming.age()
xiaoming.age(); // 今年調(diào)用是25,明年調(diào)用就變成26了

2. “this指向執(zhí)行環(huán)境的對象

 function getAge() {
    var y = new Date().getFullYear();
    return y - this.birth;
}
var xiaoming = {
    name: '小明',
    birth: 1990,
    age: getAge
};
xiaoming.age(); // 25, 正常結(jié)果
getAge(); // NaN

function getAge是綁定在window下的函數(shù),就相當(dāng)于window的方法,this指向window理所當(dāng)然。


getAge此時(shí)是回調(diào)函數(shù)。等同于如下寫法:(與1中一樣)

var xiaoming = {
    name: '小明',
    birth: 1990,
    age:  function getAge() {
    var y = new Date().getFullYear();
    return y - this.birth;
    
};

與此類似:

var fn = xiaoming.age; // 先拿到xiaoming的age函數(shù)
fn(); // NaN

非嚴(yán)格模式下,變量未被定義就被調(diào)用,返回NaN。(沒毛病)


'use strict';

var xiaoming = {
    name: '小明',
    birth: 1990,
    age: function () {
        var y = new Date().getFullYear();
        return y - this.birth;
    }
};

var fn = xiaoming.age;
fn(); // Uncaught TypeError: Cannot read property 'birth' of undefined

嚴(yán)格模式下,變量未被定義就被調(diào)用,返回undefined(指向Undefined對象)。(沒毛病)


總之:正確的姿勢是object.xxx()的調(diào)用指向正確

xiaoming.age()//this指向xiaoming

3. 修復(fù)方法。用一個that變量首先捕獲this

 'use strict';

var xiaoming = {
    name: '小明',
    birth: 1990,
    age: function () {
        var that = this; // 在方法內(nèi)部一開始就捕獲this
        function getAgeFromBirth() {
            var y = new Date().getFullYear();
            return y - that.birth; // 用that而不是this
        }
        //定義其他方法,而不是把所有語句都堆到一個方法中
        function getAgeFromBirth(){
            var return that.birth;
        }
        return getAgeFromBirth();
    }
};

var that = this;,你就可以放心地在方法內(nèi)部定義其他函數(shù),而不是把所有語句都堆到一個方法中。

xiaoming.age(); // 25

4. 用arguments.callee()代替this也是不可以的。

arguments.callee()指向當(dāng)前調(diào)用的函數(shù),常用在匿名函數(shù)里指代該匿名函數(shù)。



apply()、call()bind()理解

1. 要指定函數(shù)的this指向哪個對象,可以用函數(shù)本身apply()方法

apply vt. “應(yīng)用”的意思。apply the Function to Object.(將函數(shù)應(yīng)用于某對象)
call vt.vi."需要"的意思。call for the Object.(需要某對象來運(yùn)行這個函數(shù))

簡單粗暴的這樣理解,便于記憶。

apply(thisObj,args)
thisObj表示函數(shù)內(nèi)this所指代的對象(Obj)(是誰),備選值:this null object實(shí)例

  • thisObjthis時(shí),調(diào)用apply()的函數(shù)中this所指代的對象
  • thisObjnull時(shí),thisObj使用全局對象
  • thisObjobject實(shí)例時(shí),很常見

args表示傳入的參數(shù),可以是argumentArray實(shí)例
返回function執(zhí)行的值

例如:

//將默認(rèn)的Object.toString()應(yīng)用到對象o上,以覆蓋對象o中自定義的toString()方法。
Object.prototype.toString().apply(o);
//調(diào)用Math.max()方法來查找數(shù)組中的最大元素
var data = [1,2,3,4,5,6];
Max.max.apply(null,data);
window.color = "red";
var o = {
    color:"blue";
    }
function sayColor(){
    alert(this.color);
    }
sayColor(); //red
sayColor().apply(this);//red
sayColor().apply(window);//red
sayColor().apply(o);;//blue

call()apply()類似
call(thisObj,arg1,arg2,......)

  • arg1,arg2,......表示按照順序傳入?yún)?shù)。

2. bind() ES5新增

bind vi. “捆綁”的意思。bind the Function to the Object.(將函數(shù)綁入對象里面,函數(shù)此時(shí)成了該對象的方法,也就是說,此時(shí)函數(shù)內(nèi)的this指向綁定的對象o

bind(o,arg1,arg2,....)

例如:

function getName() {
    console.log(this.name);
    }
var o = {
    name:xiaoxiao;
    age:18;
    };
var result=getName().bind(o);
result();//xiaoxiao
getName();//undefined or NaN

參數(shù)可以分兩次傳遞:

//假設(shè)f為一個函數(shù)
var g = f.bind(0,1,2);
//此時(shí)g為一個新函數(shù),g(3)等價(jià)于:
f.call(0,1,2,3);

var o1={
    x:1,
    getplus:function(y,z){
      return this.x+y+z;
    }
  }
  var o2={
    x:11,
    getplus:function(y,z){
      return this.x*y;
    }
  }
  //o1.getplus需要2個參數(shù),分兩次傳入
  var result=o1.getplus.bind(o2,1);
  //得到的result是函數(shù),函數(shù)result需要另一個參數(shù)才能計(jì)算x+y+z的值
  result(3);//得出計(jì)算結(jié)果
  var resultapply=o1.getplus.call(o2,1,2);//與上面兩步得出的結(jié)果一樣

使ES3也兼容bind()的方法:

//如果方法不存在,就在原型里添加
//提示:bind()返回的是函數(shù)
if(!Function.prototype.bind){
    Function.prototype.bind=function(o /*,args*/){
        var self=this,boundArgs=arguments;
            //**此時(shí)Function是對象,this指向Funtion本身**,并把它保存起來
            //arguments也保存起來,這里的arguments是第一次傳入的參數(shù),所以下面for循環(huán)從第二個參數(shù)開始
        return function(){
            var args=[],i;
            for(i=1;i<boundArgs.length;i++) args.push(boundArgs[i]);
                //遍歷第一次傳入的參數(shù),從第二位開始(第一位是對象)
            for(i=0;i<arguments.length;i++) args.push(arguments[i]);
                //遍歷第二次傳入的參數(shù),全部遍歷
            return self.apply(o,args);
        }
    }
}
self為何指代被調(diào)用的方法

解釋:self的值是指向function的指針。

var result=o1.getplus.bind(o2,1);

其中o1.getplus方法(函數(shù))是圖中紅色的Function對象,而self指針是圖中的小this。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容