function test () { c=5; alert(c); } test();
当我们在执行test函数时,浏览器并不会报c未定义的错误,因为在js中,变量定义是通过var关键字,如果没有通过var定义,而直接进行引用,js引擎会自动把这个c定义为全局变量。
unction test () { c=5; alert(c); } test(); (function test2 () { alert(c) })();
所以test2函数也可以拿到这个c。
function test2 () { alert(c); console.log(c); var c=2; }
test2();
这个js引擎在编译时会先将c定义,但是不会给他赋值,赋值要在函数执行的时候,所以不会报c is not defined
但是c会赋值为undefined
今天参加了一场面试,面试过程中做了三道js的笔试题,题目只记得了大概了,不过也没关系。
var a=1; var obj={b:2} function fn(){} fn.c=6; function test(a,obj,fn){ a=3; obj.b=4; fn.c=5 } test(a,obj,fn) alert(a); alert(obj.b); alert(fn.c); alert(a+obj.b+fn.c);
大意就是这样吧!问最后alert(a+obj.b+fn.c);的值会是多少!大家不妨先自己分析分析。答案是10。a等于1,obj.b等于4,fn.c等于5。分析如下
首先基本类型的传递方式为按值传递,也就是说test(a,obj,fn),中的a是全局变量的一个拷贝,在这个test函数里面改变a的值是不会影响外面全局变量a的值的,所以全局变量a的值依然是1,而对象是按引用类型传递的,也就是test函数中的obj参数,传递的将是指向该对象的一个引用。(感觉就像c里面的指针,传递的是一个指向某个内存的地址指针,通过该指针来找到对应的内存地址,不知道这个比方打的正不正确)。那么我们在函数里面改变obj.b实际上是会改变全局变量中obj.b的值的,而fn.c也是一个道理,因为在js中函数也是对象。那么很自然就得到了10.建议大家去了解一下按值传递和按引用传递的相关内容,高程里面好像有。
还有一个题目
var name="djl"; function echo(){ alert(name); var name="eve";//就是变量的申明提前,但是只是执行了var name;但是此时是并没有给name赋值的,也就是说没有执行name="eve"; alert(name); alert(age); } echo();
因为学的如果不深入的话很肯能会得到 djl,eve,语法错误这样的答案。但实际上是undefined,eve,语法错误。因为我们知道在js中有变量申明提升的特性。
就比如
alert(a); var a;
我们会得到undefined,而不是js引擎报错 “Uncaught ReferenceError: a is not defined”。但是我们应该还要注意,变量申明确实提升了,但是却并不会执行赋值操作,也就是说我们在后面定义var a=1;js引擎提升的部分只有var a;在提升申明的过程中并不会执行a=1这个赋值操作。所以在上面var name="eve";只会提升申明,并不会在此时执行name="eve"的赋值操作,所alert的结果为undefined而不是eve也不是djl或者报错。
当然以上是我个人理解,感觉更好理解点。这里还有大神的理解(有点难懂):
http://www.laruence.com/2009/05/28/863.html
http://www.cnblogs.com/lhb25/archive/2011/09/06/javascript-scope-chain.html