js 碎片整理(变量声明,函数作用域)
1.变量声明: 在非严格模式下,函数可以对未声明的变量赋值,而这样赋值的结果就是该变量就会变成全局变量。
(function(){ var a = 1; })(); console.log(a) ;//1
上面的代码原意是在一个立即执行的匿名函数内声明一个函数内部变量,不过没有加 var js引擎默认为变量a赋值。所以现在函数内部查找变量名a,显然不存在便向上级作用域查找,此处的上级作用域是window,既全局作用域。全局作用域中也不存在a变量,便在全局中声明变量a,并赋值。
上图显示了加 var后的结果。
2.每个函数都有一个自己的作用域以及相应的作用域链。函数内查找一个变量会先从自己的作用域一级级往上查找变量。当找到为止。 如果一直查找到最上级window(全局作用域)都没有找到该变量,则会报ReferenceError的错误。
函数作用域的重点是this指针的指向。this指向函数调用的上下文。(即在哪个地方调用 谁调用了他)。函数声明时,this一般指向window对象(严格模式下this指向undefined)。但用某个对象调用他(obj.fun()),或者call()等方法改变他的上下文时,this才改变指向对应的上下文。
关于this的更多内容移步一峰大神的博客:http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html(this.4种情况)
情况一:存粹的函数调用
函数的最通常用法,属于全局性调用,此时this代表全局对象global。
下面是这种情况的代码
1 var x = 1; 2 function fun(){ 3 this.x = 2; 4 } 5 fun(); 6 console.log(x); // 2
显然这种情况下的this指向全局global
情况二:作为对象方法的调用
函数可以作为某个对象的方法,这个时候this就指向这个对象:
function test(){ console.log(this.a); } var a = 1; var o = {}; o.a = 2; o.b = test; o.b(); //2
情况三:作为构造函数调用
所谓构造函数,就是通过这个函数生成一个新对象(object)。这时,this就指这个新对象。
var x = 2; function test(){ this.x = 1; } var o = new test(); alert(o.x);//1 alert(x); //2
运行结果为2,表明全局变量x的值根本没变。
情况四:apply(call)调用
apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是这第一个参数。
var x = 0;
function test(){
alert(this.x);
}
var o={};
o.x = 1;
o.m = test;
o.m.apply(); //0
apply()的参数为空时,默认调用全局对象。因此,这时的运行结果为0,证明this指的是全局对象。
如果把最后一行代码修改为
o.m.apply(o); //1
运行结果就变成了1,证明了这时this代表的是对象o。