Function.prototype.bind、call与apply方法简介
来源:互联网 发布:商品期货软件 编辑:程序博客网 时间:2024/06/05 04:35
前言
前段时间面试遇见一题,题目内容大概是
function Parent() { this.prop = 'parent';}Parent.prototype.get = function() { alert(this.prop);};Parent.prototype.show = function() { setTimeout(this.get, 100);};var child = new Parent();child.show(); // ?
分析
上述题目考察的是this的指向性这个经典问题。
众所周知,setTimeout是window对象的一个属性,主要起到延迟给定函数执行的作用。setTimeout(fn, delay)
,因此this.get的这个this指向的是window对象,但是我们并没用在window对象上定义相应的get函数,所以会报错,而不是调用构造函数Parent的原型中的get方法。
怎么改?
经过上面的分析,我们知道setTimeout(this.get, 100)
会报错,但是如果我们想正常调用并且alert出正确的值,应该怎么改?
改动的原理很明确,就是将setTimeout中的this指向Parent.prototype,但是单纯的将this.get改成Parent.prototype.get仍然没有alert出真正的parent,而是undefined,原理仍然是原型中的get方法在通过实例对象child调用时内部的this仍然指向window对象。所以我们只能换种思路解决了
ps: 这个当时卡壳了,没答上来,汗。。。
思路1
Parent.prototype.show = function (){ var that = this; setTimeout(this.get.call(that), 100);}
这种方法在很多框架中经常使用,即先存储this默认指向的作用域,然后改变函数内部绑定的作用域来实现。ps: 不通过that存储,直接传递this也可
思路2
ES5中对函数方面唯一扩展是新增了一个bind函数,用于劫持函数作用域,并预先添加更多参数,然后返回绑定了新作用域的函数。而现在我们也可以使用它,其实这个思路在MDN上有相应的介绍使用,哎,只怪自己的年少无知。。。
Parent.prototype.show = function() { setTimeout(this.get.bind(this), 100);};
bind/call/apply
三者都是用于绑定函数作用域,区别如下:
- call 是obj.method()到method(obj)的变换,返回函数调用结果,所需参数依次用逗号分割添加至obj尾部。
- apply 功能同call,区别是传递参数的方式不是call的那种参数列表形式,而是以数组或类数组形式传递。
- bind 返回绑定作用域后的一个新函数,不会执行函数
我们可以通过apply方法实现bind函数:
if(!function() {}.bind) { Function.prototype.bind = function(context) { if (arguments.length < 2 && context == void 0) return this; var _self = this, args = [].slice.call(arguments, 1); return function() { _self.apply(context, args.concat.apply(args, arguments)); } }}
另外,我们可以利用bind修复IE事件绑定attachEvent回调中的this问题,它总是指向window对象,而标准浏览器的addEventListener中的this则为其调用对象。
function(el, type, fn) { el.attachEvent('on' + type, fn.bind(el, event));}
- Function.prototype.bind、call与apply方法简介
- as3.0 Function.apply()与Function.call()方法简介
- apply, call与bind方法
- js function call,apply,bind方法
- JavaScript里call,apply,bind方法简介
- JavaScript中的Function.prototype.bind()方法简介
- call,apply与bind方法的区别
- call apply 与 bind
- call()、apply()与bind()
- Function.prototype.bind() ,Function.prototype.call() and function.prototype.apple()
- Function.prototype.call.apply结合用法
- JS Function.prototype.apply()和call()
- Function.prototype.apply.call 待解答原理???
- 浅谈 call apply 与 bind
- javascript中call apply 与 bind方法详解
- Javascript中call,apply,bind方法的详解与总结
- 谈谈javascript的Function中那些隐藏的属性/方法:caller/callee/apply/call/bind
- prototype.js之bind及js apply call用法
- 线程同步与死锁
- 采用队列实现自底向上链表归并排序
- scala学习之:List的foldLeft、foldRight操作实战
- Javascript模块化编程:require.js的用法
- Python Web 实战 - 搭建Django环境和初步使用
- Function.prototype.bind、call与apply方法简介
- 【Unity3D Game develop by example】简单的例子—平板接掉落球
- JSBadgeView的使用
- vm10虚拟机安装Mac OS X10.10教程
- [组合数]求组合数的几种方法总结
- python对文件的读取操作方式比较
- Linux--hostname配置
- postgresql 9.4.4 安装
- 机房重构VB.Net版进行中