Posted in Javascript onOctober 09, 2011
前几天看到一个面试题,题目是这样的:
请你说说对javascript中apply,call,bind的理解?
首先apply和call是老生常谈的东西,但是对于bind,我愣了下,因为这个词是jquery中使用频率很高的一个方法,用来给DOM元素绑定事件用的。
为了搞清这个陌生又熟悉的bind,google一下,发现javascript1.8.5版本中原生实现了此方法,目前IE9+,ff4+,chrome7+支持此方法,opera和safari不支持(MDN上的说明)。
bind的作用和apply,call类似都是改变函数的execute context,也就是runtime时this关键字的指向。但是使用方法略有不同。一个函数进行bind后可稍后执行。
例子如下:
var person = { name: 'Andrew', job: 'web front end developer', gender: 'male', sayHello: function() { return 'Hi, I am ' + this.name + ', a ' + this.job; } } console.log(person.sayHello()); // Hi, I am Andrew, a web front end developer var anotherGuySayHello = person.sayHello.bind({ name:'Alex', job: 'back end C# developer' }); console.log(anotherGuySayHello()); // Hi, I am Alex, a back end C# developer
另外带有参数的例子:
function add(arg1, arg2, arg3, arg4) { return arg1 + ' ' + arg2 + ' ' + arg3 + ' ' + arg4; } var addMore = add.bind({}, 'a', 'b'); console.log(addMore('c', 'd')); // a b c d
如果你的浏览器暂时不支持此方法,但你又觉得这个很cool,想用,MDN上也给出参考实现, 这个实现很有意思,代码如下:
if(!Function.prototype.bind) { Function.prototype.bind = function(oThis) { if(typeof this !== 'function') { throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); } var fSlice = Array.prototype.slice, aArgs = fSlice.call(arguments, 1), fToBind = this, fNOP = function() {}, fBound = function() { return fToBind.apply(this instanceof fNOP ? this : oThis || window, aArgs.concat(fSlice.call(arguments))); }; fNOP.prototype = this.prototype; fBound.prototype = new fNOP(); return fBound; }; }
最后几行代码,通过prototype chain的方式,其中fBound是调用bind函数的子类,为什么这么实现,可以仔细看 fBound = function(){ return ... }这一部分,其中this是运行时决定的,这里主要考虑到如果用new的方式来调用函数(构造函数方式)的情况。
下面的例子,就能很好的说明这点,为了方便说明,此例子直接来自MDN:
function Point(x,y) { this.x = x; this.y = y; } Point.prototype.toString = function() { return this.x + ',' + this.y; }; var p = new Point(1, 2); p.toString(); // 1,2 var emptyObj = {}; var YAxisPoint = Point.bind(emptyObj, 0); var axisPoint = new YAxisPoint(5); axisPoint.toString(); // 0, 5 axisPoint instanceof Point; // true axisPoint instanceof YAxisPoint; // true
最后给出文章链接,方便您进一步了解
MDN: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
- MSDN: http://msdn.microsoft.com/en-us/library/ff841995%28v=vs.94%29.aspx
javascript之bind使用介绍
声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
Reply on: @reply_date@
@reply_contents@