ES6和ES5的区别、ES6新特性、Promise.all()用法简记、JavaScript事件代理(事件委托)、值类型和引用类型的区别、回流与 重绘——面试篇

目录

es5和es6的区别

var、let、const初始化变量的区别

使用箭头函数要注意事项

for of 与 for in 的区别

Promise.all()用法简记

解决promise失败不返回结果

 封装catch方法(失败结果也接收)

 只接收成功值方法

JavaScript事件代理(事件委托)

基本概念

值类型和引用类型的区别

1、 javascript中变量类型分为值类型(基本数据类型)和引用类型

2、 值类型和引用类型的区别

回流 与 重绘

回流

 重绘 

 何时发生回流重绘 

减少回流和重绘


es5和es6的区别

ES6 2015 年推出的一个新的版本、这个版本相对于 ES5 的语法做了很多的优化、例如:新增了 let 、 const 。let和 const 具有块级作用域,不存在变量提升的问题。新增了箭头函数,简化了定义函数的写法,同时可以巧用箭头函数的this 、(注意箭头函数本身没有 this, 它的 this 取决于外部的环境),新增了 promise 解决了回调地域的问题,新增了模块化、利用import export 来实现导入、导出。新增了结构赋值, ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构 (Destructuring )。新增了 class 类的概念,它类似于对象。
  1. 声明方式let声明变量和const声明常量,两个都有块级作用域ES5中是没有块级作用域的,并且var有变量提升,在let中,使用的变量一定要进行声明。
  2. 箭头函数ES6中的函数定义不再使用关键字function(),而是利用了()=>来进行定义。
  3. 模板字符串模板字符串是增强版的字符串,用反引号(`)标识,可以当作普通字符串使用,也可以用来定义多行字符串。
  4. 解构赋值ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值。
  5. ... 扩展运算符可以将数组或对象里面的值展开;还可以将多个值收集为一个变量。
  6. for of 是ES6新增的循环方法。
  7. promise 解决回掉地狱
  8. 模块化 import export 导入导出
  9. class类 .....

var、let、const初始化变量的区别

  1. var存在变量提升,而let和const没有(let和const存在暂时性死区)
  2. 作用域的限制:var不受作用域限制,而let和const受当前作用域限制
  3. 重复声明:var声明变量可以重复,而let和const不可以
  4. const声明的是常量,一定要有初始值,否则会报错;不能更改,但是可以更改对象内部属性

使用箭头函数要注意事项

(1)用了箭头函数,this就不是指向window,而是父级(指向是可变的)
(2)不能够使用arguments对象
(3)不能用作构造函数,这就是说不能够使用new命令,否则会抛出一个错误
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数

for of 与 for in 的区别

  1. for of无法循环遍历对象:会报错
  2. 遍历输出结果不同:for in循环遍历的是数组的键值(索引),而for of循环遍历的是数组的值
  3. 新定义属性输出结果不同:新定义的属性也会被for in输出来了,而for of并不会对新定义的属性进行输出。

详情查看下方博客

【ES6】for of用法_汪小穆的博客-CSDN博客_for of前言:for of是ES6新增的循环方法。前面已经说到了 【JavaScript】for、forEach 、for in、each循环详解。那for of又是怎么使用的?一、使用例子使用例子(一)var arr = ['nick','freddy','mike','james'];for(var item of arr){ console.log(item);}输出...https://blog.csdn.net/w390058785/article/details/80522383

Promise.all()用法简记

作用:Promise.all 等待所有都完成(或第一个失败)失败后则不返回结果。

举例:

var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([p1, p2, p3]).then(values => {
  console.log(values); // [3, 1337, "foo"]
});

实例:

methods: {  
    首先声明请求多接口数据处理的函数
     init() {
      promiseList 用于存储all的结果
      let promiseList = [];
      for (let i in 数组长度(请求次数){
        let promise = new Promise((resolve, reject) => {
          this.$http({
            url: 地址,
            method: "get",
          }).then((result) => {
            resolve(result); 请求数据直接存入
            或(根据需要)
            let res = result.data.data;
            res.forEach(item=>{
              item.name = 'name'
              .......后续操作
             }
            )
            resolve(item); 处理后数据存入
          });
        });
        promiseList.push(promise);将每次请求的返回值追加存入
      }
      Promise.all(promiseList).then((result) => {
        console.log("返回的数据,数组形式", result)
        已拿到所有请求数据result,再进行后续操作....
        this.renderTable(); //获取到所有数据后再进行后续操作
      });
    },
}

解决promise失败不返回结果

 封装catch方法(失败结果也接收)

    var p1 = Promise.resolve(3).catch(function (err) {
        return err;
    });
    var p2 = Promise.reject(2).catch(function (err) {
        return err;
    });
    var p3 = new Promise((resolve, reject) => {
        if(1 == 2){ // 接口请求状态
            resolve('请求成功')
        }else{
            reject('请求失败')
        }
    }).catch(function (err) {
        return null; // 进行标记统一清除失败结果
    });

    Promise.all([p1, p2, p3]).then(values => {
        values = values.filter(item => item != null);
        console.log(values); // [3, 2]
    }).catch(function (err) {
        console.log(1); //不会走到这里
    });

 只接收成功值方法

methods: {  
    首先声明请求多接口数据处理的函数
     init() {
      promiseList 用于存储all的结果
      let promiseList = [];
      for (let i in 数组长度(请求次数){
        let promise = new Promise((resolve, reject) => {
          this.$http({
            url: 地址,
            method: "get",
          }).then((result) => {
            resolve(result); 请求数据直接存入
            或(根据需要)
            let res = result.data.data;
            res.forEach(item=>{
              item.name = 'name'
              .......后续操作
             }
            )
            resolve(item); 处理后数据存入
          });
        });
        只接收成功值
        promise.then((res) => {
          promiseList.push(res)
        })
      }
      Promise.all(promiseList).then((result) => {
        console.log("返回的数据,数组形式", promiseList)
        已拿到所有请求数据promiseList,再进行后续操作...
      });
    },
}

JavaScript事件代理(事件委托)

基本概念

事件代理(Event Delegation),又称之为事件委托。“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown......)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。

值类型和引用类型的区别

1、 javascript中变量类型分为值类型(基本数据类型)和引用类型

值类型:String(字符串),Number(数值),Boolean(布尔值),Undefined,Null
引用类型:Array(数组),Object(对象),Function(函数)

2、 值类型和引用类型的区别

(1) 存储位置不一样
值类型占用空间固定,保存在栈中,保存与复制的是值本身,可以使用 typeOf()检测值的类型.
引用类型占用空间不固定,保存在堆中,保存与复制的是指向对象的一个指针,需要使用 instanceof() 检测数据类型,使用 new() 方法构造出的对象是引用型.

(2) 复制方式不一样
值类型的变量直接赋值就是深复制,如 var a = 10; var b = a;那么a的值就复制给b了,b修改值不会影响a,两份数据在内存中是完全独立的。
引用类型的变量直接赋值实际上是传递引用,只是浅复制.是将变量中的存储的地址赋值一份单独存储,但是两个变量中修改其中一个对象,另外一个引用来访问的时候,也会访问到修改后的值。

(3) 值类型无法添加属性和方法,引用类型可以添加属性和方法。

(4)判断比较不同

值类型的比较是值的比较,只有当它们的值相等的时候它们才相等。引用类型的比较是引用地址的比较
比较的时候注意双等号在做比较的时候做了类型转换,而全等号是值和类型相等是才能相等.

(5) 在函数中的使用

值类型变量在函数中被修改时只在函数作用域内部生效,当函数被销毁时此次修改立即失效;而引用类型在函数中被修改时修改的是运行时数据区中的值,即使函数被销毁,变量的值依旧被改变。

回流 与 重绘

回流

当渲染树(render Tree)中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这个过程就称为回流(reflow),也就是重新布局(relayout)。

 重绘 

当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如 background-color 。则就叫称为重绘。

 何时发生回流重绘 

回流阶段需要计算节点的位置和几何信息,当页面布局和几何信息发生变化的时候,就需要回流。

  • 添加或删除可见的DOM元素
  • 元素的位置发生变化
  • 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
  • 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
  • 页面一开始渲染的时候(这肯定避免不了)
  • 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)

回流必定会发生重绘,重绘不一定会引发回流。重绘和回流会在我们设置节点样式时频繁出现,同时也会很大程度上影响性能。回流所需的成本比重绘高的多,改变父节点里的子节点很可能会导致父节点的一系列回流。根据改变的范围和程度,渲染树中或多或少的部分节点需要重新计算,有些改变还会触发整个页面的重排。

减少回流和重绘

避免频繁操作样式,合并多次对DOM和样式的修改。

  • 一次性重写style属性
  • 使用cssText取代多次修改样式
  • 将样式定义为class,一次性修改class属性

当我们需要对DOM对一系列修改的时候,可以通过以下步骤减少回流重绘次数:

  • 使元素脱离文档流
  • 对其进行多次修改
  • 将元素带回到文档中。

该过程的第一步和第三步可能会引起回流,但是经过第一步之后,对DOM的所有修改都不会引起回流,因为它已经不在渲染树了。

有三种方式可以让DOM脱离文档流:

  • 隐藏元素,应用修改,重新显示,这会在展示和隐藏节点的时候,产生两次重绘。
  • 使用文档片段(document fragment)在当前DOM之外构建一个子树,应用修改,再把它拷贝回文档。
  • 将原始元素拷贝到一个脱离文档的节点中,修改节点后,再替换原始的元素。

更多详情:

http://t.csdn.cn/ZtX8R

你可能感兴趣的:(大前端,前端)