Javascript漂流記(下)__bind方法使用、bind方法實現及jQuery.proxy()使用

前面我們學習了改變this指向的兩個方法:call、apply

下面要隆重介紹第三種改變this指向的方法 ——bind

首先我們通過非常簡單的一小段代碼看一下bind的基本使用:

    var x = 10;
    function show(){
        console.log(this.x);//10    20
    }
    show();
    var aO = {
        x: 20
    }
    var newShow = show.bind(aO);
    newShow();

還可以傳入參數

    var x = 10;
    function show(a, b){
        console.log(this.x, a, b);//10 'a' 'b'    20 'c' 'd'
    }
    show('a', 'b');
    var aO = {
        x: 20
    }
    var newShow = show.bind(aO, 'c', 'd');
    newShow();
    //var newShow = show.bind(aO, 'c');
    //newShow('d');

除此之外,在單對象編程的過程中,bind發揮了重大的作用:需求如下,在頁面中有一個button按鈕,在點擊button時,打印相應信息。

    var list = {
        init : function(){
            //this -> list
            this.ms = 'duyi';
            this.dom = document.getElementsByTagName('button')[0];//此處獲取一個button元素
            this.bindEvent();
        },
        bindEvent : function(){
            //this -> list
            this.dom.onclick = this.showMessage.bind(this, 'hello', 'world');
        },
        showMessage : function(info1, info2, e){
            //不改變this指向的話,this -> dom,而dom中並沒有ms
            console.log(this.ms, info1, info2, e);//duyi hello world 事件對象
        }
    }
    list.init();

下面我們來總結一下bind的使用方法:

    function A(){}
    var obj = {};
    var x = 1;
    var y = 2;
    var z = 3;
    var B = A.bind(obj, x, y);
    B(z);
    //new B().constructor -> A

    1.函數A調用bind方法時,需要傳遞參數obj,xy...

    2.會返回新的函數B

    3.函數B在執行時,具體功能還是使用的A,但this指向了obj

    4.函數B在執行時,傳遞的參數會拼接到xy..後面,一併在內部傳遞給A執行

    5.new B(), 構造函數依舊是A,而且obj不會起到任何作用

那麼bind在內部到底是如何來實現的呢?請看如下代碼:

    Function.prototype.newBind = function(target){
        //target改變返回函數執行的this指向
        var self = this;//誰調用的newBind,this就是誰
        var args = [].slice.call(arguments, 1);
        var temp = function(){};
        var f = function(){
            //真正執行的self的功能
            //new f()
            var _arg = [].slice.call(arguments, 0);
            return self.apply(this instanceof temp ? this : (target || window), args.concat(_arg));
        }
        temp.prototype = self.prototype;
        f.prototype = new temp();
        return f;
    }

在後續要學到的jQuery中,實現了類似bind的方法$.proxy(),簡單瞭解一下

    var name = 'Lebron';
    function show(){
        console.log(this);//James
    }
    var obj = {
        name: 'James',
        age: 123
    }
    var showProxy = $.proxy(show, obj);//並沒有改變原來show的this,而是生成一個新的方法
    showProxy();
    var list = {
        init : function(){
            //this -> list
            this.mes = 123;
            this.dom = document.getElementById('demo');
            this.bindEvent();
        },
        bindEvent : function(){
            //this -> list
            this.dom.onclick = $.proxy(this.show, this);//改變this指向
        },
        show : function(){
            //不改變的話,this -> dom,去找調用它的地方找問題!!!
            console.log(this.produceMes(this.mes));
        },
        produceMes : function(mes){
            return mes + 234;
        }
    }
    list.init();

以上內容屬二哥原創,整理自 "渡一教育Javascript課程" ,一個值得推薦的"渡一教育"。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章