嵌套的函数(作用域链)

当你进行函数的嵌套时,要注意实际上作用域链是发生变化的。

var testvar = 'window属性'; 
var o1 = {testvar:'1', fun:function(){alert('o1: '+this.testvar+'<<');}}; 
var o2 = {testvar:'2', fun:function(){alert('o2: '+this.testvar);}}; 
o1.fun();//o1:1<<
o2.fun();//o2:2
o1.fun.call(o2);//o1:2<<

这是本文的首个例子。

var testvar = 'window属性'; 
var o3 = { 
testvar:'3', 
testvar2:'3**', 
fun:function(){ 
alert('o3: '+this.testvar);//o3:3
var inner = function(){ 
alert('o3-inner: '+this.testvar);//'window属性' 
alert('o3-inner: '+this.testvar2);//undefined(未定义) 
}; 
inner(); 
} 
}; 
o3.fun(); 

这里我们换了别的函数,这个函数与原先的函数几乎相似但区别是内部函数的写法。要注意的是内部函数运行时所在的作用域,和外部函数的作用域是不一样的。

变量的声明
初始化变量时一定要加上“var”关键字,没有的话这就是一个全局变量。譬如,在下面的例子中,会有一个变量写在函数内部,然而你打算仅仅是声明局部的变量,但实际也可能出现覆盖全局变量的值的情形。在FIREBUG "DOM"的标签页中,你可通过检测“window”看到所有的全局变量。如果你发现有“k”或“x”变量那证明你把这个变量分配在一个不合适的作用域里面。见下例:

var i = 4; 
var j = 5; 
var k = 7; 
var fn = function(){ 
var i = 6; 
k = 8;//注意前面没有var 所以这句话的意思的把8赋予到变量k中去! 
alert(i);//6 
alert(j);//5 
alert(k+'-1');//8-1 
x = 1;//这句的作用有两种情况,创建全部变量x或覆盖(overwrite)全部变量x 
}; 
fn(); 
alert(k+'-2');//8-2 (注意不是7-2) 

与前面例子变化不大,另外注意的是函数内的k前面是没有var关键字的,所以这里不是声明局部变量,而是将某个值再次分配到k这个全局变量中。另外要注意的是,alert方法执行期间,参数i是当前能找到的局部变量,它的值是6,但参数j在当前作用域找不到,就沿着作用域链(scope chain)向上查找,一直找到全局变量的那个j为止。

调用函数时,你可以把this想象为每个函数内的一个特殊(躲起来的)参数。无论什么时候,JavaScript都会把this放到function内部。它是基于一种非常简单的思想:如果函数直接是某个对象的成员,那么this的值就是这个对象。如果函数不是某个对象的成员那么this的值便设为某种全局对象(常见有,浏览器中的window对象)。下面的内部函数可以清晰的看出这种思想。
一个函数,若是分配到某个变量的,即不属于任何对象下的一员,那么this的参数就变为windows对象。下面是一个例子,可直接粘贴到Firebug的console:

var obj = { 
    toString:function(){ return 'obj的范围内(作用域内)';}, //重写toString函数,方便执行console.log(this)时的输出 
    func: function(){ 
        // 这里的函数直接从属与对象"object" 
        console.log(this); 
        var innerFunc = function(){ 
            //n这里的函数不是特定对象的直接成员,只是另外一个函数的变量而已 
            console.log(this); 
        }; 
        innerFunc(); 
    } 
}; 
obj.func(); 
// 输出 "obj的范围内(作用域内)" 
// 输出 "Window的一些相关内容..." 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值