call/apply/bind 的理解與實例分享

call/apply 能夠改變函數的this指向。 除了傳遞參數時有所差異,callapply做用徹底同樣。node

var tim = { 
    name: 'tim', 
    age: 20, 
    getName: function() {
        console.log(this.name);
        return this.name; 
    }
}

var jake = { name: 'jake', age: 20 }

tim.getName(); // tim

// jake對象沒有getName方法,可是能夠經過call/apply去使用tim對象的getName方法
tim.getName.call(jake);  // jake 
tim.getName.apply(jake); // jake

tim.getName.call(jake)的意思是執行getName方法,可是經過call/applygetName方法中的this指向強行設置爲jake對象。所以最終的返回結果會是jake。數組

call apply的不一樣之處在於傳遞參數的形式。其中apply傳遞的參數爲數組形式, call傳遞的參數爲按順序依次排列。一個簡單的實例說明。app

// 當參數個數不肯定或者你以爲用apply比較爽時, 就直接使用apply
// 字面解釋就是obj奪舍fn,obj擁有了執行fn函數的能力,而且this指向obj.
var arguments = { 0:'name', 1:'age', 2:'gender' };

fn.apply(obj, arguments);
fn.call(obj, name, age, gender);

下面我收集了幾個我遇到過的實際例子函數

  • 將類數組形式轉換爲數組
// arguments
// 返回值爲數組,arguments保持不變
var arg = [].slice.call(arguments);

// nodeList
var nList = [].slice.call(document.getElementsByTagName('li'));
  • 方法借用
var foo = {
    name: 'joker',
    showName: function() {
        console.log(this.name);
    }
};
var bar = {
    name: 'rose'
};

foo.showName.call(bar); // rose
  • 在繼承中的應用
// parent
var Person = function(name) {
    this.name = name;
    this.gender = ['man', 'woman'];
}

// child
var Student = function(name, age) {

    // inherit
    Person.call(this);
}
Student.prototype.message = function() {
    console.log('name:'+this.name+', age:'+this.age+', gender:.'+this.gender[0]);
}

var xm = new Student('xiaom', 12);
xm.message(); //name:undefined, age:undefined, gender:.man
  • 封裝對象時保證this指向
var Nicco = function(name) {
    this.name = name;
}
Nicco.prototype = function() {
    constructor: Nicco,

    message: function() {
        var _this = this;
        addEventListener(
            'mousedown',
            function() {
                // stay this
                return _this.fndown.call(_this);
            },
            false
        );
    },

    fndown: function() {
        var
            _this = this,
            str = this.name + ', i miss you.';
        addEventListener(
            'mouseup',
            function() {
                return _this.fnup.call(_this, str);
            },
            false
        );
    },

    fnup: function(str) {
        console.log(str);
    }
}

clipboard.png

相關文章
相關標籤/搜索