精华内容
下载资源
问答
  • ES6面试题

    千次阅读 2020-04-25 17:38:04
    1.箭头函数中的this指向定义时当前周围的作用...3. es6中和原型一样用来继承的class和继承是怎么实现的? 贴上 class Point { // ... } typeof Point // "function",类的数据类型就是函数 Point === Point.p...

    1.箭头函数中的this指向定义时当前周围的作用域;

    2.如果使用标记模板字面量,第一个参数的值总是字符串的数组。其余的参数获取的是传递的表达式的值;

    3. es6中和原型一样用来继承的class和继承是怎么实现的?

    贴上

     

    class Point {
      // ...
    }
    typeof Point // "function",类的数据类型就是函数
    Point === Point.prototype.constructor // true,类本身就指向构造函数
    
    

    使用的时候,也是直接对类使用new命令,跟构造函数的用法完全一致,不使用new会报错。

    类的所有方法都定义在类的prototype属性上面。

     

    class Point {
      constructor() {    // ...  }
      toString() {    // ...  }
      toValue() {    // ...  }
    }
    // 等同于
    Point.prototype = {
      constructor() {},
      toString() {},
      toValue() {},
    };
    
    //Object.assign方法可以很方便地一次向类添加多个方法
    Object.assign(Point.prototype, {
      toString(){},
      toValue(){}
    });
    
    

    类不存在变量提升(hoist),这一点与 ES5 完全不同。

    Class 可以通过extends关键字实现继承。

     

    class ColorPoint extends Point {}//ColorPoint继承了Point类所有的属性和方法
    
    

    super关键字,表示父类的构造函数,用来新建父类的this对象。

    子类必须在constructor方法中调用super方法,否则新建实例时会报错,只有调用super之后,才可以使用this关键字。

    区别:

    ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面Parent.apply(this))。

    ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this

    Class 作为构造函数的语法糖,同时有prototype属性和__proto__属性,因此同时存在两条继承链。

    (1)子类的_proto_属性,表示构造函数的继承,总是指向父类。

    (2)子类prototype属性的_proto_属性,表示方法的继承,总是指向父类的prototype属性。

    子类实例的__proto__属性的__proto__属性,指向父类实例的__proto__属性。也就是说,子类的原型的原型,是父类的原型。

    Object.getPrototypeOf方法判断,一个类是否继承了另一个类。

    4. es6中const、let、var之间的区别?

    1. var定义的变量,作用域是整个封闭函数,是全域的;

      let定义的变量,作用域是在块级或者字块中;

    2. 变量提升:不论通过var声明的变量处于当前作用于的第几行,都会提升到作用域的最顶部

      而let声明的变量不会在顶部初始化,凡是在let声明之前使用该变量都会报错(引用错误ReferenceError);

    3. 只要块级作用域内存在let,它所声明的变量就会绑定在这个区域

    4. let不允许在相同作用域内重复声明(报错同时使用var和let,两个let)

    const用来专门声明一个常量,它跟let一样作用于块级作用域没有变量提升重复声明会报错,不同的是const声明的常量不可改变,声明时必须初始化(赋值),const定义的对象可变。

    const使用场景很广,包括常量、配置项以及引用的组件、定义的 “大部分” 中间变量等,都应该以cosnt做定义。反之就 let 而言,他的使用场景应该是相对较少的,我们只会在 loop(for,while 循环)及少量必须重定义的变量上用到他。

    5. 大致讲一下ES6新特性;

    ① 箭头函数

    ② 增加了对类的支持class关键字;继承:class Programmer extends Animal

    ③ 增强了对象字面量:可以在对象字面量里面定义原型

    __proto__: human, //设置此对象的原型为human,相当于继承human

    定义方法可以不用function关键字

    work() {console.log('working...'); }

    ④ 字符串模板:反引号 ` 来创建字符串;

    ⑤ 解构:[name,age]=[Alice,’male’,’secrect’];//数组解构;

    ⑥ 参数默认值,不定参数,拓展参数:

    ​ 参数默认值:在定义函数的时候指定参数的默认值

     

    function sayHello2(name='dude'){
        console.log(`Hello ${name}`);
    }
    
    

    ​ 不定参数:在函数中使用命名参数同时接收不定数量的未命名参数,三个句点后跟代表所有不定参数的变量名

     

    function add(...x){
        return x.reduce((m,n)=>m+n);
    }
    
    

    ​ 拓展参数:允许传递数组或者类数组直接做为函数的参数而不用通过apply。

     

    var people=['Wayou','John','Sherlock'];
    sayHello(...people);//输出:Hello Wayou,John,Sherlock
    
    

    ⑦ let 与const关键字

    ⑧ for of值遍历:for in 循环用于遍历数组,类数组或对象,for of循环功能相似,不同的是每次循环它提供的不是序号而是值

    for…of 循环的i代表的是value(多用于数组),for…in 循环的是key(多用于对象

    ⑨ iterator, generator:iterator拥有一个next方法;generator是一种特殊的iterator,通过function来声明的,yield 关键字*可以暂停函数的执行,随后可以再进进入函数继续执行。

    ⑩ 模块module

     

    // point.js
    module "point" {
        export class Point {
            constructor (x, y) {
                public x = x;
                public y = y;
            } 
        }
    }
    
    // myapp.js
    module point from "/point.js";  //声明引用的模块
    import Point from "point";      //可以看出,尽管声明了引用的模块,还是可以通过指定需要的部分进行导入
    var origin = new Point(0, 0);
    console.log(origin);
    
    

    ① Map,Set 和 WeakMap,WeakSet:提供了更加方便的获取属性值的方法,不用像以前一样用hasOwnProperty来检查某个属性是属于原型链上还是当前对象的。同时,在进行属性值添加与获取时有专门的get,set 方法。WeakMap,WeakSet更加安全,作为属性键的对象如果没有别的变量在引用它们,则会被回收释放掉。

    ② Proxies:监听对象身上发生了什么事情,并在这些事情发生后执行一些相应的操作。

    ③ Symbols:是一种基本类型,不是一个对象。可以用symbol这种值来做为对象的键。

    ④ Math,Number,String,Object 的新API;

    ⑤ Promises:处理异步操作的一种模式,then()

    6.Object.assign浅拷贝

    Object.assign方法用来将源对象(source)的所有可枚举属性,复制到目标对象(target)。

    Object.assign方法实行的是浅拷贝,而不是深拷贝。

    参数

    ​ 它至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象。

    ​ 如果只有一个参数,Object.assign会直接返回该参数。

    ​ 如果该参数不是对象,则会先转成对象,然后返回

    ​ 由于undefined和null无法转成对象,所以如果它们作为参数,就会报错

    注:如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性

    注意:如果非对象参数出现在源对象的位置(即非首参数),那么处理规则有所不同。首先,这些参数都会转成对象,如果无法转成对象,就会跳过。这意味着, 如果undefined和null不在首参数,就不会报错。其他类型的值(即数值、字符串和布尔值)不在首参数,也不会报错。但是,除了字符串会以数组形式,拷贝入目标对象,其他值都不会产生效果。

    对于嵌套的对象,Object.assign的处理方法是替换,而不是添加。

     

    var target = { a: { b: 'c', d: 'e' } }
    var source = { a: { b: 'hello' } } 
    Object.assign(target, source); /*{ a: { b: 'hello' } } */
    
    

    注意,Object.assign可以用来处理数组,但是会把数组视为对象

     

    console.log(Object.assign([1, 2, 3], [4, 5]));
    /*[4,5,3] 4覆盖1,5覆盖2,因为它们在数组的同一位置,所以就对应位置覆盖了*/
    
    

    如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。

     

    var object1 = { a: { b: 1 } };
    var object2 = Object.assign({}, object1); 
    object1.a.b = 2; 
    console.log(object2.a.b);
    
    

    用途

    为对象添加属性;为对象添加方法;克隆对象;合并多个对象;为属性指定默认值

     

    //克隆对象:将原始对象拷贝到一个空对象,就得到了原始对象的克隆
    function copyFnc(origin) {
        return Object.assign({}, origin)
    } 
    var sur = { a: 1, b: 2 };
    console.log(copyFnc(sur));
    
    

    采用这种方法克隆,只能克隆原始对象自身的值,不能克隆它继承的值。如果想要保持继承链,可以采用下面的代码。

     

    /*克隆对象:在JS里子类利用Object.getPrototypeOf去调用父类方法,用来获取对象的原型*/
    function clone(origin) {
        let originProto = Object.getPrototypeOf(origin);
        return Object.assign(Object.create(originProto), origin);
    }
    
    

     

    //多个对象合并到某个对象
    const merge = (target, ...sources) => Object.assign(target, ...sources);
    //多个对象合并到新对象
    const merge = (...sources) => Object.assign({}, ...sources);
    
    const o1 = { a: 1 };
    const o2 = { b: 2 };
    const o3 = { c: 3 };
    const obj = Object.assign(o1, o2, o3);// { a: 1, b: 2, c: 3 }
    
    

    7.箭头函数和一般函数有什么区别?

    定义箭头函在数语法上要比普通函数简洁得多。箭头函数省去了function关键字,采用箭头=>来定义函数。

    基本语法:关于箭头函数的参数:

    ① 如果箭头函数没有参数,直接写一个空括号即可。

    ② 如果箭头函数的参数只有一个,也可以省去包裹参数的括号

    ③ 如果箭头函数有多个参数,将参数依次用逗号(,)分隔,包裹在括号中即可。

    基本语法:关于箭头函数的函数体:

    ① 如果箭头函数的函数体只有一句代码,就是简单返回某个变量或者返回一个简单的JS表达式,可以省去函数体的大括号{ }。

    ② 如果箭头函数的函数体只有一句代码,就是返回一个对象,用小括号包裹要返回的对象,不报错

     

    let getTempItem = id => ({ id: id, name: "Temp" });
    
    

    ③ 如果箭头函数的函数体只有一条语句并且不需要返回值(最常见是调用一个函数),可以给这条语句前面加一个void关键字

     

    let fn = () => void doesNotReturn();
    //用来简化回调函数:
    [1,2,3].map(function (x) {return x * x;});// 正常函数写法
    [1,2,3].map(x => x * x);// 箭头函数写法
    var result = [2, 5, 1, 4, 3].sort(function (a, b) {  return a - b;});// 正常函数写法
    var result = [2, 5, 1, 4, 3].sort((a, b) => a - b);// 箭头函数写法
    
    

    区别

    1、语法更加简洁、清晰

    2、箭头函数不会创建自己的this,它会捕获自己在定义时(注意,是定义时,不是调用时)所处的外层执行环境的this,并继承这个this值。所以,箭头函数中this的指向在它被定义的时候就已经确定了,之后永远不会改变。

    3、箭头函数继承而来的this指向永远不变

    4、.call()/.apply()/.bind()无法改变箭头函数中this的指向(但是也不会报错)

    5、箭头函数不能作为构造函数使用:因为箭头函数没有自己的this,它的this其实是继承了外层执行环境中的this,且this指向永远不会随在哪里调用、被谁调用而改变,所以箭头函数不能作为构造函数使用,或者说构造函数不能定义成箭头函数,否则用new调用时会报错!

    6、箭头函数没有自己的arguments:在箭头函数中访问arguments实际上获得的是外层局部(函数)执行环境中的值。可以在箭头函数中使用rest参数代替arguments对象,来访问箭头函数的参数列表

    7、箭头函数没有原型prototype

     

    let sayHi = () => {    console.log('Hello World !')};
    console.log(sayHi.prototype); // undefined
    
    

    8.Promise、async await 的使用?

    promise和async/await都是异步方案,promise是es6的新特性,而async/await是es7新出的特性。

    Promise是一个对象,可以实现链式的写法来实现同步异步操作,

    then()…catch()…,then表示上一个promise执行完后执行,如果出现错误就会传入catch里面,通常这么写:

     

    var pro = new promise (function(resolve,reject){
        resolve("success");
        console.log("afterresolve");
        reject("error");
    });
    pro.then(result=>{
        console.log(result);
    });
    pro.catch(result=>{
        console.log(result);
    })
    //afterresolve success
    
    

    resolve下面的语句其实是可以执行的,那么为什么reject的状态信息在下面没有接受到呢?

    这就是因为Promise对象的特点:状态的凝固。new出一个Promise对象时,这个对象的起始状态就是Pending状态,在根据resolve或reject返回Fulfilled状态/Rejected状态。

     

    new Promise((resolve, reject) => {
        var param = 'Promise 执行完后返回的数据';
        var error = 'Promise 异步执行异常';
        if( error ) {
            reject(new Error('Promise 异步执行异常'));
        } else {
            resolve(param);
        }
    }).then((res) => {
    //  这里res就是Promise中的param参数
        console.log(res);  //  Promise 执行完后返回的数据
        var param = '第一个then 执行完后返回的数据';
        return param;
    }).then((res) => {
    //  这里的res就不是Promise中resolve的param参数了,而是上一个then中的返回值
        console.log(res);  //  第一个then 执行完后返回的数据
    }).catch((error) => {
    //  这里是Promise执行reject方法中的参数
        console.log(error); //  Promise 异步执行异常
    });
    
    

    第一个then()触发条件:是 Promise() 实例化时resolve()触发,resolve(param);

    第二个及以后的then() 触发条件是第一个then()执行完成,并且将return值作为下一个then的参数;

    catch()触发条件是执行了reject(),用于指定发生错误的时候的回调函数。

    需要注意的是resolve与reject只能执行一个。也就是说如果不加入判断的话,某一个先执行了,后面的就自动忽略了。

    对于async/await来说是基于promise的,他可以让我们更加优雅的写出代码,而替代then()的写法;

    需要注意的就是await是强制把异步变成了同步,这一句代码执行完,才会执行下一句

    await必须用在async方法中;处理错误的方法:

    展开全文
  • 2021-10-16 ES6面试题

    2021-10-16 23:00:45
    一、多选 1、关于剩余参数的使用,正确的是?AB A、function fn(name, …args) {…} B、function fn(…args) {…} C、function fn(…args, name) {…} D、function fn(…name, …args) {…} 答案:AB C问题:剩余...

    一、多选题

    1、关于剩余参数的使用,正确的是?AB
    A、function fn(name, …args) {…}
    B、function fn(…args) {…}
    C、function fn(…args, name) {…}
    D、function fn(…name, …args) {…}
    答案:AB
    C问题:剩余参数只能出现在参数列表的最后一个位置
    D问题:函数的参数中,剩余参数只能有一个

    2、声明类型的语法,正确的是?BC
    A、class Person() {}
    B、class Person {}
    C、function Person () {}
    D、function Person {}
    答案:BC
    A问题,class语法中没有类型名称后面的括号
    D问题,function语法中,类型名称后面包含一个括号,使用函数模拟的类型

    3、关于ES6中constructor()的描述,正确的是?
    A、类型中的构造函数,用来在创建对象的同时初始化对象属性
    B、创建指定类型的对象时,会自动调用执行
    C、类型中的构造函数,需要手工调用执行
    D、类型中的普通函数,需要手工调用执行
    答案:ABD
    C问题:构造函数是创建对象的时候自动执行,不需要手工调用

    4、箭头函数的使用,操作语法正确的是?
    A、let fn = ()-> console.log(“hello”)
    B、let fn = ()=> console.log(“hello”)
    C、let fn = name -> console.log(“params”)
    D、let fn = name => console.log(“params”)
    答案:BD
    AC问题:箭头函数中使用错误了箭头符号

    5、箭头函数中的参数的使用,正确的是?
    A、let func = name, age => console.log(名称:${name}, 年龄:${age})
    B、let func = (name, age) => console.log(名称:${name}, 年龄:${age})
    C、let func = name, age => {console.log(名称:${name}, 年龄:${age})}
    D、let func = (name, age) => {console.log(名称:${name}, 年龄:${age})}
    答案:BD
    AC问题:多个参数出现时,不能省略括号

    6、箭头函数中返回值的操作,正确的是?
    A、let fc = (x, y) => {x++; y++; return x + y;}
    B、let fc = (x, y) => {x++; y++; x + y;}
    C、let fc = (x, y) => return x + y
    D、let fc = (x, y) => x + y
    答案:AD
    B问题:函数代码部分,带有花括号的情况下需要通过return才能返回数据
    C问题:函数代码部分,省略花括号的情况下不需要添加return关键词可以直接返回数据

    7、关于类和对象的描述,正确的是?
    A、类表示类型的意思
    B、对象是包含数据的、实际存在的物体
    C、一个类型只能创建一个对象
    D、多个对象可以属于一个类型
    ABD
    C问题:一个类型可以创建多个互相独立的对象

    8、ES6类型中,对于静态属性和静态函数的操作正确的是?
    A、静态属性是声明在类型内部、类型方法外部的、使用let声明的变量
    B、静态属性是声明在类型内部、类型方法外部的、使用static声明的变量
    C、静态属性是属于类型的属性,所以只能被类型名称调用
    D、静态属性是属于类型的属性,所以可以被类型名称和该类型创建的所有对象调用
    BC

    9、关于函数中使用默认值,操作方式正确的是?
    A、function fct(name) { name = name || ‘default’;… }
    B、function fct(name) {name = “default”;…}
    C、function fct(name=“defeult”) {…}
    D、let fct = (name=“default”)=> {…}
    ACD
    A-原生JS中默认值的添加
    B-数据覆盖,不是默认值
    C-ES6语法中给形式参数添加默认值
    D-箭头函数中使用ES6语法的默认值

    10、面向对象的继承关系中,正确的操作语法是?
    A、class Student extends Person {…}
    B、class Student(Person) {…}
    C、class Student extends Person() {…}
    D、class Student extends Person, Job {…}
    A
    B问题:继承语法,不是类型后面添加括号的语法
    C问题:继承的父类不能添加括号
    D问题:JS中的继承是单继承机制,不能同时继承多个类型

    二、简答题

    1、观察下面的代码,最终控制台会输出什么结果呢?请说明原因?

    let name = "TOM"
    function fn() {
    console.log(name)   // ? 
    let name = "JERRY"
    }
    fn()
    

    输出错误,let声明的变量存在暂时性死区,变量声明之前不能使用该变量

    2、梳理下面的代码,最终输出的数据是什么呢?请说明原因?

    let person = {'pName': 'OFFCN', 'pAge': 20, 'pGender': 'male'}
    let {pName: name, pAge} = person
    console.log(name) 	// ①
    console.log(pName)	// ② 
    console.log(pAge)	// ③
    

    ① 输出OFFCN,别名输出,给pName的值赋值到了一个名称为name的变量中
    ② 错误,一旦出现了别名赋值,原来的属性名称就不能使用
    ③ 20
    解构赋值中,如果给一个属性添加了别名,属性名称就不能再使用了,所以pName报错

    3、解析下面的代码,最终输出什么结果?为什么?

    for ( var i = 0; i < 10; i ++ ) {
    setTimeout(function() {
        console.log(i);  // ① 10, 10, 10, 10, 10, 10, 10...
    		})
    	}
    for ( let j = 0; j < 10; j ++ ) {
    setTimeout(function() {
        console.log(j);  // ②
    		})
    	}
    

    ① 10,var声明的变量的作用域只有全局和局部,for循环中多次循环使用的是同一个作用域空间,setTimeout()延时函数会在循环全部执行完成后输出,循环中最后一次判断时i=10<10跳出循环,此时最终i的值是10;
    ② 0.1.2.3…9,let声明的变量存在块级作用域,for循环每次循环都是一个独立的作用域,延时函数执行的时候相当于在10个不同的作用域中执行,最终输出了差异化的数据

    编程题
    1、公司要给员工涨薪,并重新记录到一个新的变量中,请编写代码实现

    // 公司员工数据
    let emps = [
    {name: 'Jams Gosling', job: 'Java工程师', salary: 12000},
    {name: 'Guido Van Rossum', job: 'Python工程师', salary: 11000},
    {name: 'Brendan Eich', job: 'JavaScript工程师', salary: 12500},
    {name: 'John Resig', job: '前端工程师', salary: 12800},
    {name: 'Dennis Ritchie', job: 'C工程师', salary: 9000},
    {name: 'Bjarne Stroustrup', job: 'C++工程师', salary: 10000},
    {name: 'Tim Berners Lee', job: 'WEB工程师', salary: 13000},
    {name: 'Alan Cooper', job: 'VB工程师', salary: 8000},
    {name: 'Rob Pick', job: 'Go工程师', salary: 13000}
    ]
    

    请编写代码实现员工的涨薪操作:

    var newEmps = emps.map(value=> {
        return {
    		...value,
           salary: value.salary + 1000
    		}
    	})
    console.log(newEmps) // 涨薪后的数组
    
    展开全文
  • 前端es6面试题

    2020-11-30 20:42:07
    1.声明变量: let 不允许在相同作用域内,重复声明同一个变量。 const 声明一个只读的常量。一旦声明,常量的值就不能改变。 2.变量解构赋值: 默认值 默认值可以引用解构赋值的其他变量,但该变量必须已经声明。...

    1.声明变量:

    let 不允许在相同作用域内,重复声明同一个变量。
    const 声明一个只读的常量。一旦声明,常量的值就不能改变。

    2.变量解构赋值:

    默认值 默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
    对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
    解构失败,变量的值等于undefined
    字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象
    函数参数的解构也可以使用默认值。

    3.箭头函数:

    箭头函数的分类:1.单语句,单参数 2.单语句,多参数 3.多语句,多参数.

    4.Symbol

    S6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)

    5.forEach()

    forEach(): 没有返回值,本质上等同于 for 循环,对每一项执行 function 函数。即map是返回一个新数组,原数组不变,forEach 是改变原数组。

    6.Rest:

    Rest 参数接受函数的多余参数,组成一个数组,放在形参的rest参数只能写在最后,前面用…标识Spread操作符(…),也称作展开操作符,作用是将可迭代的(Iterable)对象进行展开。

    7.模板字符串:

    模板字符串使用反引号 () 来代替普通字符串中的用双引号和单引号。模板字符串可以包含特定语法(${})的占位符。占位符中的表达式和周围的文本会一起传递给一个默认函数,该函数负责将所有的部分连接起来,如果一个模板字符串由表达式开头,则该字符串被称为带标签的模板字符串,该表达式通常是一个函数,它会在模板字符串处理后被调用,在输出最终结果前,你都可以通过该函数来对模板字符串进行操作处理。在模版字符串内使用反引号(`)时,需要在它前面加转义符(\)。

    8.class:

    S6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

    9.class继承:

    Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后对其加工,加上子类自己的实例属性和方法,如果不调用super方法,子类就得不到this对象。

    10.super关键字

    super这个关键字,既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同.
    第一种情况,super作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。
    第二种情况,super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

    11.类的prototype属性和_proto_属性

    子类的_prop_属性,表示构造函数的继承,总是指向父类。
    子类prototype属性的_prop_属性,表示方法的继承,总是指向父类的prototype属性。

    12.Typeof

    typeof运算符用于判断对象的类型,但是对于一些创建的对象,它们都会返回’object’,有时我们需要判断该实例是否为某个对象的实例,那么这个时候需要用到instanceof运算符,后续记录instanceof运算符的相关用法。

    展开全文
  • 前端ES6面试题

    万次阅读 多人点赞 2019-06-15 14:43:04
    1、ES5、ES6和ES2015有什么区别? ES2015特指在2015年发布的新一代JS语言标准,ES6泛指下一代JS语言标准,包含ES2015、ES2016、ES2017、ES2018等。现阶段在绝大部分场景下,ES2015默认等同ES6。ES5泛指上一代语言...

    1、ES5、ES6和ES2015有什么区别?

    ES2015特指在2015年发布的新一代JS语言标准,ES6泛指下一代JS语言标准,包含ES2015ES2016ES2017ES2018等。现阶段在绝大部分场景下,ES2015默认等同ES6ES5泛指上一代语言标准。ES2015可以理解为ES5ES6的时间分界线

    2、babel是什么,有什么作用?

    babel是一个 ES6 转码器,可以将 ES6 代码转为 ES5 代码,以便兼容那些还没支持ES6的平台

    3、let有什么用,有了var为什么还要用let?

    ES6之前,声明变量只能用varvar方式声明变量其实是很不合理的,准确的说,是因为ES5里面没有块级作用域是很不合理的。没有块级作用域回来带很多难以理解的问题,比如for循环var变量泄露,变量覆盖等问题。let声明的变量拥有自己的块级作用域,且修复了var声明变量带来的变量提升问题。

    4、举一些ES6对String字符串类型做的常用升级优化?

    优化部分

    ES6新增了字符串模板,在拼接大段字符串时,用反斜杠()`取代以往的字符串相加的形式,能保留所有空格和换行,使得字符串拼接看起来更加直观,更加优雅

    升级部分

    ES6String原型上新增了includes()方法,用于取代传统的只能用indexOf查找包含字符的方法(indexOf返回-1表示没查到不如includes方法返回false更明确,语义更清晰), 此外还新增了startsWith(), endsWith(), padStart(),padEnd(),repeat()等方法,可方便的用于查找,补全字符串

    5、举一些ES6对Array数组类型做的常用升级优化

    优化部分

    • 数组解构赋值。ES6可以直接以let [a,b,c] = [1,2,3]形式进行变量赋值,在声明较多变量时,不用再写很多let(var),且映射关系清晰,且支持赋默认值
    • 扩展运算符。ES6新增的扩展运算符(...)(重要),可以轻松的实现数组和松散序列的相互转化,可以取代arguments对象和apply方法,轻松获取未知参数个数情况下的参数集合。(尤其是在ES5中,arguments并不是一个真正的数组,而是一个类数组的对象,但是扩展运算符的逆运算却可以返回一个真正的数组)。扩展运算符还可以轻松方便的实现数组的复制和解构赋值(let a = [2,3,4]; let b = [...a]

    升级部分

    ES6Array原型上新增了find()方法,用于取代传统的只能用indexOf查找包含数组项目的方法,且修复了indexOf查找不到NaN的bug([NaN].indexOf(NaN) === -1).此外还新增了copyWithin(),includes(), fill(),flat()等方法,可方便的用于字符串的查找,补全,转换等

    6、举一些ES6对Number数字类型做的常用升级优化

    优化部分

    ES6在Number原型上新增了isFinite(), isNaN()方法,用来取代传统的全局isFinite(), isNaN()方法检测数值是否有限、是否是NaNES5isFinite(), isNaN()方法都会先将非数值类型的参数转化为Number类型再做判断,这其实是不合理的,最造成isNaN('NaN') === true的奇怪行为--'NaN'是一个字符串,但是isNaN却说这就是NaN。而Number.isFinite()Number.isNaN()则不会有此类问题(Number.isNaN('NaN') === false)。(isFinite()同上)

    升级部分

    ES6Math对象上新增了Math.cbrt()trunc()hypot()等等较多的科学计数法运算方法,可以更加全面的进行立方根、求和立方根等等科学计算

    7、举一些ES6对Object类型做的常用升级优化?(重要)

    优化部分

    对象属性变量式声明。ES6可以直接以变量形式声明对象属性或者方法,。比传统的键值对形式声明更加简洁,更加方便,语义更加清晰

    let [apple, orange] = ['red appe', 'yellow orange'];
    let myFruits = {apple, orange};    // let myFruits = {apple: 'red appe', orange: 'yellow orange'};
    

    尤其在对象解构赋值(见优化部分b.)或者模块输出变量时,这种写法的好处体现的最为明显

    let {keys, values, entries} = Object;
    let MyOwnMethods = {keys, values, entries}; // let MyOwnMethods = {keys: keys, values: values, entries: entries}
    

    可以看到属性变量式声明属性看起来更加简洁明了。方法也可以采用简洁写法

    let es5Fun = {
        method: function(){}
    }; 
    let es6Fun = {
        method(){}
    }
    

    对象的解构赋值。 ES6对象也可以像数组解构赋值那样,进行变量的解构赋值

    let {apple, orange} = {apple: 'red appe', orange: 'yellow orange'};
    

    对象的扩展运算符(...)。 ES6对象的扩展运算符和数组扩展运算符用法本质上差别不大,毕竟数组也就是特殊的对象。对象的扩展运算符一个最常用也最好用的用处就在于可以轻松的取出一个目标对象内部全部或者部分的可遍历属性,从而进行对象的合并和分解

    let {apple, orange, ...otherFruits} = {apple: 'red apple', orange: 'yellow orange', grape: 'purple grape', peach: 'sweet peach'}; 
    // otherFruits  {grape: 'purple grape', peach: 'sweet peach'}
    // 注意: 对象的扩展运算符用在解构赋值时,扩展运算符只能用在最有一个参数(otherFruits后面不能再跟其他参数)
    let moreFruits = {watermelon: 'nice watermelon'};
    let allFruits = {apple, orange, ...otherFruits, ...moreFruits};
    

    super 关键字。ES6Class类里新增了类似this的关键字super。同this总是指向当前函数所在的对象不同,super关键字总是指向当前函数所在对象的原型对象

    升级部分

    ES6Object原型上新增了is()方法,做两个目标对象的相等比较,用来完善'==='方法。'==='方法中NaN === NaN //false其实是不合理的,Object.is修复了这个小bug(Object.is(NaN, NaN) // true)

    ES6Object原型上新增了assign()方法,用于对象新增属性或者多个对象合并

    const target = { a: 1 };
    const source1 = { b: 2 };
    const source2 = { c: 3 };
    Object.assign(target, source1, source2);
    target // {a:1, b:2, c:3}
    

    注意: assign合并的对象target只能合并source1、source2中的自身属性,并不会合并source1source2中的继承属性,也不会合并不可枚举的属性,且无法正确复制get和set属性(会直接执行get/set函数,取return的值)

    • ES6Object原型上新增了getOwnPropertyDescriptors()方法,此方法增强了ES5getOwnPropertyDescriptor()方法,可以获取指定对象所有自身属性的描述对象。结合defineProperties()方法,可以完美复制对象,包括复制getset属性
    • ES6Object原型上新增了getPrototypeOf()setPrototypeOf()方法,用来获取或设置当前对象的prototype对象。这个方法存在的意义在于,ES5中获取设置prototype对像是通过__proto__属性来实现的,然而__proto__属性并不是ES规范中的明文规定的属性,只是浏览器各大产商“私自”加上去的属性,只不过因为适用范围广而被默认使用了,再非浏览器环境中并不一定就可以使用,所以为了稳妥起见,获取或设置当前对象的prototype对象时,都应该采用ES6新增的标准用法
    • ES6Object原型上还新增了Object.keys()Object.values()Object.entries()方法,用来获取对象的所有键、所有值和所有键值对数组

    8、举一些ES6对Function函数类型做的常用升级优化?

    优化部分

    箭头函数(核心)。箭头函数是ES6核心的升级项之一,箭头函数里没有自己的this,这改变了以往JS函数中最让人难以理解的this运行机制。主要优化点

    • 箭头函数内的this指向的是函数定义时所在的对象,而不是函数执行时所在的对象。ES5函数里的this总是指向函数执行时所在的对象,这使得在很多情况下this的指向变得很难理解,尤其是非严格模式情况下,this有时候会指向全局对象,这甚至也可以归结为语言层面的bug之一。ES6的箭头函数优化了这一点,它的内部没有自己的this,这也就导致了this总是指向上一层的this,如果上一层还是箭头函数,则继续向上指,直到指向到有自己this的函数为止,并作为自己的this
    • 箭头函数不能用作构造函数,因为它没有自己的this,无法实例化
    • 也是因为箭头函数没有自己的this,所以箭头函数 内也不存在arguments对象。(可以用扩展运算符代替)
    • 函数默认赋值。ES6之前,函数的形参是无法给默认值得,只能在函数内部通过变通方法实现。ES6以更简洁更明确的方式进行函数默认赋值
    function es6Fuc (x, y = 'default') {
        console.log(x, y);
    }
    es6Fuc(4) // 4, default
    

    升级部分

    ES6新增了双冒号运算符,用来取代以往的bindcall,和apply。(浏览器暂不支持,Babel已经支持转码)

    foo::bar;
    // 等同于
    bar.bind(foo);
    
    foo::bar(...arguments);
    // 等同于
    bar.apply(foo, arguments);
    

    9、Symbol是什么,有什么作用?

    SymbolES6引入的第七种原始数据类型(说法不准确,应该是第七种数据类型,Object不是原始数据类型之一,已更正),所有Symbol()生成的值都是独一无二的,可以从根本上解决对象属性太多导致属性名冲突覆盖的问题。对象中Symbol()属性不能被for...in遍历,但是也不是私有属性

    10、Set是什么,有什么作用?

    SetES6引入的一种类似Array的新的数据结构,Set实例的成员类似于数组item成员,区别是Set实例的成员都是唯一,不重复的。这个特性可以轻松地实现数组去重

    11、Map是什么,有什么作用?

    MapES6引入的一种类似Object的新的数据结构,Map可以理解为是Object的超集,打破了以传统键值对形式定义对象,对象的key不再局限于字符串,也可以是Object。可以更加全面的描述对象的属性

    12、Proxy是什么,有什么作用?

    ProxyES6新增的一个构造函数,可以理解为JS语言的一个代理,用来改变JS默认的一些语言行为,包括拦截默认的get/set等底层方法,使得JS的使用自由度更高,可以最大限度的满足开发者的需求。比如通过拦截对象的get/set方法,可以轻松地定制自己想要的key或者value。下面的例子可以看到,随便定义一个myOwnObjkey,都可以变成自己想要的函数`

    function createMyOwnObj() {
    	//想把所有的key都变成函数,或者Promise,或者anything
    	return new Proxy({}, {
    		get(target, propKey, receiver) {
    			return new Promise((resolve, reject) => {
    				setTimeout(() => {
    					let randomBoolean = Math.random() > 0.5;
    					let Message;
    					if (randomBoolean) {
    						Message = `你的${propKey}运气不错,成功了`;
    						resolve(Message);
    					} else {
    						Message = `你的${propKey}运气不行,失败了`;
    						reject(Message);
    					}
    				}, 1000);
    			});
    		}
    	});
    }
    
    let myOwnObj = createMyOwnObj();
    
    myOwnObj.hahaha.then(result => {
    	console.log(result) //你的hahaha运气不错,成功了
    }).catch(error => {
    	console.log(error) //你的hahaha运气不行,失败了
    })
    
    myOwnObj.wuwuwu.then(result => {
    	console.log(result) //你的wuwuwu运气不错,成功了
    }).catch(error => {
    	console.log(error) //你的wuwuwu运气不行,失败了
    })
    
    

    13、Reflect是什么,有什么作用?

    ReflectES6引入的一个新的对象,他的主要作用有两点,一是将原生的一些零散分布在ObjectFunction或者全局函数里的方法(如applydeletegetset等等),统一整合到Reflect上,这样可以更加方便更加统一的管理一些原生API。其次就是因为Proxy可以改写默认的原生API,如果一旦原生API别改写可能就找不到了,所以Reflect也可以起到备份原生API的作用,使得即使原生API被改写了之后,也可以在被改写之后的API用上默认的API

    14、Promise是什么,有什么作用?

    PromiseES6引入的一个新的对象,他的主要作用是用来解决JS异步机制里,回调机制产生的“回调地狱”。它并不是什么突破性的API,只是封装了异步回调形式,使得异步回调可以写的更加优雅,可读性更高,而且可以链式调用

    15、Iterator是什么,有什么作用?(重要)

    • IteratorES6中一个很重要概念,它并不是对象,也不是任何一种数据类型。因为ES6新增了SetMap类型,他们和ArrayObject类型很像,ArrayObject都是可以遍历的,但是SetMap都不能用for循环遍历,解决这个问题有两种方案,一种是为SetMap单独新增一个用来遍历的API,另一种是为SetMapArrayObject新增一个统一的遍历API,显然,第二种更好,ES6也就顺其自然的需要一种设计标准,来统一所有可遍历类型的遍历方式。Iterator正是这样一种标准。或者说是一种规范理念
    • 就好像JavaScriptECMAScript标准的一种具体实现一样,Iterator标准的具体实现是Iterator遍历器。Iterator标准规定,所有部署了key值为[Symbol.iterator],且[Symbol.iterator]value是标准的Iterator接口函数(标准的Iterator接口函数: 该函数必须返回一个对象,且对象中包含next方法,且执行next()能返回包含value/done属性的Iterator对象)的对象,都称之为可遍历对象,next()后返回的Iterator对象也就是Iterator遍历器
    //obj就是可遍历的,因为它遵循了Iterator标准,且包含[Symbol.iterator]方法,方法函数也符合标准的Iterator接口规范。
    //obj.[Symbol.iterator]() 就是Iterator遍历器
    let obj = {
      data: [ 'hello', 'world' ],
      [Symbol.iterator]() {
        const self = this;
        let index = 0;
        return {
          next() {
            if (index < self.data.length) {
              return {
                value: self.data[index++],
                done: false
              };
            } else {
              return { value: undefined, done: true };
            }
          }
        };
      }
    };
    
    

    ES6SetMapArrayString都加上了[Symbol.iterator]方法,且[Symbol.iterator]方法函数也符合标准的Iterator接口规范,所以SetMapArrayString默认都是可以遍历的

    //Array
    let array = ['red', 'green', 'blue'];
    array[Symbol.iterator]() //Iterator遍历器
    array[Symbol.iterator]().next() //{value: "red", done: false}
    
    //String
    let string = '1122334455';
    string[Symbol.iterator]() //Iterator遍历器
    string[Symbol.iterator]().next() //{value: "1", done: false}
    
    //set
    let set = new Set(['red', 'green', 'blue']);
    set[Symbol.iterator]() //Iterator遍历器
    set[Symbol.iterator]().next() //{value: "red", done: false}
    
    //Map
    let map = new Map();
    let obj= {map: 'map'};
    map.set(obj, 'mapValue');
    map[Symbol.iterator]().next()  {value: Array(2), done: false}
    
    
    

    16、for…in 和for…of有什么区别?

    如果看到问题十六,那么就很好回答。问题十六提到了ES6统一了遍历标准,制定了可遍历对象,那么用什么方法去遍历呢?答案就是用for...of。ES6规定,有所部署了载了Iterator接口的对象(可遍历对象)都可以通过for...of去遍历,而for..in仅仅可以遍历对象

    • 这也就意味着,数组也可以用for...of遍历,这极大地方便了数组的取值,且避免了很多程序用for..in去遍历数组的恶习

    17、Generator函数是什么,有什么作用?

    • 如果说JavaScriptECMAScript标准的一种具体实现、Iterator遍历器是Iterator的具体实现,那么Generator函数可以说是Iterator接口的具体实现方式。
    • 执行Generator函数会返回一个遍历器对象,每一次Generator函数里面的yield都相当一次遍历器对象的next()方法,并且可以通过next(value)方法传入自定义的value,来改变Generator函数的行为。
    • Generator函数可以通过配合Thunk 函数更轻松更优雅的实现异步编程和控制流管理。

    18、async函数是什么,有什么作用?

    async函数可以理解为内置自动执行器的Generator函数语法糖,它配合ES6Promise近乎完美的实现了异步编程解决方案

    19、Class、extends是什么,有什么作用?

    ES6class可以看作只是一个ES5生成实例对象的构造函数的语法糖。它参考了java语言,定义了一个类的概念,让对象原型写法更加清晰,对象实例化更像是一种面向对象编程。Class类可以通过extends实现继承。它和ES5构造函数的不同点

    类的内部定义的所有方法,都是不可枚举的

    ///ES5
    function ES5Fun (x, y) {
    	this.x = x;
    	this.y = y;
    }
    ES5Fun.prototype.toString = function () {
    	 return '(' + this.x + ', ' + this.y + ')';
    }
    var p = new ES5Fun(1, 3);
    p.toString();
    Object.keys(ES5Fun.prototype); //['toString']
    
    //ES6
    class ES6Fun {
    	constructor (x, y) {
    		this.x = x;
    		this.y = y;
    	}
    	toString () {
    		return '(' + this.x + ', ' + this.y + ')';
    	}
    }
    
    Object.keys(ES6Fun.prototype); //[]
    
    
    • ES6class类必须用new命令操作,而ES5的构造函数不用new也可以执行。
    • ES6class类不存在变量提升,必须先定义class之后才能实例化,不像ES5中可以将构造函数写在实例化之后。
    • ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this

    20、module、export、import是什么,有什么作用?

    • moduleexportimportES6用来统一前端模块化方案的设计思路和实现方案。exportimport的出现统一了前端模块化的实现方案,整合规范了浏览器/服务端的模块化方法,用来取代传统的AMD/CMDrequireJSseaJScommondJS等等一系列前端模块不同的实现方案,使前端模块化更加统一规范,JS也能更加能实现大型的应用程序开发。
    • import引入的模块是静态加载(编译阶段加载)而不是动态加载(运行时加载)。
    • import引入export导出的接口值是动态绑定关系,即通过该接口,可以取到模块内部实时的值

    21、日常前端代码开发中,有哪些值得用ES6去改进的编程优化或者规范?

    • 常用箭头函数来取代var self = this;的做法。
    • 常用let取代var命令。
    • 常用数组/对象的结构赋值来命名变量,结构更清晰,语义更明确,可读性更好。
    • 在长字符串多变量组合场合,用模板字符串来取代字符串累加,能取得更好地效果和阅读体验。
    • Class类取代传统的构造函数,来生成实例化对象。
    • 在大型应用开发中,要保持module模块化开发思维,分清模块之间的关系,常用importexport方法。

    22、ES6的了解

    新增模板字符串(为JavaScript提供了简单的字符串插值功能)、箭头函数(操作符左边为输入的参数,而右边则是进行的操作以及返回的值Inputs=>outputs。)、for-of(用来遍历数据—例如数组中的值。)arguments对象可被不定参数和默认参数完美代替。ES6将promise对象纳入规范,提供了原生的Promise对象。增加了let和const命令,用来声明变量。增加了块级作用域。let命令实际上就增加了块级作用域。ES6规定,var命令和function命令声明的全局变量,属于全局对象的属性;let命令、const命令、class命令声明的全局变量,不属于全局对象的属性。。还有就是引入module模块的概念

    23、说说你对Promise的理解

    • 依照 Promise/A+ 的定义,Promise 有四种状态:
      • pending: 初始状态, 非 fulfilled 或 rejected.
      • fulfilled: 成功的操作.
      • rejected: 失败的操作.
      • settled: Promise已被fulfilled或rejected,且不是pending
    • 另外, fulfilled 与 rejected 一起合称 settled
    • Promise 对象用来进行延迟(deferred) 和异步(asynchronous ) 计算

    24、Promise 的构造函数

    • 构造一个 Promise,最基本的用法如下:
    var promise = new Promise(function(resolve, reject) {
    
            if (...) {  // succeed
    
                resolve(result);
    
            } else {   // fails
    
                reject(Error(errMessage));
    
            }
        });
    
    
    • Promise 实例拥有 then 方法(具有 then 方法的对象,通常被称为thenable)。它的使用方法如下:
    promise.then(onFulfilled, onRejected)
    
    
    • 接收两个函数作为参数,一个在 fulfilled 的时候被调用,一个在rejected的时候被调用,接收参数就是 future,onFulfilled 对应 resolve, onRejected 对应 reject

    什么是 Promise ?

    • Promise 就是一个对象,用来表示并传递异步操作的最终结果
    • Promise 最主要的交互方式:将回调函数传入 then 方法来获得最终结果或出错原因
    • Promise 代码书写上的表现:以“链式调用”代替回调函数层层嵌套(回调地狱)

    解构赋值:
    只要判定了等号两边的模式相同(解构),左边的变量就会被赋予对应的值(赋值),以前一次给一个变量赋值,解构赋值可以一次性给多个变量进行赋值。

    25、谈一谈你了解ECMAScript6的新特性?

    • 块级作用区域 let a = 1;
    • 可定义常量 const PI = 3.141592654;
    • 变量解构赋值 var [a, b, c] = [1, 2, 3];
    • 字符串的扩展(模板字符串) var sum =${a + b};
    • 数组的扩展(转换数组类型) Array.from($('li'));
    • 函数的扩展(扩展运算符) [1, 2].push(...[3, 4, 5]);
    • 对象的扩展(同值相等算法) Object.is(NaN, NaN);
    • 新增数据类型(Symbol) let uid = Symbol('uid');
    • 新增数据结构(Map) let set = new Set([1, 2, 2, 3]);
    • for…of循环 for(let val of arr){};
    • Promise对象 var promise = new Promise(func);
    • Generator函数 function* foo(x){yield x; return x*x;}
    • 引入Class(类) class Foo {}
    • 引入模块体系 export default func;
    • 引入async函数[ES7]
    async function asyncPrint(value, ms) {
          await timeout(ms);
          console.log(value)
         }
         
    
    

    26、Object.is() 与原来的比较操作符 = 的区别?

    • == 相等运算符,比较时会自动进行数据类型转换
    • === 严格相等运算符,比较时不进行隐式类型转换
    • Object.is 同值相等算法,在 === 基础上对 0 和 NaN 特别处理
    +0 === -0 //true
    NaN === NaN // false
    
    Object.is(+0, -0) // false
    Object.is(NaN, NaN) // true
    
    

    27、什么是 Babel

    • Babel 是一个 JS 编译器,自带一组 ES6 语法转化器,用于转化 JS 代码。
      这些转化器让开发者提前使用最新的 JS语法(ES6/ES7),而不用等浏览器全部兼容。
    • Babel 默认只转换新的 JS 句法(syntax),而不转换新的API。
    展开全文
  • es6面试题

    2020-08-18 20:36:08
    (1)this的值不是指向windows,而是父级 (2)不能够使用arguments对象 (3)不能构造函数(不能使用new命令) (4)不可以使用yield命令,因此箭头函数不能用作Generator函数 3.es6的模板字符串有什么新特点?...
  • ES6总结及面试题集合

    2019-10-12 17:38:52
    ES6总结及面试题集合 ES6总结及面试题集合 ES6总结及面试题集合
  • es6面试题总结

    2021-01-11 12:01:28
    故心故心故心故心小故冲啊 文章目录 ES6重要知识汇总 1.说说var、let、const之间的区别 2.ES6中数组新增了哪些扩展? 3.ES6中函数新增了哪些扩展? 4.字符串扩展 5.数值扩展 6.ES6中新增的Set、Map两种数据结构怎么...
  • ES6经典面试题

    2019-10-30 14:14:04
    ES6经典面试题
  • ES6面试题总结

    2021-08-05 09:27:35
    1. 谈谈你对 ES6 的理解,为什么要学习es6? ES6是新一代的JS语言标准,对分JS语言核心内容做了升级优化,规范了JS使用标准,新增了JS原生方法,使得JS使用更加规范,更加优雅,更适合大型应用的开发。学习ES6是成为...
  • ES6面试题总结!

    2020-08-18 14:34:58
    ES6面试题总结! 1.变量 var // 重复声明,函数级 let // 不能重复声明,块级,变量 const // 不能重复声明,块级,常量 2.箭头函数 // a.简写 // ()=>{} // i. 如果只有一个参数,()可以省略 // ii. 如果只有一...
  • ES6前端面试题整理

    千次阅读 2021-03-18 20:52:12
    ES6前端面试题整理,es5和es6的区别, ES6新增的一些特性,箭头函数,模板字符串,解构赋值,... 展开运算符,修饰器 @,Symbol,Proxy代理,使用箭头函数应注意什么?Set、Map的区别?setTimeout、Promise、Async/Await 的...
  • ES6面试题基础版

    2020-03-02 11:16:44
    ES6之前,变量声明关键字:var var的缺点: (1)var可以多次声明同一个变量–在其他编程语言是没办法想象的 var a =0; var a = 99; (2)var会造成变量提升 (function rr() { if(true) { var a = 666; } ...
  • es6面试题总结一

    2020-03-28 10:44:40
    1:es5和es6的区别,说一下你所知道的es6 es5和es6是不同标准的ECMAScript5,ES6相对于ES5 更加简洁,提高了开发效率 ES6新增的一些特性: 1)let声明变量和const声明常量,两个都有块级作用域ES5中是没有块级作用域...
  • js(Es6)面试题总结

    千次阅读 2019-10-23 09:50:55
    Es6面试 Let有块级作用域 不存在变量声明提前 不允许重复声明 声明的全局变量不会挂在到window上 const 声明一个只读的常量。一旦声明,常量的值就不能改变 有块级作用域 不存在变量声明提前 不允许重复...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,189
精华内容 6,075
关键字:

es6面试题