• 大厂HR面试必备ES6中的深入浅出面试题知识点


    file

    ESMAScript6简介,ES6是JavaScript语言的下一代标准,目的是让JavaScript语言可以写复杂的大型应用程序,成为企业级语言。那么ECMAScript和JavaScript的关系到底是什么呢?两者有着什么样的联系?

    JavaScript的创造者Netscape公司,将JavaScript提交给国际标准化组织ECMA,希望这种语言可以成为国际标准,次年,ECMA决定了浏览器脚本语言的标准,并称为ECMAScript。

    因某些原因,一是商标,二是这门语言制定者是ECMA,不是Netscape。ECMAScript和JavaScript的关系是前者是后者的规格,后者是前者的一种实现。

    ES6 let和const命令

    let命令:

    基本用法,ES6新增let命令,用来声明变量,用法类似于var,但所声明的变量,只在let命令所在的代码块内有效。

    {
     let a = 10;
     var b = 1;
    }
    
    a // ReferenceError: a is not defined
    b // 1
    

    let和var声明了两个变量,然后在代码块之外调用这两个变量,结果let声明的变量报了错,var声明的变量返回了正确的值。说明,let声明的变量只在它所在的代码块有效。

    for(let i = 0; i<10; i++) {
    }
    console.log(i);
    // ReferenceError: i is not defined
    
    var a = [];
    for(var i = 0; i<10; i++) {
     a[i] = function() {
      console.log(i);
     };
    }
    a[6](); // 10
    

    使用let,声明的变量仅仅在块级作用域内有效:

    var a = [];
    for(let i = 0; i<10; i++){
     a[i] = function() {
      console.log(i);
     };
    }
    a[6](); // 6
    

    变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出6。

    不存在变量提升

    var存在变量提升,let不会发生“变量提升”的现象,所以,变量一定要在声明后使用,不然会报错。

    console.log(a); // 输出undefined
    console.log(b); // 报错ReferenceError
    
    var a = 1;
    let b = 1;
    

    var声明的变量会发生变量提升,该变量没用赋值就已经存在了,但是没有值,就会输出undefined,变量用let命令声明,不会发生变量提升,声明变量之前,变量是不存在的,如果用它,就会报错。

    用let声明的变量是可以修改的,而用const一般用来声明常量,声明之后不能更改了。

    let a = 1;
    const b = 2;
    a = 3;
    b = 3; // 报错
    

    var命令声明的变量会发生变量提升的现象,变量在声明之前使用,其值为undefined,而let命令声明的变量没有变量提升,如果在声明之前使用,会报错的。

    暂时性死区,在一个块级作用域中对一个变量使用let声明前,该变量是不可使用,称为暂时性死区。

    da = 'coding';
    if(true) {
     // 在之前就定义 一个全局变量da,块内重新定义了一个da
     console.log(da); // 报错ReferenceError
     let da;
    }
    

    不允许重复声明:

    let命令是不允许重复声明同一个变量的

    if(true) {
     let da;
     let da; // 报错
    }
    
    function func(coding) {
     // 已经有个变量名的形参了
     let coding;
    }
    func() // 报错
    

    在代码块内,使用let命令声明变量之前,该变量都是不可用的,称为暂时性死区。

    if(true) {
     temp = 'da'; // ReferenceError
     console.log(temp); // ReferenceError
     
     let temp; // TDZ结束
     console.log(temp); // undefined
     
     temp = 12;
     console.log(temp); // 12
    }
    

    暂时性死区表明typeof不再是一个安全的操作

    typeof x; // ReferenceError
    let x;
    

    变量x使用了let命令声明,所以存在死区,用到该变量就会报错,作为对比,如果一个变量根本没有被声明,使用typeof就不会报错

    typeof dacoding // undefined
    

    ES6:

    var arr = [];
    for(var i=0; i<10; i++) {
     arr.push(function() { console.log(i) })
    }
    
    arr.forEach(function(func) {
     func()
    });
    
    // ES5
    var arr = [];
    for(var i=0; i<10; i++){
     func.push((function(value){
      return function() {
       console.log(value);
      }
     }(i))
    }
    
    // ES6
    for(let i = 0; i<10; i++) {
     func.push(function(){
      console.log(i)
     })
    }
    

    箭头函数的特点:不需要function关键字来创建函数,省略return关键字,继承当前上下文的this关键字。

    let声明变量和const声明常量,两个都有块级作用域

    ES5中没有块级作用域,var有变量提升,在let中,使用的变量一定要进行声明。箭头函数,定义不在使用关键字function(),而是用箭头 ()=> 来表示。模板字符串,是增强版的字符串,用反引号(`)表示,可以当作普通字符串使用,同时可以定义多行字符串。

    解构赋值,ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,for...of循环可以遍历数组,set和map结构。

    set数据结构类似数组一样的,所有的数据都是唯一,没有重复的值,它本身是一个构造函数,class类的继承,ES6中不像ES5中使用原型链实现继承,引入了class概念可以用来继承了

    // 基础用法
    const da1 = function (参数1, 参数2, …, 参数N) { 函数声明 }
    const da1 = (参数1, 参数2, …, 参数N) => { 函数声明 }
    
    // 当只有一个参数时,圆括号是可选
    const da2 = (单一参数) => { 函数声明 }
    const da2 = 单一参数 => { 函数声明 }
    
    // 没有参数时,圆括号不能省略
    const da3 = () => { 函数声明 }
    
    // 当函数体只是 return 一个单一表达式时,可以省略花括号和 return 关键词
    const da4 = () => { return 表达式(单一) }
    const da4 = () => 表达式(单一)
    
    // 函数体返回对象字面表达式时,如果省略花括号和 return 关键词,返回值需要加括号
    const da5 = () => { return {foo: 'bar'} }
    
    const da5 = () => ({foo: 'bar'})  
    // 输出 {foo: 'bar'}
    
    const da6 = () => {foo: 'bar'}    
    // 输出 undefined,大括号被识别为代码块
    

    块级作用域:

    es5只有全局作用域和函数作用域,没有块级作用域:

    var temp = new Date();
    
    function f() {
      console.log(temp);
      if (false) {
        var tmp = "hello world";
      }
    }
    
    f(); // undefined
    

    es6的块级作用域:

    function f1() {
      let n = 5;
      if (true) {
        let n = 10;
      }
      console.log(n); // 5
    }
    
    // IIFE 写法
    (function () {
      var temp = ...;
      ...
    }());
    
    // 块级作用域写法
    {
      let temp = ...;
      ...
    }
    

    es5中,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域中声明。

    // 情况一
    if (true) {
      function f() {}
    }
    
    // 情况二
    try {
      function f() {}
    } catch(e) {
    }
    
    // ES5的规定都是非法的
    
    // ES5严格模式
    'use strict';
    if (true) {
      function f() {}
    }
    // 报错
    

    在es6中引入了块级作用域,明确允许在块级作用域之中声明函数

    // ES6严格模式
    'use strict';
    if (true) {
      function f() {}
    }
    // 不报错
    

    es6的块级作用域声明函数只在使用大括号的情况下成立

    // 不报错
    'use strict';
    if (true) {
      function f() {}
    }
    
    // 报错
    'use strict';
    if (true)
      function f() {}
    

    箭头函数:

    用了箭头函数,this就不是在指向window,而是父级了,不能够使用arguments对象了,不能用构造函数了,就是不能使用new命令了,否则会报错,不能使用yield命令,所以箭头函数不能用作Generator函数了。

    map和set的区别:

    set用于数据重组,map用于数据储存

    set中元素不能重复,只有键值没有键名,类似数组,可以遍历,有方法add,delete,has等。

    map的本质是键值对的集合,可以遍历,可以跟各种数据转换。

    class类的出现:

    //定义类
    class Point { 
      constructor(x,y) { 
          //构造方法
           this.x = x; //this关键字代表实例对象
           this.y = y; 
      } 
      toString() {
           return '(' + this.x + ',' + this.y + ')'; 
      }
    }
    

    promise构造函数是同步执行的,then方法是异步执行的。

    function Person(){
      this.age = 10;
    
      setInterval(() => {
        this.age++;    // this 正确地指向 p 实例
      }, 100);
    }
    
    var p = new Person();  // 1s后打印出 10
    
    this.param = 1
    
    const func1 = () => console.log(this.param)
    
    const func2 = function() {
        console.log(this.param)
    }
    
    func1.apply({ param: 2 })   // 输出: 1
    func2.apply({ param: 2 })   // 输出: 2
    

    解构赋值:

    let [a, b, c] = [1, 2, 3]          
    // a:1 b:2 c:3
    
    let [a, [[b], c]] = [1, [[2], 3]]  
    // a:1 b:2 c:3
    
    let [a, , b] = [1, 2, 3]           
    // a:1 b:3
    
    let [a,...b] = [1, 2, 3]           
    // a:1 b:[2, 3]
    
    let [a, b,...c] = [1]              
    // a:1 b:undefined c:[]
    
    let [a, b = 4] = [null, undefined] 
    // a:null b:4
    
    let [a, b = 4] = [1]               
    // a:1 b:4
    
    let [a, b = 4] = [1, null]         
    // a:1 b:null
    

    解构不成功的,其变量的值为undefined,解构指定默认值,如果该被解构变量的对应位置没有值,为空或者是undefined,默认值才有效。

    let { a, b } = { a: 1, b: 2 }      
    // a:1 b:2
    
    let { c } = { a: 1, b: 2 }         
    // c:undefined
    
    let { c = 4 } = { a: 1, b: 2 }     
    // c:4
    
    let { a: c } = { a: 1, b: 2 }      
    // c:1
    
    let { a: c = 4, d: e = 5 } = { a: 1, b: 2 }   
    // c:1 e:5
    
    let { length } = [1, 2]            
    // length:2
    

    扩展运算符:

    将一个数组转化为逗号分隔的参数序列

    console.log(...[1, 2, 3])               
    // 1 2 3
    
    console.log(1, ...[2, 3, 4], 5)         
    // 1 2 3 4 5
    
    [...document.querySelectorAll('div')]   
    // [<div>, <div>, <div>]
    
    {...{a: 1}, ...{a: 2, b: 3}}            
    // {a: 2, b: 3}
    
    [...[1], ...[2, 3]]                     
    // [1, 2, 3]
    
    const arr = [1]
    arr.push(...[2, 3])                     
    // arr:[1, 2, 3
    

    默认参数:

    function log(x, y = 'World') {
        console.log(x, y)
    }
    
    log('Hello')             
    // Hello World
    
    log('Hello', undefined)  
    // Hello World
    
    log('Hello', 'China')    
    // Hello China
    
    log(undefined, 'China')  
    // undefined China
    
    log(, 'China')           
    // 报错 SyntaxError
    
    log('Hello', '')         
    // Hello
    
    log('Hello', null)       
    // Hello null
    

    参数不传递或是传递undefined会让参数等于默认值,如果参数不是最后一个,不传递参数就会报错。

    传递null不会让函数参数等于默认值。

    // 获取函数所有的参数,rest 为数组
    function func1(...rest){ /* ... */}
    
    // 获取函数第一个参数外其他的参数,rest 为数组
    function func1(val, ...rest){ /* ... */}
    

    模板字符串:

    var str = `abc
    def
    gh`;
    console.log(str);
    let name = "小明";
    function a() {
        return "ming";
    }
    console.log(`我的名字叫做${name},年龄${17+2}岁,性别${'男'},游戏ID:${a()}`);
    

    函数的默认参数:

    function A(a,b=1){
        console.log(a+b);
    }
    A(1);    //2
    A(2+3);  //5
    function A(a,b=1){
        console.log(a+b);
    }
    A(1);    //2
    A(2+3);  //5
    

    箭头函数:

    //省略写法
    var people = name => 'hello' + name;
     
    var getFullName = (firstName, lastName) => {
        var fullName = firstName + lastName;
        return fullName;
    }
    

    对象的扩展:

    var foo = 'bar';
    var baz = {foo};  
    //等同于  var baz = {foo: foo};
    
    var o = {
      method() {
        return "Hello!";
      }
    };
     
    // 等同于
    var o = {
      method: function() {
        return "Hello!";
      }
    };
    

    Promise对象

    它有三种状态,分别是pending-进行中、resolved-已完成、rejected-已失败。

    var promise = new Promise((resolve, reject) => {
        var success = true;
        if (success) {
            resolve('成功');
        } else {
            reject('失败');
        }
    }).then(
        (data) => { console.log(data)},
        (data) => { console.log(data)}
    )
    

    set数据结构

    size 数据的长度
    add() 添加某个值,返回 Set 结构本身。
    delete() 删除某个值,返回一个布尔值,表示删除是否成功。
    has() 查找某条数据,返回一个布尔值。
    clear() 清除所有成员,没有返回值。

    Spread Operator 展开运算符(...)

    将字符串转成数组

    var str="abcd";
    console.log([...str]) // ["a", "b", "c", "d"]
    

    将集合转成数组

    var set = new Set([1,2,3,4,5])
    console.log([...set]) // [1, 2, 3, 4, 5]
    

    数组的合并

    var a1=[1,2,3];
    var a2=[4,5,6];
    
    console.log([...a1,...a2]); 
    //[1, 2, 3, 4, 5, 6]
    

    rest参数 …变量名称

    function func(...args){
        console.log(args);
        //[1, 2, 3, 4]
    }
    func(1, 2, 3, 4);
     
    function f(x, ...y) {
        console.log(x);
        console.log(y);
    }
    
    f('a', 'b', 'c');     //a 和 ["b","c"]
    f('a')                //a 和 []
    f()                   //undefined 和 []
    

    经典

    var val = "全局变量";
    
    {
      let val = "局部变量";
      console.log(val);     
      // 局部变量
    }
    
    console.log(val);       
    // 全局变量
    
    const val = "常量";
    val = "123";            
    // Uncaught TypeError: Assignment to constant variable.
    

    迭代器iterator、for...of和for...in

    //for in 会继承
    for (let i in iterable) {
        console.log(i); 
        // 依次打印 0, 1, 2, "foo", "arrCustom", "objCustom"
    }
    
    for (let i in iterable) {
        if (iterable.hasOwnProperty(i)) {
            console.log(i); 
            // 依次打印 0, 1, 2, "foo"
        }
    }
    
    // for of
    for (let i of iterable) {
        console.log(i); 
        // 依次打印 3, 5, 9
    }
    

    forEach,for in,for of三者区别:

    forEach来遍历数组,for in 遍历对象或json,for of数组对象都可以遍历,for in 循环出的是key,for of 循环出的是value。

    const promise = new Promise((resolve, reject) => {
        console.log(1);
        resolve();
        console.log(2);
    })
    
    promise.then(() => {
        console.log(3);
    })
    
    console.log(4);
    
    1 2 4 3
    

    Promise.then() 内部的代码在 当次 事件循环的 结尾 立刻执行

    关于目前文章内容即涉及前端,PHP知识点,如果有兴趣即可关注,很荣幸,能被您发现,真是慧眼识英!也感谢您的关注,在未来的日子里,希望能够一直默默的支持我,我也会努力写出更多优秀的作品。我们一起成长,从零基础学编程,将 Web前端领域、数据结构与算法、网络原理等通俗易懂的呈现给小伙伴。分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯。

    推荐阅读

    1、你知道多少this,new,bind,call,apply?那我告诉你

    2、为什么学习JavaScript设计模式,因为它是核心

    3、一篇文章把你带入到JavaScript中的闭包与高级函数


    意见反馈:
    若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理。


    感谢阅读,原创不易,喜欢就点个赞吧,这是我写作最大的动力。

    欢迎关注达达的简书!

    这是一个有质量,有态度的博客

    博客

  • 相关阅读:
    ($children,$refs,$parent)的使用
    watch监听变化
    vue组件间通信六种方式(完整版)
    CSS水平垂直居中常见方法总结2
    CSS水平垂直居中常见方法总结
    Uncaught SyntaxError: Unexpected identifier 报错 import Vue from 'vue';
    前端跳槽面试必备
    防止重复发送Ajax请求问题
    JQuery中的$().each 以及 $.each的区别
    数组中的forEach和map的区别
  • 原文地址:https://www.cnblogs.com/dashucoding/p/11875370.html
Copyright © 2020-2023  润新知