JavaScript:call,apply,bind的用法
2015-09-17 14:20
796 查看
var jane = { name: 'Jane', sayHelloTo: function (otherName) { 'use strict'; console.log(this.name+' says hello to '+otherName); } };
Function.prototype.call(thisValue, arg1?, arg2?, …)
第一个参数将被指向被调用函数的this值,其它的参数讲是调用函数所需要用到的。下面三种调用所得到的结果是一样的
jane.sayHelloTo('Tarzan'); jane.sayHelloTo.call(jane, 'Tarzan'); var func = jane.sayHelloTo; func.call(jane, 'Tarzan');
对于第二种方法,还需要把jane传入,因为call()并不知道你调用的是哪个对象。
Function.prototype.apply(thisValue, argArray)
其实,apply()与call()总体是一样的,只不apply()的第二个参数是以数组的形式传入。jane.sayHelloTo('Tarzan'); jane.sayHelloTo.apply(jane, ['Tarzan']); var func = jane.sayHelloTo; func.apply(jane, ['Tarzan']);
Function.prototype.bind(thisValue, arg1?, …, argN?)
通过调用bind()方法,产生了一个新的函数,thisValue将赋值给新函数的this,参数从arg1到argN。function func() { console.log('this: '+this); console.log('arguments: '+Array.prototype.slice.call(arguments)); } var bound = func.bind('abc', 1, 2); > bound(3) this: abc arguments: 1,2,3
下面三种方法调用产生的结果是一样的。
jane.sayHelloTo('Tarzan'); var func1 = jane.sayHelloTo.bind(jane); func1('Tarzan'); var func2 = jane.sayHelloTo.bind(jane, 'Tarzan'); func2();
可以看出,call()和apply()调用之后,立即执行了, 调用bind()并没有立即执行,因为调用它产生了一个新的函数,得去调用这个新的函数,才能执行。
apply() for Constructors
现在有一个数组,选出数组中最大的值。var array = [10,5,6,12];
当然,有很多方法可以实现。
现在通过Math.max()实现,下面的用法肯定很熟悉啦。
> Math.max(10,5,6,12) 12
对于函数而言,我们可以通过apply达到上面的效果。
> Math.max.apply(null,array) 12
apply仅仅在对函数或方法调用有作用
在构造器上调用apply()
这里以new Date()为例第一步:
给Data传递参数
new (Date.bind(null,2015,9.17))
第二步:
因为bind()是一个方法,所以我们可以对它apply().使用apply()给bind()传递一个数组。
new (Function.prototype.bind.apply( Date, [null, 2011, 11, 24]))
稍作修改:
var arr = [2011, 11, 24]; new (Function.prototype.bind.apply( Date, [null].concat(arr)))
做个简单的封装:
if (!Function.prototype.construct) { Function.prototype.construct = function(argArray) { if (! Array.isArray(argArray)) { throw new TypeError("Argument must be an array"); } var constr = this; var nullaryFunc = Function.prototype.bind.apply( constr, [null].concat(argArray)); return new nullaryFunc(); }; }
用法:
> Date.construct([2015,9,17]) Sat Oct 17 2015 00:00:00 GMT+0800 (中国标准时间)
抽离一个方法时this的指向
何谓抽离一个方法?就是将一个对象中的某个方法单独提取出来赋值给一个变量,这个变量又是一个函数了。比如:
var counter = { count: 0, inc: function () { this.count++; } }
将inc提取出来:
> var func = counter.inc; > func() //undefined > counter.inc // didn’t work 0
这是为什么呢?
在执行counter.inc操作时,this已经指向了全局对象,相当于进行了window.count++操作。因为window.count不存在,那也就是undefined,对它进行++操作,得到的结果就是NaN了。
再严格模式下,它就会报错。
> counter.inc = function () { 'use strict'; this.count++ }; > var func2 = counter.inc; > func2() TypeError: Cannot read property 'count' of undefined
在严格模式下,this的值是undefined。
正确的抽离一个方法
那就是运用bind()了。> var func3 = counter.inc.bind(counter); > func3() > counter.count // it worked! 1
相关文章推荐
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
- Win10/UWP开发—使用Cortana语音指令启动前台App
- Android 用EditText加一个ImageButton自定义一个带clear的搜索框
- Swift - 按钮(UIButton)的用法
- 我的Android进阶之旅------>Android使用百度地图时,关于android.permission.BAIDU_LOCATION_SERVICE的声明警告。
- Android 三次贝塞尔曲线练习之弹性的圆
- iOS开发学习资源
- 【图片裁剪】移动端一些处理措施
- Android 图片压缩(建议采用下面的方式而不是compress)
- 【分享】零基础学习iOS开发的学习方法总结
- 调研Android Studio开发环境的发展演变(附安装教程,多图)
- iOS学习总结----核心动画(2)
- Android中wp promote为sp流程
- Android多线程任务优化1:探讨AsyncTask的缺陷
- iOS基础知识
- 关于安卓开发选择android 4.2.2(API 17)应用无法打开的解决办法
- iOS学习总结----核心动画
- 【Android】Log优雅的注释(github开源项目)
- Android 动态创建Drawable selector
- Unity游戏开发—休闲类(有源代码)