几个JS代码题的解析

考题 1

难度:**

    var a = 1;
    function a() {}
    console.log(a) 

以上代码运行结果: 1

代码解析:

JS代码的运行分为 预解析阶段和执行阶段,只有在预解析结束后,才会进入执行阶段

在预解析阶段,会进行语法检查、函数及变量的声明等工作

而函数和变量的声明,是先声明函数后声明变量

解析阶段不会赋值,只会声明变量

也就是在执行前,代码中的所有函数和变量都已经声明好了,因此这种现象也叫做 声明提升

思考:下面代码的运行结果是什么?

    function b() {}
    console.log(b)
    var b = 2;

以上代码运行结果: function b()

代码解析:

变量 b 重复声明,在第二次 var b 时,会被忽略,声明无效

-------------------------------------------------------------

考题 2

难度:***

    var foo = 1;
    function fn() {
        foo = 10;
    }
    fn();
    console.log(foo);

以上代码运行结果: 10

代码解析:

代码执行到 fn() 函数调用,函数中的代码就会执行

函数中 foo=10 是直接使用foo变量并赋值 而函数中并没有 foo 变量的声明

因此,根据作用域及作用域链的相关知识可知,函数中在使用变量 foo 时会向上一层作用域查找

如果找到,则直接使用,因此,全局中的 foo 变量,在函数中被重新赋值为 10

函数中 foo 也被称为 隐式全局变量

思考:下面代码的运行结果是什么?

    var foo = 1;
    function fn() {
        foo = 10;
        return;
        function foo() {
        }
    }
    fn();
    console.log(foo);

以上代码运行结果: 1

代码解析:

在调用函数 fn 时同样会先进行预解析再进行代码执行这两个阶段

而函数中的代码在进行预解析阶段时,会先声明一个函数 foo ,此时函数内部就有了一个局部的变量声明 foo

在代码运行时,foo=10 实际是操作的函数内部的局部变量foo,而这个foo就是在预解析阶段时声明过的局部变量

所以 foo=10 不会发生作用域链的查找,因此也不会影响到全作用域中的foo变量

-------------------------------------------------------------

考题 3

难度:****

   var x = 1,
        y = 0,
        z = 0;


    var add = function (x) {
        return x = x + 1;
    }
    y = add(x);


    function add(x) {
        return x = x + 3;
    }
    z = add(x);


    console.log(x, y, z); 

以上代码运行结果: 1 2 2

代码解析:

代码中有两个 add 函数,一个是表达式声明一个是关键字声明

表达式声明的函数,在预解析阶段只是声明了变量 而不是 函数

关键字声明的函数,在预解析阶段声明了函数

预解析阶段的 函数声明 要 优先于变量的声明 因此关键字函数add优先声明

但是 预解析阶段结束后,在代码执行阶段时,表达式声明的函数会被赋值

因此 两次函数的调用 y=add(x) z=add(x) 实际都是在调用 表达式函数add

-------------------------------------------------------------

考题 4

难度:*****

  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);

以上代码运行结果: undefined 0 0 0

代码解析:

代码 var a = fun(0); 调用函数传入一个实参0,函数形参两个,因此第二形参接受到的值是 undefined

函数返回值 是一个对象 变量 a 接收

因此 a.fun() 调用的就是 对象中的fun方法

方法的返回值 是 fun() ,也就是说 a.fun(x) === fun(x,x)

参数 m 是对象方法调用时的传参,参数 n 则是 最开始函数调用时传入的参数

最后:欢迎关注 西岭老湿 微信公众号;

欢迎关注西岭老湿知乎专栏: https://zhuanlan.zhihu.com/xilinglaoshi

西岭老湿 博客地址:http://blog.xiling.me

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值