zoukankan      html  css  js  c++  java
  • 大厂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中的闭包与高级函数

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

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

    欢迎关注达达的简书!

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

    博客

  • 相关阅读:
    一个简单XQuery查询的例子
    《Microsoft Sql server 2008 Internals》读书笔记第七章Special Storage(1)
    《Microsoft Sql server 2008 Internals》读书笔记第八章The Query Optimizer(4)
    《Microsoft Sql server 2008 Internal》读书笔记第七章Special Storage(4)
    SQL Server中SMO备份数据库进度条不显示?
    《Microsoft Sql server 2008 Internal》读书笔记第七章Special Storage(5)
    《Microsoft Sql server 2008 Internal》读书笔记第七章Special Storage(3)
    《Microsoft Sql server 2008 Internal》读书笔记第八章The Query Optimizer(2)
    省市三级联动的DropDownList+Ajax的三种框架(aspnet/Jquery/ExtJs)示例
    FireFox意外崩溃时的手工恢复命令
  • 原文地址:https://www.cnblogs.com/dashucoding/p/11932243.html
Copyright © 2011-2022 走看看