美文网首页
es6知识点和题目

es6知识点和题目

作者: 罂粟1995 | 来源:发表于2020-03-15 13:29 被阅读0次

    知识点:

    let和const

    暂时性死区

    let和const命令声明的变量无变量提升。如果区块中存在let和const命令,这个区块对这些命令声明的变量就形成封闭的作用域。在声明之前使用这些变量,就会报错,这就是暂时性死区。

    顶层对象

    var和function的全局声明会自动绑定到window或global对象,这时es5全局变量的一个缺陷,let和const不会。

    const命令

    const声明的变量只是引用无法修改,对象的内部结构可以改变,使用object.Freeze()可以彻底锁死某对象,需递归锁定多层级对象。

    变量的解构赋值

    一种更优雅的赋值写法。
    按照一定的模式,从数组或对象中提取值,对变量进行赋值的过程。

    数组的结构赋值
    let arr = [0,1,2];
    let [a,b,c] = arr;
    console.log(a);//0
    console.log(b);//1
    console.log(c);//2
    
    对象的解构赋值

    对象的解构赋值和数组的解构赋值其实类似,但是数组的数组成员是有序的,而对象的属性则是无序的,所以对象的解构赋值简单理解是等号的左边和右边的结构相同。

    let {name,age} = {name:'swr',age:28};
    console.log(name);//swr
    console.log(age);//28
    

    注意,对象的解构赋值是根据key值进行匹配的。

    函数参数

    首先解构赋值允许指定默认值,这为函数参数设置默认值提供基础。

    各种数据结构的扩展

    字符串

    ``表示模板字符串。

    箭头函数

    箭头函数,this的指向在函数定义时就定义好了。原因:箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。

    双冒号运算符

    代替bind,call,apply绑定this对象指向。Foo::bar(arguments)相当于bar.apply(foo,arguments)

    尾调用

    某个函数的最后一步再调用另一个函数。
    就是最后返回值为执行另一个参数return anotherFunction(),而return anotherFunction()+1不属于尾调用,因为在执行完anotherFunction后还需要+1。尾调用的优势在return后,可以释放当前函数执行所需要的一切资源空间。
    例:

        function a(x){
             return b(x);
        }
    
    尾递归

    在一个尾调用中,如果函数最后的尾调用位置上是这个函数本身,则被称为尾递归。

    对象

    Object.assign:合并对象,把多个对象合并到第一个对象上。
    Object.create:以某原型,生成一个新对象。可选第二个参数,为属性描述符。
    Object.getPrototypeOf、Object.setPrototypeOf:获取和设置对象的原型属性proto
    Object.getOwnPropertyDescriptors:获取对象的属性信息,包括value,writable,enumerable,configurable。
    ES6允许字面量定义对象时,用表达式作为属性名,把表达式放在方括号内。

    const propKey = 'foo';
    
    const obj = {
      [propKey]: true,
      ['a' + 'bc']: 123
    };
    obj // { foo: true, abc: 123 }
    

    Promise

    Promise是异步编程的解决方案,是es6的原生对象。有三种状态:pending-进行中,resolved-已成功,reject-已失败。

    宏任务与微任务

    js的执行机制是事件循环机制(Event Loop),js有同步任务和异步任务,同步任务在主线程中排队执行,异步任务在事件队列中等待执行,主线程中的同步任务执行完毕时,系统才会读取事件队列中的异步任务执行。在es6中,又新增了宏任务与微任务的概念。
    所有任务分为宏任务(macrotask )和微任务(microtask ) 两种。

    MacroTask(宏任务):* script全部代码、setTimeoutsetIntervalsetImmediateI/OUI Rendering

    MicroTask(微任务):* Process.nextTick(Node独有)PromiseMutationObserver

    在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首先在宏任务的队列中取出第一个任务,执行完毕后取出微任务队列中的所有任务顺序执行;之后再取宏任务,周而复始,直至两个队列的任务都取完。

    题目:

    题目1:

       var tmp = 123;
       if(true){
           tmp = 'abc';
           let tmp;
       }
    
       tmp='abc'能否定义成功?
    

    Answer:不能,会抛出错误,let将tmp变量绑定在{}代码块之内,外部的tmp声明无效,tem='abc'处在死区,所以报错。

    题目2:

      typeof undeclared_variable;
      if(true){
         typeof tmp;
         let tmp;
         console.log(tmp);
      }
    
      typeof能否运行成功?console输出什么?
    

    Answer:第一个typeof的值是undefined,第二个typeof抛出错误,console输出undefined。

    题目3:

     var a = 1;
     console.log(Window.a);
     let b = 1;
     console.log(Window.b);
    
    分别输出什么?
    

    Answer:1,Undefined

    题目4:

    const定义的对象属性是否可以改变?
    

    Answer:当const定义的是值类型(普通类型)变量时,其值确实不能修改;但当const定义的是引用类型(数组或对象)变量时,其属性值是可变的,因为const实际上保证的,并不是变量的值不变,而是变量指向的那个内存地址所保存的数据不得改动。对于值类型的数据,值就保存在变量指向的那个内存地址中,所以此时const定义的就是常量,不可以改变。但对于引用类型来说,变量指向的那个内存地址中存放的是指向实际数据的指针,const只能保证这个指针是固定的,而不能保证它指向的数据也是不变的。
    如果想让对象的属性值不可改变,需要使用object.freeze()锁死:
    let cc {'name':'eu','age':12};
    object.freeze(cc);
    cc.age = 15;
    console.log(cc.age);
    输出:12

    题目5:

       let {newName:nm,oldName:om} = {oldName:'小王',newName:'老王'}
       console.log(nm); 
       console.log(om);
    
       分别输出什么?
    

    Answer:老王,小王

    题目6:

      let {newName:nm='小李',oldName:om} = {oldName:'小王'}
      console.log(nm);
      console.log(om);
    
      分别输出什么?
    

    Answer:小李,小王

    题目7:

       let {
              newName:nm='小李',
              oldName:om;midName:'中间人'
            } = {
                   oldName:'小王',
                   newName:null,
                   midName:undefined
                }
          console.log(nm);
          console.log(om);
          console.log(mn);
    
       输出什么?
    

    Answer:null,小王,中间人

    题目8:

    let tree = {
      root: {
        leaf: {
           left: 5,
           right:5
        }
      }
    }
    let {root:{leaf:{left}}} = tree;
    console.log(left);
    
    输出?
    

    Answer:5
    相当于{left} = {left:5,right:5}

    题目9:

       var a = 1;
       var b = 3;
       let [a,b] = [b,a];
       console.log(a);
       console.log(b);
    
       输出结果是?
    

    Answer:3,1
    相当于[a,b] = [3,1],交换两个变量的值可以用到这段代码。

    题目10:

    var [a,...b] = [1,2,3];
    console.log(a);
    console.log(b);
    
    输出什么?
    

    Answer:1,[2,3]
    解构一个数组时,可以使用剩余模式,将数组剩余部份赋值给一个变量。

    题目11:

    用尾递归实现阶乘。
    

    Answer:

    function fact(n,r){
       if(n < 0){
           return 1*r;
       }else{
           return fact(n-1,r*n);
       }
    }
    

    计算过程:
    第一轮:fact(6,1)
    第二轮:fact(5,6)
    第三轮:fact(4,30)
    第四轮:fact(3,120)
    第五轮:fact(2,360)
    第六轮:fact(1,720)
    返回:720

    题目12:

    通过object.defineproperty的set和get实现一个数据的绑定。例如输入框输入的值即时显示在p标签内部。
    

    Answer:

    <html>
    <head></head>
    <body>
         <input type="text" id="input">
         <p id="p"></p>
    </body>
     
    <script>
        
            var obj = {};
            Object.defineProperty(obj,"name",{
                get:function(){
                    return name;
                },
                set:function(value){
                    document.getElementById("input").value = value;
                    document.getElementById("p").innerHTML = value;
                }
            });
    
            var input = document.getElementById("input");
            input.addEventListener("input",function(event){
                var text = event.target.value;
                obj.name = text;
            });
    
    </script>
    
    </body>
    </html>
    

    题目13:

    实现函数的链式调用 a().b().c()。当然也可以b().c().a()
    

    Answer:

    function a() {
        console.log('a')
        this.b = function () {
            console.log('b')
            return this
        }
        this.c = function () {
            console.log('c')
            return this
        }
        return this
    }
    
    a().b().c()
    

    题目14:

    使用Promise封装的ajax。
    

    Answer:

    const getJSON = function(url) {
       const promise = new Promise((resolve, reject) => {
          const client = new XMLHttpRequest();
          client.open("GET", url, false);//false-异步
          client.onreadystatechange = function() {
          //函数异步执行,实现每次变化都监听readyState的状态变化
          if (this.readyState == 4) {//请求完成
             if (this.status === 200) {
                resolve(this.response);
             } else {
                reject(new Error(this.statusText));
             }
          };
        }
        client.responseType = "json";
        client.setRequestHeader("Accept", "application/json");
        client.send();//请求参数
      });
      return promise;
    };
    
    getJSON("/posts.json").then(function(json) {
      console.log('Contents: ' + json);
    }, function(error) {
      console.log('出错了'+ error);
    });
    

    题目15

    红灯3秒亮一次,绿灯1秒亮一次,黄灯2秒亮一次;如何让三个灯不断交替重复亮灯?
    

    Answer:

    function red() {
        console.log('red');
    }
    function green() {
        console.log('green');
    }
    function yellow() {
        console.log('yellow');
    }
    
    var light = function (timmer, cb) {
        return new Promise(function (resolve, reject) {
            setTimeout(function () {
                cb();
                resolve();
            }, timmer);
        });
    };
    
    var step = function () {
        Promise.resolve().then(function () {
            return light(3000, red);
        }).then(function () {
            return light(2000, green);
        }).then(function () {
            return light(1000, yellow);
        }).then(function () {
            step();
        });
    }
    
    step();
    

    题目16:

    以下代码输出什么?
    
    const first = () => (new Promise((resolve, reject) => {
        console.log(3);
        let p = new Promise((resolve, reject) => {
            console.log(7);
            setTimeout(() => {
                console.log(5);
                resolve(6);
            }, 0)
            resolve(1);
        });
        resolve(2);
        p.then((arg) => {
            console.log(arg);
        });
    
    }));
    
    first().then((arg) => {
        console.log(arg);
    });
    console.log(4);
    

    Answer: 3,7,4,1,2,5
    考察:js事件循环机制、宏任务与微任务。

    题目17:

    promise.all与promise.race的区别。
    

    Anwser:promise.all接收一个函数数组,返回值为promise对象,函数并行执行,如果执行成功,在then中接收一个返回值数组;如果执行失败,返回最快失败的函数的reject。promise.race与promise.all相似,不同的是,执行成功后,它在then中接收最快执行完毕的函数的返回值。

    题目18:

    封装一个异步加载图片的方法。
    

    Answer:

    function loadImageAsync(url) {
        return new Promise(function(resolve,reject) {
            var image = new Image();
            image.onload = function() {
                resolve(image) 
            };
            image.onerror = function() {
                reject(new Error('Could not load image at' + url));
            };
            image.src = url;
         });
    } 
    

    题目19:

    箭头函数作用域?箭头函数与function的区别在哪?
    

    Answer:箭头函数的作用域指向定义变量时所在的作用域。箭头函数与function的主要区别在于this绑定的时间。Function的this,是在执行的时候进行绑定;箭头函数的this,是在声明的时候进行绑定,使用箭头函数可以避免指向不明确的问题。

    相关文章

      网友评论

          本文标题:es6知识点和题目

          本文链接:https://www.haomeiwen.com/subject/eutfehtx.html