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课程" ,一个值得推荐的"渡一教育"。

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