一、bind
首先:
var alertWrite = document.write; alertWrite(‘who am I?‘);
这两行代码的运行结果是什么呢?不要急着回答,看完下面的内容再回答。
bind 的其中一个用法就是:绑定函数,使其无论怎么样调用都用相同的 this
看下面的例子:
var obj = { getThis: function() { console.log(this); } };
obj.getThis(); var getThisCopy = obj.getThis; getThisCopy();
运行结果如下:
通过上述例子我们会发现,虽然是 getThisCopy 是复制了 obj 的 getThis 方法,但是他们所属的对象却不一样。在对象里面,所有的 this 都指向对象本身,而在全局作用域定义的变量的 this 指向 Window。
所以,下面这段代码的运行结果,能猜的出来结果吗?
1 var obj = { 2 num: 100, 3 numFun: function() { 4 console.log(this.num); 5 } 6 }; 7 var numFunCopy = obj.numFun; 8 numFunCopy();
bind 的存在就是 为了解决 this 不能够指向原来的问题。
所以,试试这段代码:
1 var alertWrite = document.write; 2 alertWrite.bind(document)(‘hello‘);
4 var obj = { 5 getThis: function(){ 6 console.log(this); 7 } 8 } 9 var getThisCopy = obj.getThis; 10 getThisCopy.bind(obj)(); 11 12
13 var obj = { 14 num: 100, 15 numFun: function(){ 16 console.log(this.num); 17 } 18 } 19 var numFunCopy = obj.numFun; 20 numFunCopy.bind(obj)();
总结bind使用方法:
fun.bind(thisObj, 参数1, 参数2...)()
thisObj:this调用绑定函数时作为参数传给目标函数值,如果绑定函数时使用 new 运算符构造的,则该值将被忽略。
参数1,参数2...:在调用目标函数时加入提供给绑定函数的参数的参数
返回值:具有指定 this 值和初始参数的给定函数的副本
但是 bind 是 ES5 的内容,有一定的兼容性问题。
解决bind兼容性方案(1)
1 //解决IE10以下不支持Function.bind 2 if (!Function.prototype.bind) { 3 Function.prototype.bind = function(oThis) { 4 if (typeof this !== "function") { 5 throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); 6 } 7 var aArgs = Array.prototype.slice.call(arguments, 1), 8 fToBind = this, 9 fNOP = function() {}, 10 fBound = function() { 11 return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, 12 aArgs.concat(Array.prototype.slice.call(arguments))); 13 }; 14 fNOP.prototype = this.prototype; 15 fBound.prototype = new fNOP(); 16 return fBound; 17 }; 18 }
解决bind兼容性方案(2)
1 if (!function() {}.bind) { 2 Function.prototype.bind = function(context) { 3 var self = this 4 , args = Array.prototype.slice.call(arguments); 5 return function() { 6 return self.apply(context, args.slice(1)); 7 } 8 }; 9 }
二、call