zoukankan      html  css  js  c++  java
  • JS明确指定函数的接受者

    由于方法和值为对象的属性值没什么区别,因此很容易提取对象的方法作为回调函数直接传递给高阶函数。但这也很容易忘记应明确指定方法的接受者。例如,一个字符串缓冲对象使用数组来存储字符串。

    var buffer = {
        entries: [],
        add: function(args) {
            this.entries.push(args);
        },
        concat: function() {
            return this.entries.join('');
        }
    };
    
    var arr = ['alert', '-', '123'];
    // error: entries is undefined
    arr.forEach(buffer.add);
    buffer.concat();
    

    方法的接受者取决于它是如何被调用的。forEach方法的实现使用全局对象作为默认的接受者。由于全局对象没有entries属性,因此这段代码抛出了一个错误。

    在回调函数中执行方法

    var arr = ['alert', '-', '123'];
    arr.forEach(function() {
        buffer.add(arr);
    });
    buffer.concat();
    

    该方法创建一个显示地以buffer对象方法的方式调用add()。

    使用bind()返回一个指定接受者的函数

    创建一个函数用来实现绑定其接受者到一个指定对象是常见的。

    arr = ['alert', '-', '123'];
    arr.forEach(buffer.add.bind(buffer));
    buffer.concat();
    

    注意,bind()返回的是一个新的函数而不是修改buffer.add函数。这意味着bind方法是安全的。

    其实forEach()允许调用者提供一个可选的参数作为回调函数的接受者。arr.forEach(buffer.add, buffer)。

    兼容没有实现bind()方法的浏览器

    if (!Function.prototype.bind) {
      Function.prototype.bind = function (oThis) {
        if (typeof this !== "function") {
          // closest thing possible to the ECMAScript 5
          // internal IsCallable function
          throw new TypeError("Function.prototype.bind - 
               what is trying to be bound is not callable");
        }
    
        var aArgs = Array.prototype.slice.call(arguments, 1), 
            fToBind = this, 
            fNOP = function () {},
            fBound = function () {
              return fToBind.apply(this instanceof fNOP && oThis
                     ? this
                     : oThis,
                     aArgs.concat(Array.prototype.slice.call(arguments)));
            };
    
        fNOP.prototype = this.prototype;
        fBound.prototype = new fNOP();
    
        return fBound;
      };
    }
    

    更新 2014/11/07

    简化如下代码

    Function.prototype.bind = function (oThis) {
      var self = this
        , args = [].slice.call(arguments, 1)
        ;
      return function() {
        return self.apply(oThis, args.concat([].slice.call(arguments)));
      };
    };
    
  • 相关阅读:
    registration system(map+思维)
    Codeforces 158B:Taxi(贪心)
    牛客小白月赛24 B-组队(二分)
    CF58C Trees(逆向思维)
    lower_bound和upper_bound学习笔记
    POJ--2689Prime Distance(区间素数筛)
    Codeforces Round #635 (Div. 2)
    navicat premium安装,使用
    Oracel 之PL/SQL Developer使用
    PLSQL,sql语句中带有中文的查询条件查询不到数据
  • 原文地址:https://www.cnblogs.com/mackxu/p/bind-polyfill.html
Copyright © 2011-2022 走看看