欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

你真的了解Js吗?用五个问题来回顾一下,留下你的答案,我们一起进步!(系列十)

程序员文章站 2022-04-05 09:47:17
...

你真的了解Js吗(一)

灵感来自Amandeep Singh大佬的文章,也是我第一次翻译英文技术文章(仅翻译了前言和题目),问题主要考察的是作用域、this指向、立即执行函数、变量提升相关知识点,我在翻译加上了自己的思考和回答,如果有错误欢迎大家指正!

选择这篇文章作为前端内功系列的期中总结,为了贴合前面总结的知识点,我仅保留了部分题目,希望能引发自己和大家的思考,加油~

希望大家可以将答案写在评论区下方,增加参与感,我也会在下一篇文章中给出问题的答案。

目录

一、前言

JavaScript是一种非常有趣的语言,我们都因为它的某些性质而爱上了它。
对于JavaScript来说,浏览器就是大本营,并且它们可以一起很好的为我们服务。

在Js中,有一些概念是容易被人们忽视的,甚至曾因为它们而吃过苦头。例如:原型、闭包、事件循环仍然是大部分开发者会可以绕开的“晦涩”的领域。

正如我们所知道的,不掌握细节是一件危险的事情,很可能导致你犯错。

让我们玩一个小游戏,我会问你几个问题,而你需要试着去回答它们。如果你不知道答案,或者问题超过了你的知识范围,不妨大胆的给出猜测。
记录下你的回答,并在之后检查你的答案,每答对一道题,就给自己一分,让我们开始吧!

二、开始答题

阅读完问题后大家可以停下来思考一下,再看看我的回答与分析,看看我们呼应上没有《手动狗头》~

问题一:在浏览器中,下面代码会输出什么?

var a = 10;
function foo(){
    console.log(a); // qustion
    var a = 20;
}
foo();

我的分析

上述代码等价于:

foo(){
    var a;
    console.log(a);
    a = 20
}
var a
a = 10

我的答案

输出:undefined,正如上面分析得一样:

  1. 执行foo函数,函数作用域内 a变量提升到作用域顶部
  2. 打印a,此时a变量已声明但未赋值,为undeined
  3. 函数内a变量赋值,执行结束a变量销毁
  4. 函数外变量执行

核心问题

不要慌,变量提升会在之后作为JS专题系列的文章与大家见面~

你真的了解Js吗?用五个问题来回顾一下,留下你的答案,我们一起进步!(系列十)

问题二:如果上一题中的var声明改为let声明结果会一样吗?

var a = 10;
function foo(){
    console.log(a); // qustion
    let a = 20;
}
foo();

我的分析

上述代码等价于:

foo(){
    console.log(a);
    let a = 20;
}
var a
a = 10

我的答案

输出:ReferenceError报错
典型暂时性死区问题:
函数作用域因为let的声明而成为了一个块级作用域,且let声明的变量不会提升,并且在它声明之前使用变量即报错

核心问题

  • let声明
  • 变量提升

问题三:还是和上面类似的问题,这次结果是什么?

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

我的分析

同样是作用域问题,我们来分析一下:

  1. 全局作用域 :var name = ‘world!’; 没什么问题
  2. 立即指向函数内自成作用域:if判断为
    • var name // 此时name为undefined,声明为定义
    • if ( typeof name === ‘undefined’) 判断成立
    • name = 'Jack'
    • console.log('Goodbye' + name )

我的答案

输出:“Goodbye Jack”

核心问题

你真的了解Js吗?用五个问题来回顾一下,留下你的答案,我们一起进步!(系列十)

问题四:新数组中将包含哪些元素?

var arr = [];
for(var i = 0; i < 3; i++) {
    arr.push(() => i);
}
var newArr = arr.map(el => el());
console.log(newArr); // ??

我的分析

经典问题的变形:

  1. for循环向arr中添加了三个返回i的匿名函数
  2. arr数组遍历,分别将函数执行后的返回值返回
  3. 返回新数组

我的答案

输出:[3, 3, 3]

核心问题

问题五:下面代码的xGetter结果是什么?

var x = 10;
var foo = {
    x: 90,
    getX: function() {
        return this.x;
    }
};
foo.getX(); // prints 90
var xGetter = foo.getX;
xGetter(); // prints ??

我的分析

读一遍代码:经典的this指向问题

  1. foo的属性getX保存了一个匿名函数
  2. getX中保存的一个匿名函数的引用赋值给了xGetter
  3. 这里抓住重点:
    • 当函数作为对象的方法调用时,this指向当前对象
    • 当函数作为普通函数调用时,this指向全局对象——window

这里有疑惑的同学推荐大家看一下《this、call、apply详解,系列(一)》

我的答案

输出: 10

核心问题

参考

你真的了解Js吗?用五个问题来回顾一下,留下你的答案,我们一起进步!(系列十)

写在做后

前端内功进阶系列已经第十篇了,为了能让参与感强烈些,希望大家可以在评论区写下自己心中的答案,一起进步~

JavaScript内功系列:

  1. this、call、apply详解,系列(一)
  2. 从原型到原型链,系列(二)
  3. 从作用域到作用域链,系列(三)
  4. JavaScript中的执行上下文(四)
  5. JavaScript中的变量对象(五)
  6. JavaScript之自执行函数表达式(六)
  7. JavaScript中的闭包,给自己一场重生(七)
  8. 参数传递(求值策略)(八)
  9. JavaScript中的的数据类型(九)
  10. 本文

上面的问题是我参考了几位大牛的问题,并结合系列中已经提到的知识点整理出来的,未来我也会出更多版本的《你真的了解Js吗》

关于我

  • 花名:余光
  • WX:j565017805
  • 沉迷JS,水平有限,虚心学习中

其他沉淀

如果您看到了最后,不妨收藏、点赞、关注一下吧!您的三连就是我最大的动力,虚心接受大佬们的批评和指点,共勉!

你真的了解Js吗?用五个问题来回顾一下,留下你的答案,我们一起进步!(系列十)