zoukankan      html  css  js  c++  java
  • 浅析 JavaScript 中的 Function.prototype.bind() 方法

    Function.prototype.bind()方法

    bind() 方法的主要作用就是将函数绑定至某个对象,bind() 方法会创建一个函数,函数体内this对象的值会被绑定到传入bind() 函数的值。

    例如,在 f() 函数上调用 bind() 方法并传入参数 obj ,即 f.bind(obj) ,这将返回一个新函数, 新函数会把原始的函数 f() 当做 obj 的方法来调用,就像 obj.f() 似的,当然这时 f() 函数中的 this 对象指向的是 obj

    简单使用情形一

    var o={
        f: function () {
            var self=this;
            var fff=function() {
                console.log(self.value);  //此时 this 指向的是全局作用域 global/window,因此需要使用 self 指向对象o
            };
            fff();
        },
        value: "Hello World!"
    };
    o.f(); // Hello World! 
    

    上例是我们常用了 保持 this 上下文的方法,把 this 赋值给了中间变量 self,这样在内部嵌套的函数中能够使用 self 访问到对象o,否则仍使用 this.value,内部嵌套函数的this此时指向的是全局作用域,最后的输出将会是 undefined,代码如下:

    var o={
        f: function () {
            var self=this;
            var fff=function() {
                console.log(this.value); 
            };
            fff();
        },
        value: "Hello World!"
    };
    o.f(); // undefined
    

    但是,如果我们使用 bind()函数,将fff函数的绑定在对象o中,即将fff()函数内部的 this 对象绑定为对象 o,那么可以遇见此时 this.value 是存在的。代码如下:

    var o={
        f: function () {
            var self=this;
            var fff=function() {
                console.log(this.value); // bind(this) 中 this 指向的是o,这里也可直接写成 bind(o)
            }.bind(this);
            fff();
        },
        value: "Hello World!"
    };
    o.f(); // Hello World!
    

    更普遍的使用情形

    再看一个例子:

    function f(y,z){
        return this.x+y+z;
    }
    var m=f.bind({x:1},2); 
    console.log(m(3));  // 6
    

    最后将输出 6

    这是因为 bind()方法会把传入它的第一个实参绑定给f函数体内的 this,从第二个实参起,将依此传递给原始函数,因此 {x:1}传递给this ,2传递给形参ym(3) 调用时的3 传递给形参z

    其实这个例子 f() 函数能够处理部分参数,分步计算 ( bind() 时处理了参数x,和参数y,调用 m(3)时处理了参数z )的过程其实是一个典型的Curry过程(Currying)。

    bind()背后的简单原理

    那么bind函数背后做了什么呢? 我们可以用以下代码来模拟:

    Function.prototype.testBind = function (scope) {
        var fn = this;                                // this 指向的是调用testBind方法的一个函数
        return function () {
            return fn.apply(scope, arguments);
        }
    };
    

    下面是测试的例子:

    var foo = {x: "Foo "};
    var bar = function (str) {
        console.log(this.x+(arguments.length===0?'':str));
    };
    
    bar();                                   // undefined
    
    var testBindBar = bar.testBind(foo);     // 绑定 foo
    testBindBar("Bar!");                     // Foo Bar!
    

    当调用 testBind() 后,我们创建了一个新的函数,通过调用 applythis 设置成 foo, OK,现在应该比较清晰了,但实际 bind() 的实现远比上面的复杂,如上面提到的 curry化过程等,上面只是主要原理便于学习理解 bind() 函数。

    参考资料:
    Javascript权威指南

  • 相关阅读:
    Android 如何自定义EditText 下划线?
    一步一步理解 Java 企业级应用的可扩展性
    客户案例—北京优络时代科技有限公司
    11个显著提升 ASP.NET 应用程序性能的技巧——第1部分
    如何用 React Native 创建一个iOS APP?(二)
    如何与 DevOps 为伍?
    通过 DevOps 整合开发和应用安全管道
    性能为王:选择模拟监控的10大理由!
    模拟监控和真实用户体验监测,选哪个?
    PHP 之 Laravel 框架安装及相关开源软件
  • 原文地址:https://www.cnblogs.com/zztt/p/4122352.html
Copyright © 2011-2022 走看看