第一道:var tt = 'aa';
function test(){
alert(tt);
var tt = 'dd';
alert(tt);
}
test();
第二道:var myObject= {
num: 2,
add: function(){
this.num=3;
(function(){
alert(this.num);
this.num=4;
})();
alert(this.num)
}
}myObject.add();
凡得出正确答案者,请自觉到网易门口排队进行面试!!!
function test(){
alert(tt);
var tt = 'dd';
alert(tt);
}
test();
第二道:var myObject= {
num: 2,
add: function(){
this.num=3;
(function(){
alert(this.num);
this.num=4;
})();
alert(this.num)
}
}myObject.add();
凡得出正确答案者,请自觉到网易门口排队进行面试!!!
解决方案 »
- 这段代码啥意思?
- 关于js读取数据作对比,谁能帮下
- 如何通过JavaScript GIS开发地图
- 被我的网页代码挂马了!谁知道吗?
- jquery 的thickbox 3.1插件 内存回收的问题
- 谁帮我改个JS翻页,下面的JN倒过来了````谢谢
- 想sina那样弹出一个小电视窗口,是怎么弄的?
- 急!!在线等待 select多选怎样传值 高分
- 请高手加盟,有java编程经验,特别对javascript精通。
- 请把下面的JSSCRIPT大小写转换程序转换成VBSCRIPT程序
- jQuery 取值问题
- |zyciis| 当Jquery.ui.datepicker用$(this).datepicker();的方法显示的时候,第一次焦点不显示,第二次才显示,为什么
第二题测试 (function(){})小小题目,专业性很强啊
至少对其原因有所了解,若类似代码报undefined啊,也能快速排查到。
所以我猜测JS里面函数被预先编译过了。 当它执行到alert(tt); 的时候它认为tt就是这个函数里的局部变量所以导致undefine
function test(){
alert(tt);
//var tt = 'dd';
//alert(tt);
}
test(); 看看这个结果是什么
做个第二题的解释,
var myObject= {
num: 2,
add: function(){
this.num=3;
(function(){
alert(this.num);
this.num=4;
})();
alert(this.num)
}
}myObject.add();
this.num=3;这个this 是myObject这个对象的一个实例化。
第一个alert(this.num); 中的this 是这个function(){
alert(this.num);
this.num=4;
}对象的一个实例化。那么第一次的alert(this.num); 当执行到它的实惠它并未被定义,所以是undefine.而第二个alert(this.num),在之前被赋值过了所以第二个值是3
var tt ="aa";
function test(){
alert(tt);
var tt ;
alert(tt);
}
test();
这样就都是undefined,如果
var tt ="aa";
function test(){
alert(window.tt);
var tt = 'dd' ;
alert(tt);
}
test();
这样就是aa,dd 如果
var tt ="aa";
function test(){
alert(tt);
}
test(); 这样因为没有定义function中的局部变量tt,作用域链会找到window下的tt,等同于alert(window.tt)
(function(){
alert(this.num);
this.num=4;
})();
匿名函数不属于任何一个对象,这里的this指向的是window,所以是undefined
num: 2,
add: function(){
this.num=3;
(function(){
alert(this.num); // 一切的关键就在于这个this指的是什么? 想知道的话请看最后一句语句
this.num=4;
})();
alert(this.num)
}
}myObject.add();alert(num); // 看清楚,这里的num跟myObject完全没有任何关系了
// 而最终结构就是4,所以那个嵌套函数中的this指的就是window
不然全局的变量应该是在window这个对象下的,
所以按照常理来说不可能会找不到tt。
很遗憾,这个题我错了。
这涉及到作用域链的问题,当执行Test函数时,Test的作用域排在最前面,WINDOW的作用域排在后面。Test的作用域包括函数里面的变量,函数定义,参数,this指针,arguments TEST的作用域在代码执行之前的语法分析过程就已经完成,所用的变量定义都是undefined,this指针赋值为它的直接调用者,在这里是window的对象,第二题myObject.add(),add函数的直接调用者是myObject,里面的闭包函数的直接调用者是WINDOW对象!一个函数里面的this指针判断依据是看它的直接调用者,凡没有直接调用者,this指针都是window对象,不过可以用apply,call函数改变this指针,比如第二题可以这样写:
(function(){
alert(this.num);
this.num=4;
}).call(this);
这样的话里面的this指针就变成了myObject,答案应该是3,4.验证果然正确!
当需要判断一个变量是否为 undefined 时,直接用
Js代码 1. alert(om == undefined); alert(om == undefined);
可能出错。因为 JS 如果引用未声明的变量,那么会出现JS错误,在上述例子中,如果 om 未曾声明,就会报 JS 错误。因此判断一个变量是 undefined,最好用这种方法
Js代码 1. alert( typeof om == 'undefined' ); alert(typeof om == 'undefined');2. JS 中没有块作用域,在函数中声明的变量在整个函数中都可用(无论是在函数开头处声明还是末尾处声明),如
Js代码 1. function () {
2. alert(om); // 显示 undefined
3. var om = 'abc' ;
4. alert(om); // 显示 abc
5. } function() {
alert(om); // 显示 undefined
var om = 'abc';
alert(om); // 显示 abc
}3. JS 在函数执行前将整个函数的变量进行声明,无论这个变量的声明语句有没有机会执行,如
Js代码 1. function () {
2. alert(om); // 显示 undefined
3. if ( false ) {
4. var om = 'abc' ; // 此处声明没有机会执行
5. }
6. } ======================================================================今天工作需要,搜索下JS面试题,看到一个题目,大约是这样的
Js代码 1. <script>
2. var x = 1, y = z = 0;
3. function add(n) {
4. n = n+1;
5. }
6.
7. y = add(x);
8.
9. function add(n) {
10. n = n + 3;
11. }
12.
13. z = add(x);
14. </script> <script>
var x = 1, y = z = 0;
function add(n) {
n = n+1;
} y = add(x);
function add(n) {
n = n + 3;
} z = add(x);
</script>问执行完毕后 x, y, z 的值分别是多少?仔细看的人马上就知道了, x, y 和 z 分别是 1, undefined 和 undefined。不过,如果将两个 add 函数修改一下,题目变为
Js代码 1. <script>
2. var x = 1, y = z = 0;
3. function add(n) {
4. return n = n+1;
5. }
6.
7. y = add(x);
8.
9. function add(n) {
10. return n = n + 3;
11. }
12.
13. z = add(x);
14. </script> <script>
var x = 1, y = z = 0;
function add(n) {
return n = n+1;
} y = add(x);
function add(n) {
return n = n + 3;
} z = add(x);
</script>
那么这时 y 和 z 分别是什么呢?我马上想到是 2 和 4,不过结果却是 4 和 4。
这说明,在第一次调用 add 函数之前,第二个 add 函数已经覆盖了第一个 add 函数。原来,这是 JS 解释器的"预编译",JS 解析器在执行语句前会将函数声明和变量定义进行"预编译",而这个"预编译",并非一个页面一个页面地"预编译",而是一段一段地预编译,所谓的段就是一个 <script> 块。且看下面的代码
Js代码 1. <script>
2. function add(n) {
3. return n = n+1;
4. }
5. alert(add(1));
6. </script>
7.
8. <script>
9. function add(n) {
10. return n = n+3;
11. }
12. alert(add(1));
13. </script> <script>
function add(n) {
return n = n+1;
}
alert(add(1));
</script><script>
function add(n) {
return n = n+3;
}
alert(add(1));
</script>会分别弹出 2 和 4。那么,将上面的题目再变换一下,如下
Js代码 1. <script>
2. alert( typeof addA);
3. addA();
4. function addA() {
5. alert( "A executed!" );
6. };
7. </script>
8. <script>
9. alert( typeof addB);
10. addB();
11. var addB = function () {
12. alert( "B executed!" );
13. };
14. </script> <script>
alert(typeof addA);
addA();
function addA() {
alert("A executed!");
};
</script>
<script>
alert(typeof addB);
addB();
var addB = function() {
alert("B executed!");
};
</script>执行结果是什么呢? 按照前面的知识,第一个 <script> 块执行正常,结果就是弹出 "function" 和 "A executed!" 的对话框。
那么第二个 <script> 块呢? 执行结果是弹出 "undefined" 的对话框后报 JS 错误,说 addB 不是一个 function。
有点出乎意料?呵呵,其实第一个 script 块中的 addA 一句是函数声明,当然进行了"预编译",但是第二个 script 块中的 addB 一句并非函数声明。只不过在执行这段 <script> 之前对变量进行了"预声明",因此一开始变量addB是存在的,只不过是 undefined 的(可参看http://eclipse07.javaeye.com/admin/blogs/484566 )。因此执行结果便如上面所示。将题目再变化下,如下
Js代码 1. <script>
2. alert( typeof addB);
3. addB();
4. var addB = function addB() {
5. alert( "B executed!" );
6. };
7. </script> <script>
alert(typeof addB);
addB();
var addB = function addB() {
alert("B executed!");
};
</script>
执行结果如何呢?
在 ff 下执行,与上面执行结果一样。打住,且在 IE6 下执行看看如何。
结果是弹出 "function" 和 "B executed!",一切正常。
Google 了一下,有人说这是 IE 的 BUG。那么,请看下面的代码
Js代码 1. <script>
2. alert( typeof addB);
3. var addB = "variable" ;
4. function addB() {
5. alert( "function addB" );
6. }
7. alert(addB);
8. </script> <script>
alert(typeof addB);
var addB = "variable";
function addB() {
alert("function addB");
}
alert(addB);
</script>
执行结果是"function"和"variable"。
JS解析器先预定义了 addB 变量为 undefined, 但是 addB 函数覆盖了此变量,因此一开始执行结果是 function,然后 addB 被赋值为 "variable",因此最后执行结果是 "variable",上面的代码即使变为
Js代码 1. <script>
2. alert( typeof addB);
3. function addB() {
4. alert( "function addB" );
5. }
6. var addB = "variable" ;
7. alert(addB);
8. </script> <script>
alert(typeof addB);
function addB() {
alert("function addB");
}
var addB = "variable";
alert(addB);
</script>
结果也一样,这说明JS解析器先预声明变量,再预定义函数 。
小结一下:JS 在执行前会进行类似"预编译"的操作,而且先预定义变量再预定义函数。