从作用域知识点看打印结果

51 阅读2分钟

这是我参与「4月日新计划更文活动」的第18天。

今天带着带着大家一起来看一下js方向的一些知识点。

js属于特别重要的知识,今天先来看一下作用域方面的知识点。

那我主要讲几个常用的作用域的知识点吧。

最重要的知识点:作用域的变量提升

先看下面这个题目,大家猜猜看执行结果是什么?

var name='World!';
(function () {
  if (typeof name==='undefined') {
    var name='Jack'; // 函数作用域会向前提升
    console.log('Goodbye '+name);
  } else {
    console.log('Hello '+name);
  }
})();

一看,有点傻眼了吧。

正确的输出结果是:Goodbye Jack。

为什么呢?

var name='Jack';作用域会提升到函数内部最上面,所以最开始name的数据类型是undefined,然后重新赋值成Jack。

好,我们再来看作用于变量提升的案例,看一下大家是不是已经学以致用了。

try {
  (
    function(){
      var x=y=1;
    }
  )();
  console.log(y);
  console.log(x);
} catch (error) {
  console.log('error>>>>>', error);
}

这一题输出多少呢?

正确答案是:1,error。

我来揭秘一下正确的解题思路。

首先x和y在函数内会进行变量提升。

但是在提升的时候只会用var定义第一项:var x;y;那么此时x是函数作用域,y是全局作用域,即执行结束之后x销毁,y仍然在内存中。

所以x is not defined。

那我再来一题吧,这个是箭头函数的知识点,但是我觉得箭头函数也是跟作用域相关的,也是很重要的知识。

让我们一起来看代码吧。

let obj1 = {
  name:'obj1_name',
  print:function(){
    return ()=>console.log(this.name)
  }
}
let obj2 = {name:'obj2_name'}
obj1.print()();  
obj1.print().call(obj2); 
obj1.print.call(obj2)();

这一题输出多少呢?

正确答案是:obj1_name, obj1_name, obj2_name。

大家是不是觉得有点纳闷。

不要着急,让我慢慢跟你解释清楚。

第一个输出,因为是箭头函数,指向的是obj1的属性值。

第二个输出,箭头函数无法用call/apply的方式改变this指向,this指向的是继承父级this的指向。

第三个输出,obj1.print这个时候还没有返回箭头函数,这个时候可以改版this的指向。

学知识我就最喜欢在一个知识点上花很多时间去死磕,然后把单项的能力变得很厉害。

并且在练习和学习新知识之间,不断地举一反三,加深印象,并且有新的灵感出现。

以上就是我今天学习的如何使用作用域的知识点解决结果输出的问题。

看到掘金上的好文章,如果对你有帮助,顺手点个赞,或者把文章收藏。不用担心找不到了,以后也能经常收到类似好回答,我会持续进行更新。