zoukankan      html  css  js  c++  java
  • 解析Function.prototype.bind

    简介

    对于一个给定的函数,创造一个绑定对象的新函数,这个函数和之前的函数功能一样,this值是它的第一个参数,其它参数,作为新的函数的给定参数。

    bind的作用

    bind最直接的作用就是改变this的指向

    // 定义函数
     var checkNumericRange = function (value) {
         if (typeof value !== 'number')
             return false;
         else
             return value >= this.minimum && value <= this.maximum;
     }
     
     // 定义对象
     var range = { minimum: 10, maximum: 20 };

    这时就会碰到一个问题,因为作用域不符,checkNumricRange不能操作range对象的属性。

    那我们该如何做呢?

    答案是修改this的值。把函数内部的this修改为range对象,这样这个函数就可以访问range的属性。

    通过bind可以很好的实现。

     // 限定函数的this值为range,返回一个新的函数
     var boundCheckNumericRange = checkNumericRange.bind(range);
     
     // 使用新生成的函数。
     var result = boundCheckNumericRange (12);
     document.write(result);//  true

    让我们分析分析checkNumricRange.bind(range)都做了什么?

    通过bind方法,将this的值修改为range对象,返回一个新函数,这个函数this值是range,但函数的功能没有改变。

    Function.prototype.bind原理解析

    内部原理有一点点绕人,

    下面给出一个简化的bind代码,

    Function.prototype.bind = function (scope) {
        var fn = this;//这里fn为this,也就是调用bind的函数,方便下面调用
        return function () {//返回的是一个可以运行函数
            return fn.apply(scope);//利用apply方法,使用scope对象调用fn,
        };
    }    

    一个简单的测试用例

    var foo = {
        x: 3
    }
     
    var bar = function(){
        console.log(this.x);
    }
     
    bar(); // undefined
     
    var boundFunc = bar.bind(foo);
     
    boundFunc(); // 3

     具体适用情况

    1.在事件监听时,简化在触发事件时用匿名函数的情况

    这是一个用来处理和保存数据的计数器

    var logger = {
        x: 0,       
        updateCount: function(){this.x++;
            console.log(this.x);
        }
    }

    一般经常使用以下情况去运行方法updateCount,

    添加一个匿名函数,然后用logger对象调用方法updateCount,以保证updateCount里可以通过this访问logger.

    document.getElementsByTagName("button")[0].addEventListener("click",function(){
        logger.updateCount();
    })

    但是现在我们可以是用bind简化这个内容。

    document.getElementsByTagName("button")[0].addEventListener("click",logger.updateCount.bind(logger))
  • 相关阅读:
    [转]进程与线程及其区别
    [转]工厂模式
    [转]Filter实现处理中文乱码,转义html标签,过滤敏感词
    [转]JAVA设计模式之单例模式
    [转]Servlet 中文乱码问题及解决方案剖析
    Servlet作业2-将表单提交的商品信息输出到页面中
    Servlet作业1-实现注册登录
    [转] ServletContext 与application的异同
    [转]servlet中的service, doGet, doPost方法的区别和联系
    [转]Servlet 3.0 新特性详解
  • 原文地址:https://www.cnblogs.com/winderby/p/4050432.html
Copyright © 2011-2022 走看看