理解prototype.js的bind函数

来源:互联网 发布:网络监管员是做什么的 编辑:程序博客网 时间:2024/04/30 11:15

http://muyu.iteye.com/blog/423917

先看call(或apply)的用处:

Js代码  收藏代码
  1. var first_object = {  
  2.   num: 42  
  3. };   
  4. function multiply(mult) {  
  5.   return this.num * mult;  
  6. }  
  7.    
  8. multiply.apply(first_object, [5]);  //等于 42*5  

 

在上面的例子中,multiply是一个function,里面有this,所以,它必须“成为某个对象的方法才能执行”。这里的multiply函数中的this默认为全局的window对象:

Js代码  收藏代码
  1. function multiply(mult) {  
  2.   return this.num * mult;  
  3. }  
  4.    
  5. window.num = 100;  
  6. multiply(4); //等于 400  

 

 

由于JavaScript是动态语言,一个对象的方法可以被变成另外的对象的方法,所以,该方法下的this会发生变化。

Js代码  收藏代码
  1. function multiply(mult) {  
  2.   return this.num * mult;  
  3. }  
  4.    
  5. var book = {  
  6.   num : 33  
  7. };  
  8. book.total = multiply;  
  9. book.total(10);  

 

换种写法,采用new关键字

Js代码  收藏代码
  1. function multiply(mult) {  
  2.   return this.num * mult;  
  3. }  
  4.   
  5. function Book(newNum) {  
  6.   this.num = newNum;  
  7. }  
  8.    
  9. var book = new Book(33);  
  10. book.total = multiply;  
  11. book.total(10);  

 

再看看下面的写法,和平时写的类比较像了:

Js代码  收藏代码
  1. function Book(newNum) {  
  2.   this.num = newNum;  
  3.   this.total = function (mult) {  
  4.                  return this.num * mult;  
  5.                }  
  6. }  
  7.    
  8. var book = new Book(33);  
  9. book.total(10);  

 

正因为this指针的不确定性,使得this所属函数定义的 和 实际执行的 上下文环境不同,从而计算出非预期的结果。

 

再看最初的代码示例,我们用js提供的call函数来解决this的问题。可以考虑给function函数原型增加一个bind方法------它只是封装了apply函数,返回值是一个function:

Js代码  收藏代码
  1. var first_object = {  
  2.   num: 42  
  3. };   
  4. function multiply(mult) {  
  5.   return this.num * mult;  
  6. }  
  7.   
  8. Function.prototype.bind = function(obj) {  //该行可换做 multiply.prototype.bind = function(obj) {  
  9.   var method = this;  
  10.   return function() {  
  11.     return method.apply(obj, arguments);  
  12.   };  
  13. }  
  14.   
  15. var foo = multiply.bind(first_object);  
  16. foo(5);  

 (把bind方法建立在multiply的原型上也可,如注释所示)

 

总之,把正确的方法放在正确的对象里,才是bind方法的目的。请参看prototype.js关于bind方法的API:

http://www.prototypejs.org/api/function/bind

下面是prototype.js关于bind的源代码:

Js代码  收藏代码
  1. bind: function() {  
  2.   if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;  
  3.   var __method = this, args = $A(arguments), object = args.shift();  
  4.   return function() {  
  5.     return __method.apply(object, args.concat($A(arguments)));  
  6.   }  
  7. },  

  

参考网址

http://www.digital-web.com/articles/scope_in_javascript/


0 0
原创粉丝点击