嵌套函数中的this指向的对象
我们通过一个测试来举出所有的情况,然后用自己的debug方法输出结果来判断嵌套时的this指向的对象是自己还是父对象
下面是这个测试的前提html和css代码,用来显示测试结果:

css和html代码
1
<style type="text/css">
2
.block{
}{
3
margin-top:5px;
4
padding:10px;
5
font-family:Verdana;
6
font-size:12px;
7
background-color:#e0ecf9;
8
width:90%;
9
overflow:hidden;
10
border:1px #4B8FE3 solid;
11
padding-left:4px;
12
}
13
</style>
14
<div id="debug1" class="block">
15
.
16
</div>
之后是一些增加的系统函数,用来更方便的实现某些测试功能:

基础代码
1
function $$(ele)
{
2
return document.getElementById(ele);
3
}
4
function adddebug(e1,e2)
{
5
$$("debug1").innerHTML+=e1+":"+e2+"<br />";
6
}
7
//用来显示当前对象的所有属性和方法,用来测试this所指的对象,以及输出所有的属性的值
8
Object.prototype.printToScreen=function(objname,ele)
{
9
div=document.createElement("div");
10
div.className="block";
11
div.innerHTML+="当前对象+"+objname+"<br />"+"<HR/>";
12
count=7;
13
for(i in this)
{
14
if(count==0)
{div.innerHTML+="此对象含有大量的属性,已经省略之";break;}
15
div.innerHTML+="<font color=#ff00ff>"+i+"</font>"+":"+"<font color=#0ff00d>"+this[i]+"</font>"+"<br />";
16
count--;
17
}
18
$$("debug1").appendChild(div);
19
}
为了测试在不同情况下嵌套函数(对象)中this所指的对象,我们写了如下的代码(在代码中已经标识出各种情况的分析结果):

测试代码
1
function testA()
{
2
this.name="a";
3
this.func1=function()
{
4
this.name1="a1";
5
this.name="b";
6
this.printToScreen("func1","debug1");
7
//这里的this指向了外部函数的this
8
}
9
this.func1();
10
11
12
function func2()
{
13
this.name1="b1";
14
this.name="c";
15
this.printToScreen("func2","debug1");
16
//这里的this不指向外部的this,而是自身环境的this
17
}
18
var func2=new func2();
19
20
21
var func3=function()
{
22
this.name1="b1";
23
this.name="c";
24
this.printToScreen("func3","debug1");
25
//这种方式也不影响外部的值,this指向自身的环境
26
}
27
func3();
28
29
this.a=function func4()
{
30
this.name1="b1";
31
this.name="c";
32
this.printToScreen("func4","debug1");
33
//这种方式也会影响外部的this,这里的this指向外部的this
34
}
35
this.a();
36
37
}
38
var testa=new testA();
39
this.name="aa";
40
this.func5=function()
{
41
this.printToScreen("func5","debug1");
42
}
45
this.func5();
总结:
javascript中的函数是顶级对象,每次创建一个函数的时候我们就会为其创建一个运行环境,这个环境中包含一个作用域链属性,它可以指向外部的对象来实现外部变量对于函数内部是可见的(具体在其他文章中讨论闭包的时候讨论),所以在javascript中函数是可以嵌套的,也就是说在定义了一个函数后,在函数内部仍然可以定义一个函数,而且外部函数内定义的变量在内部函数中是可见的(在php中则是不可见的),通过环境中的作用域链,内部函数在初始化的时候顺着作用域链可以找到其外部任何层级的函数(对象)中的变量.在完成一系列初始化工作后,将给当前的this赋值,this属性指向运行环境所指向的对象本身,所以在全局环境中我们也可以使用this关键字,这时它指向全局对象.
我们这里考虑的是javascript中this指针指向的对象,当在某个函数内嵌套一个函数的时候,有好几种方法,可以将内部函数直接复制给外部函数对象的一个属性,也可以单独创建一个函数.这些不同的方法中 在内部对象中使用this指针所指向的对象是不同的.通过上面的例子可以看到不同的情况下this所指向
上面的所有情况其实分为两大种:
第一种是在外部函数的内部直接定义一个对象,这个对象不作为外部对象的属性出现:
这种情况下内部函数中的this指向此内部函数,这是正常创建函数的方法,所以会为内部函数创建自己的运行环境,this指向这个运行环境
第二种情况是定义一个函数,然后赋给外部对象的一个属性.
这种情况下并不会给这个内部函数创建运行环境,而是以外部对象的运行环境作为当前的运行环境,所以这时候this指向的是外部的对象.
这是今天偶尔想到的一个问题,最近在从原理上分析javascript,但是有很多地方晦涩难懂,不过javascript的确是门很有意思的语言,至少以后可以在任何电脑上写代码了,只要一个浏览器,完成所有的工作^^^^^^再说,javascript的面向对象其实看起来简单,但是还是有很多内涵的,深入研究的话,还是很充实的.