JavaScript 中apply()、call()和bind()方法的使用

apply()和call()
我们可以将call()和apply()看做是某个对象的方法,通过调用此方法来简介调用函数。
call()和apply()两个方法实际上差别不大,只是在方法的第二个参数类别上有区别,call()第二个参数为一系列参数,而apply()第二个参数为一个数组,即如下所示。

f.call(obj,1,2,...); f.apply(obj,[1,2,...]);

这是这两个方法的参数区别,他们第一个参数调用上下文实参,估计很多朋友都不理解上下文实参是个啥,其实这也是我看的书上这么说的,我的理解就是传入一个对象,这个对象决定了此方法使用时候的上下文。
下面介绍几个例子来说明:
function Person(name, age) { this.name = name; this.age = age; } Person.prototype.showName = function() { console.log('Person showName -' + this.name); }; Person.prototype.setName = function(name) { this.name = name; console.log('setName-' + name); }; Person.prototype.showAge = function() { console.log('Person showAge - ' + this.age) }; function Women(name,age) { Person.call(this,[name,age]); //this Women对象调用Person中所有方法 this.sex = 'male'; } Women.prototype = Person.prototype; Women.prototype.showSex = function() { console.log('Women showSex-' + this.sex) }; Women.prototype.showName = function() { console.log('Women showName - ' + this.name); }; var women = new Women('cyl', 22); women.showName(); women.showSex(); women.setName('sf'); //此处更改this.name调用了Person.setName()的方法 women.showName(); //Women showName - cyl,22 //Women showSex-male //setName-aaa //Women showName - sf

//将对象o中名为m()的方法替换为另一个方法 //可以在调用原始的方法之前和之后记录日志消息 function trace(o, m){ var original = 0[m]; //在闭包中保存原始方法 o[m] = function(){//定义新的方法 console.log(new Date(), "Entering:", m); //输出日志信息 var result = original.apply(this, arguments); //调用原始函数 console.log(new Date(), "Exiting:", m); return result; }; }

trance()函数接收两个参数,一个对象和一个方法名,它将指定的方法替换为一个新方法,这个新方法是“包裹”原始方法的另一个泛函数。这种动态修改已有方法的做法有时候也成为“monkey-patching”。
bind()方法
这个方法的主要作用就是将函数绑定到某个对象上,一个函数调用bind()方法将返回一个新的函数。举个例子吧:
function f(y){return this.x + y; }//这个是待绑定的函数 var o = {x: 1}; //将要绑定的对象 var g = f.bind(o); //通过调用g(x) 来调用 o.f(x) g(2); // => 3

可以通过如下代码轻易实现这种绑定:
//返回一个函数,通过调用它来调用o中的方法f() //传递它所有实参 function bind(f, o){ if(f.bind) return f.bind(o); //如果bind方法存在的话使用bind方法 else return function(){ return f.apply(o,arguments); } }

【JavaScript 中apply()、call()和bind()方法的使用】当然bind()方法不仅仅是将函数绑定值一个对象,它还附带一些其他的应用:除了第一个实参之外,传入bind()的实参也会绑定值this,之歌附带的应用是一种常见的函数式编程技术,有时也被成为“柯里化(currying)”。参考下面的例子中的方法的实现:
var sum = function(x, y) { //返回两个实参的和值 return x+y; } //创建一个类似sum的新函数,但是this的值绑定到null //并且第一个参数绑定到1, 这个心的函数期望只传入一个实参 var succ = sum.bind(null, 1); succ(2)//=>3x 绑定到 1, 传入2作为实参function f(y, z) { return this.x + y+ z; } var g = f.bind({x:1},2); g(3) //=>6this.x 绑定到{x:1}.x =1y绑定到2, z传入3作为实参

    推荐阅读