js几个经典的题目详解

1、做用域、运算符(逗号运算、赋值运算)浏览器

 1 var out = 25,
 2    inner = {
 3         out: 20,
 4         func: function () {
 5             var out = 30;
 6             return this.out;
 7         }
 8     };
 9 console.log((inner.func, inner.func)());
10 console.log(inner.func());
11 console.log((inner.func)());
12 console.log((inner.func = inner.func)());
 1 25,20,20,25
 2 
 3 代码解析:这道题的考点分两个 
 4 1.做用域
 5 2.运算符(赋值预算,逗号运算)
 6 
 7 先看第一个输出:25,由于(inner.func, inner.func)是进行逗号运算符,逗号运算符就是 运算前面的,
 8 返回最后一个,举个栗子
 9 
10 var i=0,j=1,k=2;
11 console.log((i++,j++,k))//返回的是k的值 2 ,若是写成k++的话  这里返回的就是 3
12 console.log(i);//1
13 console.log(j);//2
14 console.log(k);//2   
15 
16 回到原题(inner.func, inner.func)就是返回inner.func而inner.func只是一个匿名函数 
17 function () {
18     var out = 30;
19     return this.out;
20 }
21 并且这个匿名函数是属于window的
22 则变成了
23 (function () {
24     var out = 30;
25     return this.out;
26 })()
27 此刻的this--》window
28 
29 因此out 是25
30 
31 第二和第三个console.log的做用域都是 foo,也就是他们执行的实际上是
32 foo.func();
33 foo做用域中是有out变量的,因此结果是20
34 
35 第四个console.log
36 考查的是一个等号运算inner.func = inner.func 其实返回的是运算的结果,
37 举个栗子
38 var a=2,b=3;
39 console.log(a=b)//输出的是3
40 因此inner.func = inner.func 返回的也是一个匿名函数
41 function () {
42     var out = 30;
43     return this.out;
44 }
45 
46 此刻 道理就和第一个console.log同样了 输出的结果是 25

2、变量声明提早函数

1 if (!("a" in window)) {
2     var a = 1;
3 }
4 alert(a);
 1 代码解析:若是window不包含属性a,就声明一个变量a,而后赋值为1。
 2 
 3 你可能认为alert出来的结果是1,而后实际结果是“undefined”。要了解为何,
 4 须要知道JavaScript里的3个概念。
 5 
 6 首先,全部的全局变量都是window的属性,语句 var a = 1;等价于window.a = 1;
 7 
 8 你能够用以下方式来检测全局变量是否声明:"变量名称" in window
 9 第二,全部的变量声明都在范围做用域的顶部,看一下类似的例子:   
10 
11 alert("b" in window);
12 var b;
13 
14 此时,尽管声明是在alert以后,alert弹出的依然是true,这是由于JavaScript引擎
15 首先会扫墓全部的变量声明,而后将这些变量声明移动到顶部,最终的代码效果是这样的:
16 
17 var a;
18 alert("a" in window);
19 这样看起来就很容易解释为何alert结果是true了。
20 
21 第三,你须要理解该题目的意思是,变量声明被提早了,
22 但变量赋值没有,由于这行代码包括了变量声明和变量赋值。
23 
24 你能够将语句拆分为以下代码:
25 
26 var a;    //声明
27 a = 1;    //初始化赋值
28 当变量声明和赋值在一块儿用的时候,JavaScript引擎会自动将它分为两部以便将变量声明提早,
29 不将赋值的步骤提早是由于他有可能影响    代码执行出不可预期的结果。
30 
31 因此,知道了这些概念之后,从新回头看一下题目的代码,其实就等价于:
32 
33 var a;
34 if (!("a" in window)) {
35     a = 1;
36 }
37 alert(a);
38 这样,题目的意思就很是清楚了:首先声明a,而后判断a是否在存在,若是不存在就赋值为1,
39 很明显a永远在window里存在,这个赋值语    句永远不会执行,因此结果是undefined。
40 
41 提早这个词语显得有点迷惑了,你能够理解为:预编译。

