this
javascript中this总是指向一个对象,this对象是根据执行环境决定的.
当函数被作为某个对象的方法调用的时候,this指向该对象。当函数不作为对象的属性被调用时,即作为普通函数,此时this指向全局对象,即window对象。
此外匿名函数的执行环境具有全局性。
window.name = 'window';
var Person = {
name : 'zll',
age : 20,
getA : function(){
return this.name;
},
getB : function(){
return function(){
return this.name;
};
}
};
alert( Person.getA() ); //作为Person对象的方法调用,此时this指向Person,输出 zll
alert( Person.getB() ); //getB中返回一个匿名函数,这时this指向Window,输出 window
var getA = Person.getA;
alert( getA() ); //此时不作为对象的方法,this指向window,输出 window
此外还有
构造器调用
javascript中没有类,大部分的函数可以作为构造器使用,构造器和函数的区别在于被调用的方式。使用new操作符时函数才会作为构造器使用。
var test = function(){
this.name = 'zll';
};
var obj = new test();
alert( obj.name ); //输出 zll
但是构造器存在一个问题:当构造器
显示的返回一个object对象时,则结果会返回这个对象。
var test = function(){
this.name = 'zll';
this.age = 20;
return {
age : 19
};
};
var obj = new test();
alert( obj.age );
此处做了个测试,如果是alert(obj.age ),则输出19,如果alert(obj.name),则会输出
undefined。
如果返回的不是object类型,比如return 'aaaa';或者return 10;则会正常返回所需值;
call和apply
ECMAScript给function的原型定义了Function的原型定义了两个方法:Function.prototype.call和function.prototype.apply。
apply接受2个参数,(函数体内this指向的对象,带下标的集合),这个集合可以是数组也可以是类数组。
call传入的参数大于等于2,第一个参数相同(this指向的对象),第二个开始是每个参数依次传入 。必须明确的传入每一个参数
var func = function( a,b,c ){
alert( [a,b,c] );
};
func.apply(null,[1,2,3]);
func.call( null, 1, 2, 3 );
call和apply的用途是,改变this指向,扩展作用域
var obj1 ={
name : 'zll'
};
var obj2 ={
name : 'lily'
};
window.name = 'window';
var getName = function(){
alert( this.name );
};
getName(); //输出window
getName.call(this); //输出window
getName.call( obj1 ); //this指向obj1,输出zll
getName.call( obj2 ); //this指向obj2,输出lily
用于修正this的指向
<div id = "div"></div>
<script type="text/javascript">
document.getElementById = (function( func ){
return function(){
return func.apply( document , arguments );
};
})( document.getElementById );
var getId = document.getElementById;
var div = getId( 'div' );
alert( div.id );
</script>
这里引用《javascript设计模式与开发实践》的代码。
如果将return的apply方法去掉,浏览器将会弹出undefined。
arguments代表的是函数的参数列表,可以看作是一个数组但并非是数组,但是具有下标和length属性,比如function(a,b,c){}。则对应的arguments就是[a,b,c],arguments.length=3,arguments[0]=a;
ECMA5定义了一个方法bind()。这个方法会创建一个函数实例,其this值会绑定到传给bind函数的值。
window.name = 'window';
var obj={
name : 'lily'
};
function getName(){
alert(this.name);
}
var objName = getName.bind( obj );//创建一个函数实例,其this值指向obj。
getName(); //输出window
objName(); //输出lily