作用域&变量提升&闭包题目及内容解答

  • 作用域&变量提升&闭包题目及内容解答已关闭评论
  • 31 次浏览
  • A+
所属分类:Web前端
摘要

这段代码的关键在于:var x = y = 1; 实际上这里是从右往左执行的,首先执行y = 1, 因为y没有使用var声明,所以它是一个全局变量,然后第二步是将y赋值给x,讲一个全局变量赋值给了一个局部变量,最终,x是一个局部变量,y是一个全局变量,所以打印x是报错。


这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

作用域&变量提升&闭包题目及内容解答

1. 代码输出结果

(function(){    var x = y = 1; })(); var z;  console.log(y); // 1 console.log(z); // undefined console.log(x); // Uncaught ReferenceError: x is not defined

这段代码的关键在于:var x = y = 1; 实际上这里是从右往左执行的,首先执行y = 1, 因为y没有使用var声明,所以它是一个全局变量,然后第二步是将y赋值给x,讲一个全局变量赋值给了一个局部变量,最终,x是一个局部变量,y是一个全局变量,所以打印x是报错。

2. 代码输出结果

var a, b (function () {    console.log(a);    console.log(b);    var a = (b = 3);    console.log(a);    console.log(b);    })() console.log(a); console.log(b);

输出结果:

undefined  undefined  3  3  undefined  3

这个题目和上面题目考察的知识点类似,b赋值为3,b此时是一个全局变量,而将3赋值给a,a是一个局部变量,所以最后打印的时候,a仍旧是undefined。

3. 代码输出结果

var friendName = 'World'; (function() {   if (typeof friendName === 'undefined') {     var friendName = 'Jack';     console.log('Goodbye ' + friendName);   } else {     console.log('Hello ' + friendName);   } })();

输出结果:Goodbye Jack

我们知道,在 JavaScript中, Function 和 var 都会被提升(变量提升),所以上面的代码就相当于:

var name = 'World!'; (function () {     var name;     if (typeof name === 'undefined') {         name = 'Jack';         console.log('Goodbye ' + name);     } else {         console.log('Hello ' + name);     } })();

这样,答案就一目了然了。

4. 代码输出结果

function fn1(){   console.log('fn1') } var fn2   fn1() fn2()   fn2 = function() {   console.log('fn2') }   fn2()

输出结果: 

fn1 Uncaught TypeError: fn2 is not a function fn2

这里也是在考察变量提升,关键在于第一个fn2(),这时fn2仍是一个undefined的变量,所以会报错fn2不是一个函数。

5. 代码输出结果

function a() {     var temp = 10;     function b() {         console.log(temp); // 10     }     b(); } a();  function a() {     var temp = 10;     b(); } function b() {     console.log(temp); // 报错 Uncaught ReferenceError: temp is not defined } a();

在上面的两段代码中,第一段是可以正常输出,这个应该没啥问题,关键在于第二段代码,它会报错Uncaught ReferenceError: temp is not defined。这时因为在b方法执行时,temp 的值为undefined。

6. 代码输出结果

 var a=3;  function c(){     alert(a);  }  (function(){   var a=4;   c();  })();

js中变量的作用域链与定义时的环境有关,与执行时无关。执行环境只会改变this、传递的参数、全局变量等

7. 代码输出问题

function fun(n, o) {   console.log(o)   return {     fun: function(m){       return fun(m, n);     }   }; } var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3); var b = fun(0).fun(1).fun(2).fun(3); var c = fun(0).fun(1);  c.fun(2);  c.fun(3);

输出结果:

undefined  0  0  0 undefined  0  1  2 undefined  0  1  1

这是一道关于闭包的题目,对于fun方法,调用之后返回的是一个对象。我们知道,当调用函数的时候传入的实参比函数声明时指定的形参个数要少,剩下的形参都将设置为undefined值。所以 console.log(o); 会输出undefined。而a就是是fun(0)返回的那个对象。也就是说,函数fun中参数 n 的值是0,而返回的那个对象中,需要一个参数n,而这个对象的作用域中没有n,它就继续沿着作用域向上一级的作用域中寻找n,最后在函数fun中找到了n,n的值是0。了解了这一点,其他运算就很简单了,以此类推。

8. 代码输出结果

f = function() {return true;};    g = function() {return false;};    (function() {       if (g() && [] == ![]) {          f = function f() {return false;};          function g() {return true;}       }    })();    console.log(f());

输出结果: false

这里首先定义了两个变量f和g,我们知道变量是可以重新赋值的。后面是一个匿名自执行函数,在 if 条件中调用了函数 g(),由于在匿名函数中,又重新定义了函数g,就覆盖了外部定义的变量g,所以,这里调用的是内部函数 g 方法,返回为 true。第一个条件通过,进入第二个条件。

第二个条件是[] == ![],先看 ![] ,在 JavaScript 中,当用于布尔运算时,比如在这里,对象的非空引用被视为 true,空引用 null 则被视为 false。由于这里不是一个 null, 而是一个没有元素的数组,所以 [] 被视为 true, 而 ![] 的结果就是 false 了。当一个布尔值参与到条件运算的时候,true 会被看作 1, 而 false 会被看作 0。现在条件变成了 [] == 0 的问题了,当一个对象参与条件比较的时候,它会被求值,求值的结果是数组成为一个字符串,[] 的结果就是 '' ,而 '' 会被当作 0 ,所以,条件成立。

两个条件都成立,所以会执行条件中的代码, f 在定义是没有使用var,所以他是一个全局变量。因此,这里会通过闭包访问到外部的变量 f, 重新赋值,现在执行 f 函数返回值已经成为 false 了。而 g 则不会有这个问题,这里是一个函数内定义的 g,不会影响到外部的 g 函数。所以最后的结果就是 false。

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 作用域&变量提升&闭包题目及内容解答