3、函数声明与函数表达式this

1    var a = 1;
2 
3    var b = function a(x) {
4             x && a(--x);
5         };
6  
7    alert(a);
 1 这个题目看起来比实际复杂,alert的结果是1;这里依然有3个重要的概念须要咱们知道。
 2 
 3 首先,在题目1里咱们知道了变量声明在进入执行上下文就完成了;第二个概念就是函数声明也是提早的,
 4 全部的函数声明都在执行代码以前都已经完成了声明,和变
 5 
 6 量声明同样。澄清一下,函数声明是以下这样的代码:
 7 
 8 function functionName(arg1, arg2){
 9     //函数体
10 }
11 以下不是函数,而是函数表达式,至关于变量赋值:
12 
13 var functionName = function(arg1, arg2){
14        //函数体
15    };
16 澄清一下,函数表达式没有提早,就至关于平时的变量赋值。
17 
18 第三须要知道的是,函数声明会覆盖变量声明,但不会覆盖变量赋值,为了解释这个,咱们来看一个例子:
19 
20 function value(){
21     return 1;
22 }
23 var value;
24 alert(typeof value);    //"function"
25 尽快变量声明在下面定义,可是变量value依然是function,也就是说这种状况下,
26 函数声明的优先级高于变量声明的优先级,但若是该    变量value赋值了,那结果就彻底不同了:
27 
28 function value(){
29     return 1;
30 }
31 var value = 1;
32 alert(typeof value);    //"number"
33 该value赋值之后,变量赋值初始化就覆盖了函数声明。
34 
35 从新回到题目,这个函数实际上是一个有名函数表达式,函数表达式不像函数声明同样能够覆盖变量声明,
36 但你能够注意到,变量b是包含了该函数表达式,而该函数表达式的名字是a;不一样的浏览器对a这个名
37 词处理有点不同,在IE里,会将a认为函数声明,因此它被变量初始    化覆盖了,就是说若是调用a(–x)的
38 话就会出错,而其它浏览器在容许在函数内部调用a(–x),由于这时候a在函数外面依然是数字。
39 基本上,IE里调用b(2)的时候会出错,但其它浏览器则返回undefined。
40 
41 理解上述内容以后,该题目换成一个更准确和更容易理解的代码应该像这样:
42 
43 var a = 1,
44     b = function(x) {
45     x && b(--x);
46     };
47 alert(a);
48 这样的话,就很清晰地知道为何alert的老是1了。

4、函数声明与变量声明spa

1 function a(x) {
2     return x * 2;
3 }
4 var a;
5 alert(a);
这个题目比较简单:即函数声明和变量声明的关系和影响,遇到同名的函数声明,不会从新定义

5、argumentscode

1 function b(x, y, a) {
2         arguments[2] = 10;
3         alert(a);
4     }
5     b(1, 2, 3);
1 关于这个题目,ECMAsCRIPT 262-3的规范有解释的。
2 
3 活动对象是在进入函数上下文时刻被建立的,它经过函数的arguments属性初始化。
4 arguments属性的值是Arguments对象.
5 关于 Arguments对象的具体定义,看这里:ECMAScript arguments 对象

6、call对象

1 function a() {
2         alert(this);
3     }
4     a.call(null);
 1 这个题目能够说是最简单的,也是最诡异的!关于这个题目,咱们先来了解2个概念。
 2 
 3 这个问题主要考察 Javascript 的 this 关键字,具体看这里:
 4 
 5 关于Javascript语言中this关键字的用法
 6 
 7 关于 a.call(null);  根据ECMAScript262规范规定:若是第一个参数传入的对象调用者是null
 8 或者undefined的话,call方法将把全局对象(也就是window)做为this的值。因此,
 9 无论你何时传入null,其this都是全局对象window,因此该题目能够理解成以下代码:
10 function a() {
11     alert(this);
12 }
13 a.call(window);
14 因此弹出的结果是[object Window]就很容易理解了。
相关文章
相关标签/搜索