Javascript this相关笔记

初学JS,最让人不容易理解的两个概念都是和执行环境相关的,一个是this,另外就是闭包了。

this是JavaScript里面一个保留的关键字,指向当前执行对象。我以前也写过这样的代码:

var $=document.getElementById;
$('id');
//视乎不同JS引擎,抛出的错误代码不一样(IE较低的版本是不会报错的)
//如Chrome的报TypeError: Illegal invocation

为什么这样写不可以呢?答案和一个看不见的参数有关。

JavaScript所有变量、对象、方法,都是定义在其它对象里的。在浏览器环境下,最顶端的一个window对象。

而每次我们调用方法(函数)时,除了显式传入的形参以外,还隐式传入一个当前执行环境对象this。

在比较简单的情况,没有用到 this 对象时,上面那种简单命名是不会出现问题的,如:

var obj = { a: function( str ){
                            alert( str )
                       },
               }
var a = obj.a;
a( 'wow' );
//obj.a并没有和执行对象相关的代码,所以不会出错,正常弹出wow

 

当方法是依赖执行对象 this 的时候,情况就改变了,下面的例子不会报错,但尝试改别名后结果不一样:

var value = 888;//顶部window变量,相当于window.value
var obj = {
                 value:777,//内部对象
                 a: function(){
                                        alert( this.value )
                      },
              }

var b = obj.a;//尝试改一个别名

obj.a(); // 777
b(); // 888

 上面两个不同的结果,就是因为传入函数时的 this 指向不同,一个是指向 obj 对象,一个没有声明,指向的是顶层对象 window,结果自然也不同了。

 

至此,应该能明白最开始为什么尝试用一个别名定义 document.getElementById 报错了:因为 getElementById 方法只能在传入 this 参数指向 document 类的对象时,才能正常执行。

 

那么,除了定义新的顶层方法,如 $ = function ( sel ){ return document.getElementById( sel ); } 外,有没有方法改变传入的 this 对象呢? 答案是肯定的, call 和 apply 方法都可以指定 this 对象,如:

//续上例
b.apply( obj ) // 777
b.call( obj ) // 777

 call 和 apply是类似的,只是传入形参的表达方法不同。

 

对支持 JavaScript 1.8.5 标准的 JS 引擎,有一个新的方法,可以简单实现本文开头报错那段的效果, bind

bind 的用途就是指定一个方法的this对象,它不像 call 和 apply 那样在执行时才指定的,而是定义后总是把 this 指向同一个对象。

var $ = document.getElementById.bind(document);
$( 'id' );//正常返回结果

 bind的浏览器最低支持为:

             Firefox 4.0
             Chrome 7
             IE 9
             Opera 11.60
             Safari 5.1.4

 

Reference:
Bind - MDN
JavaScript alaising doesn't work

posted on 2012-08-28 17:42  dindog  阅读(224)  评论(0)    收藏  举报

导航