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
浙公网安备 33010602011771号