The more hard you work The more luck you get
var socpe = "global";
function t(){
console.log(scope);
var scope = "local";
consloe.log(scope);
}
t();
(PS: console.log()是firebug提供的调试工具,很好用,有兴趣的童鞋可以用下,比浏览器+alert好用多了)
第一句输出的是: "undefined",而不是 "global"
第二讲输出的是:"local"
你可能会认为第一句会输出:"global",因为代码还没执行var scope="local",所以肯定会输出“global"。
我说这想法完全没错,只不过用错了对象。我们首先要区分Javascript的函数作用域与我们熟知的C/C++等的块级作用域。
在C/C++中,花括号内中的每一段代码都具有各自的作用域,而且变量在声明它们的代码段之外是不可见的。而Javascript压根没有块级作用域,而是函数作用域.
所谓函数作用域就是说:-》变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。
所以可以将上面的代码写成:
var scope = "global";
function t(){
var scope;
console.log(scope);
scope = "local';
console.log(scope);
}
t();
var name = "global";
if(true){
var name = "local";
console.log(name)
}
console.log(name);
都输出是“local",如果有块级作用域,明显if语句将创建局部变量name,并不会修改全局name,可是没有这样,所以Js没有块级作用域。
现在很好理解为什么会得出那样的结果了。scope声明覆盖了全局的scope,但是还没有赋值,所以输出:”undefined“。
所以下面的代码也就很好理解了。
function t(flag){
if(flag) {
var s = "ifscope";
for(var i = 0; i < 2;i++);
}
console.log(i);
consloe.log(s);
}
t(true);
变量作用域
function t(flag){
if(flag) {
s = "ifscope";
for(var i = 0; i < 2;i++);
}
console.log(i);
}
t(true);
console.log(s);// ifscope.
因为s 是全局变量而且还是订车对象的属性 所以 console.log(window.s);
当使用var声明一个变量时,创建的这个属性是不可配置的,也就是说无法通过delete运算符删除
var name=1 ->不可删除
sex=”girl“ ->可删除
this.age=22 ->可删除
作用域链
name = "long";
function t(){
var name = "tlong";
function s(){
var name = "slong";
console.log(name);
}
function ss(){
console.log(name);
}
s();//slong
ss();//tlong
}
t();
当执行s时,将创建函数s的执行环境(调用对象),并将该对象置于链表开头,然后将函数t的调用对象链接在之后,最后是全局对象。然后从链表开头寻找变量name,很明显
name是"slong"。但执行ss()时,作用域链是: ss()->t()->window,所以name是”tlong"
再看看下面的这个