js函数题

题目一:

(function() {
   var a = b = 5;
})();

console.log(b);
控制台(console)会打印出什么?

答案:5。
这个问题的陷阱就是,在立即执行函数表达式(IIFE)中,有两个赋值,但是其中变量a使用关键词var来声明。这就意味着a是这个函数的局部变量。与此相反,b被分配给了全局作用域。

这个问题另一个陷阱就是,在函数中没有使用”严格模式” 。如果 严格模式开启,那么代码就会报错 ” Uncaught ReferenceError: b is not defined” 。请记住,如果这是预期的行为,严格模式要求你显式地引用全局作用域。

题目二:

function test() {
   console.log(a);
   console.log(foo());

   var a = 1;
   function foo() {
      return 2;
   }
}

test();

这段代码的执行结果是undefined 和 2。
这个结果的原因是,变量和函数都被提升(hoisted) 到了函数体的顶部。因此,当打印变量a时,它虽存在于函数体(因为a已经被声明),但仍然是undefined。

题目三:

运行以下程序,y和z的最终结果?
var m= 1, j = k = 0;
function add(n) {
  return n = n+1;
}
y = add(m);
function add(n) {
  return n = n + 3;
}
z = add(m);

答案:4 4
由于函数声明提升,所以函数声明会提前,由于存在同名函数,后面的add函数将覆盖第一个add函数

题目四:

以下函数运行结果为:
(function() {
var x=foo();
var foo=function foo() {
return “foobar”
};
return x;
})();

答案:TypeError: foo is not a function
foo变量“被提前”了,但是他的赋值(也就是函数)并没有被提前,从这一点上来说,和前面我们所讲的变量“被提前”是完全一致的,并且,由于“被提前”的变量的默认值是 undefined。
函数声明可以被提前,但函数表达式不能被提前

题目五:

:以下代码的输出结果是?
var f = function g() {
        return 23;
    };
typeof g();

答案:error
在 JS 里,声明函数只有 2 种方法:
第 1 种: function foo(){…} (函数声明)
第 2 种: var foo = function(){…}

除此之外,类似于 var foo = function bar(){…} 这样的东西统一按 2 方法处理,即在函数外部无法通过 bar 访问到函数,因为这已经变成了一个表达式。

这里如果求 typeof g ,会返回 undefined,但求的是 g(),所以会去先去调用函数 g,这里就会直接抛出异常,所以是 Error。

题目六:

var scope = "global";
function myFunc(){
 console.log(scope); 
 var scope = "local";
}

答案:undefined
控制台打印出来的不是“global”而是“undefined”,这是因为在myFunc这个函数的作用域中,局部变量scope声明被提前至函数顶部,而此时,scope仅声明,未赋值,因此输出undefined

题目七:

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

答案:10
代码执行到 fn() 函数调用,函数中的代码就会执行
函数中 foo=10 是直接使用foo变量并赋值 而函数中并没有 foo 变量的声明
因此,根据作用域及作用域链的相关知识可知,函数中在使用变量 foo 时会向上一层作用域查找
如果找到,则直接使用,因此,全局中的 foo 变量,在函数中被重新赋值为 10
函数中 foo 也被称为 隐式全局变量

题目八:

 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 则是 最开始函数调用时传入的参数

题目九:

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变量

题目十:

 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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值