this是面向对象语言中的一个重要概念,在JAVA,C#等大型语言 中,this固定指向运行时的当前对象。但是在javascript中,由于 javascript的动态性(解释执行,当然也有简单的预编译过程),this的指向在运行时才确定。这个特性在给我们带来迷惑的同时也带来了编程上的 自由和灵活。
下面介绍一些this的常见用法:
1、 this默认指向window
alert(this); //this默认指向window
this.n=20; //对window设置属性并赋值
alert(window.n); //显示window的属性n的值,结果为20
看另外一个有趣的示例:
<script language="javascript" type="text/javascript">
function test1(){
alert(this);//[object Window]
alert(window.n);//26
alert(this.m);//hello
}
var n=26;
var m="hello";
test1();
</script>
运行后window.n=26,this.m="hello";看起来似乎有点奇怪,怎么会 这样呢?原因是JavaScript变量作用域问题,在JavaScript的变量作用域里有一条规则“全局变量都是window对象的属性”。
2、直接在HTML元素中注册事件,this可以当作参数并指向元素本身
<input type="button" οnclick="show(this)" value="点击测试" /> <!--this指向input-->
<script language="javascript" type="text/javascript">
function show(obj){
alert("value="+obj.value); //实参this传递给形参 obj,obj指向input,obj.value="点击测试"
}
</script>
针对上面内容,如果this不做为参数时,this指向不会改变
<input type="button" οnclick="show()" value="点击测试" />
<script language="javascript" type="text/javascript">
function show(){
alert(this.value); //此时this指向window,输 出:undefined
}
</script>
3、采用dom方式注册事件
<input type="button" value="点击测试" />
var d=document.getElementsByTagName("input")[0]; //d指向第一个input
d.οnclick=show; //把d的单击事件绑定show函数
function show(){
alert("value="+this.value);} //此时this指向d
代码还可以写成下面的形 式,两种写法结果是一样的:
<input type="button" value="点击测试" />
var d=document.getElementsByTagName("input")[0]; //d指向第一个input
d.οnclick=function(){alert("value="+this.value); }/*此时this指向d*/
4、JavaScript 模拟面向对象,将function变成类(class),类中的this指向类的实例
function person(){ // 定义类
this.name="John"; //类的name属性
this.age=26; //age属性
this.sex="male";
this.say=function(content){alert(content)} // 类的方法
}
var Smith=new person(); //初始化类
alert(Smith.sex); //初始化以后,person()中的this指向实例 Smith;输出:male
Smith.say("hello"); //调用方法;输出:hello
运用Prototype添加方法
function person(){
var name='John';
this.age='26';
}
person.prototype.say=function(){
alert(this.name+", "+this.age); //会显示name为 undefined
}
var Smith=new person();
Smith.say();
------------------------------------- 给属性赋值--------------------------------------
function person(){
var name='John';
this.age='26';
}
person.prototype.say=function(){
alert(this.name+", "+this.age);//Smith,26
}
var Smith=new person();
Smith.name="Smith"; //给Smith添加name属性
Smith.say();
5、为脚本引擎内部对象添 加原形方法中的this关键字
Function.prototype.GetFunctionName=function(){
var fnName = this.toString(); //this跟上面的类 似,指向实例
fnName = fnName.substr(0, fnName.indexOf('(')); //截取"("前面部分;
fnName = fnName.replace(/^function/, ''); // 替换function字符串;
return fnName.replace(/(^/s+)|(/s+$)/g, '');//去处前后空字符;
}
function test(){}
alert(test.GetFunctionName());//test
6、下面引用一个网上的例子,变量作用域与this关键字
function OuterFoo(){
this.Name = 'Outer Name';
function InnerFoo(){
var Name = 'Inner Name';
alert(Name + ', ' + this.Name); //此 this.Name='Outer Name'
}
return InnerFoo;
}
OuterFoo()();
运行结果显示是:"Inner Name, Outer Name"。这里的结果如果是"Inner Name, undefined"似乎更合理些吧?但是正确的结果确实是前者,这是由于JavaScript变量作用域的问题决定的。JavaScript的作用域包 含关系在定义的时候确定,后面不论怎么调用,作用域不会变化,InnerFoo函数执行时,自身找不到this.Name,会向上层作用域查找,在 OuterFoo中找到this.Name,调用该变量,故输出结果为:"Inner Name,Outer Name"。