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

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)));
};
};

JS明确指定函数的接受者的更多相关文章

  1. js推断指定函数、变量是否存在的方法

    //推断是否存在指定函数 function isExitsFunction(funcName) { try { if (typeof (eval(funcName)) == "functio ...

  2. js 查找指定函数的内容

    function test(){  //hahahhahahhahahha }alert(test.toString());

  3. js 数组处理函数

    本文转载自有有<js 数组处理函数> concat 将参数列表连接到原数组后面形成一个新的数组并返回,原有数组不受影响. var arr = ["a","b& ...

  4. js使用split函数按照多个字符对字符串进行分割的方法

    这篇文章主要介绍了js使用split函数按照多个字符对字符串进行分割的方法,实例分析了split函数的使用技巧,非常具有实用价值,需要的朋友可以参考下   本文实例讲述了js使用split函数按照多个 ...

  5. JS中的函数,Array对象,for-in语句,with语句,自定义对象,Prototype

    一)函数 A)JS中的函数的定义格式: function add(a,b) { var sum = a+b; document.write("两个数的和是:" + sum); // ...

  6. 分享我常用的一些JS验证和函数

    下面是我常用一些JS验证和函数,有一些验证我直接写到了对象的属性里面了,可以直接通过对象.方法来调用//浮点数除法运算 function fdiv(a, b, n) { if (n == undefi ...

  7. 常用JS验证和函数

    下面是我常用一些JS验证和函数,有一些验证我直接写到了对象的属性里面了,可以直接通过对象.方法来调用 //浮点数除法运算 function fdiv(a, b, n) { if (n == undef ...

  8. js中的函数,Date对象,Math对象和数组对象

    函数就是完成某个功能的一组语句,js中的函数由关键字 function + 函数名 + 一组参数定义;函数在定义后可以被重复调用,通常将常用的功能写成一个函数,利用函数可以使代码的组织结构更多清晰. ...

  9. js原生之函数

    1.函数作为参数传给其他函数:    data.sort(function(a,b){return a-b})    //关于数组的sort函数,其回调函数返回负值,a在b之前    //正值,b在a ...

随机推荐

  1. 大数据计算平台Spark内核解读

    1.Spark介绍 Spark是起源于美国加州大学伯克利分校AMPLab的大数据计算平台,在2010年开源,目前是Apache软件基金会的顶级项目.随着 Spark在大数据计算领域的暂露头角,越来越多 ...

  2. Safari 快捷键

    标签和网页导航快捷键 8 个 切换到下一个标签页 – Control+Tab 切换到上一个标签页 – Control+Shift+Tab 向下滚动一屏 – 空格 向上滚动一屏 – Shift+空格 焦 ...

  3. [转载]50个Demo展示HTML5无穷的魅力

    Flash和HTML5的比较已经成为现在最热门的主题之一,我们不去争论哪个好哪个不好.和HTML5在很酷的动画和简单的游戏等方面一样,除非HTML5在未来几年有一些重大发展,否则Flash在富内容网页 ...

  4. 优化SqlServer--数据压缩

    数据压缩是对存储和性能优势的加强.减少数据库占用的磁盘空间量将减少整体数据文件存储空间,在一下几个方面增加吞吐量: 1.更好的I/O利用率,每个页面可以读写更多的数据. 2.更好的内存利用率,缓冲区可 ...

  5. Oracle安装前用户信息设置

    如果是重复安装,首先需要清除已经存在的软件安装记录: rm -fr /usr/local/bin/*oraenv rm -fr /usr/local/bin/dbhome rm -fr /usr/tm ...

  6. netbeans打包成jar

    文件页里找到build.xml文件,打开在</project>前 加入以下代码保存之 按 Ctrl+C 复制代码 <target name="package-for-sto ...

  7. vc6.0快捷键大全

                                                                转载! 按下Alt  键不放,点击鼠标左键拖动,可以选择文本块.可选择列:    ...

  8. C语言中链表怎么删除结点?

    第一个方法: /*根据姓名删除链表的中的学生记录*/ void deleteByName(struct STUDENT * head) { struct STUDENT *p,*q; ]; if(he ...

  9. Unity3d Asset Server启动问题

    周末机房停电后asset server无法启动,点击启动出现“asset server could not start server”. 几经周折,找到原来是用户问题,解决办法如下: 1.命令行输入“ ...

  10. mysql 性能优化方案 (转)

    网 上有不少mysql 性能优化方案,不过,mysql的优化同sql server相比,更为麻烦与复杂,同样的设置,在不同的环境下 ,由于内存,访问量,读写频率,数据差异等等情况,可能会出现不同的结果 ...