欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ECMAScript 2015 ES6

程序员文章站 2022-03-13 08:30:58
牛掰的ES6(持续更新中…)ES6简介:  ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。所以又称ECMAScript 2015。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。  ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现(另外的ECMAScript方言还有Jscript和ActionScript)。日常场合,这两个词是可以互换的。、在我...

锋利的ES6(持续更新中…)

ES6简介:
  ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。所以又称ECMAScript 2015。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
  ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现(另外的ECMAScript方言还有Jscript和ActionScript)。日常场合,这两个词是可以互换的。、在我们正式讲解ES6语法之前,我们得先了解下Babel。
  Babel是一个广泛使用的ES6转码器,可以将ES6代码转为ES5代码,从而在现有环境执行。大家可以选择自己习惯的工具来使用使用Babel,具体过程可直接在Babel官网查看。

let和const命令

1.作用域

​   被let和const命令声明的变量,只在let命令所在的代码块内生效,代码块外无法访问;

  ​ ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

2.变量提升

​   与var不同,let和const声明的变量,不会发生“变量提升”现象,即变量不能在声明之前使用,一旦使用就会报错。

3.暂时性死区

​   在代码块内,使用let和const命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

4.重复声明

​ 被let和const声明的变量不可重复声明。

  在ES6之前,JavaScript只有全局作用域和函数作用域,let命令实际上增加了块级作用域。块级作用域的应用场景:

​ 1.在函数作用域内声明变量

​ 2.在for循环中声明循环变量const声明一个只读的常量。一旦声明,常量的值就不能改变。

注意:const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。

Promise

  这可能是前端程序员处理异步最长用,用的最多的吧。哈哈哈。。。
  背景:在Javascript的世界里,所有代码都是单线程执行的。由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现,但是如果代码中异步代码比较多,也就意味着需要写很多回调函数,这样的代码难以读懂,维护困难,而且不利于复用。
我们希望不用写太多回调,而是也可以像同步代码一样链式执行,而Promise就是为了这种情况而生的。暂且不谈await、async。

Promise介绍

  Promise本身并不能实现任何业务,我们之所以要使用Promise只是为了不写回调,为了把本来异步的代码写成同步的形式,我们先来看一个简单的Promise处理异步的例子:承诺一秒之后生成的随机数大于0.5

const pro = new Promise((resolve, reject) => {
	setTimeout(() => {
		const num = Math.random()
		if (num > 0.5) resolve(num)
		else reject(num)
	}, 1000)
})
pro.then((n) => {
	console.log(n + '大于0.5,承诺兑现')
}).catch((n) => {
	console.log(n + '不大于0.5,承诺失信')
})

  变量pro是一个Promise对象,它负责执行参数里的函数,函数带有 resolve 和 reject 两个参数,resolve 和 reject 函数被调用时,分别将promise的状态改为fulfilled(完成)或rejected(失败)。
  Promise内部只负责判断和修改状态,并不需要执行具体的逻辑,承诺兑现的逻辑在then里执行,承诺失信的逻辑在catch里执行
  先来看个采用Promise后ajax的写法:

getData(method, url){
  var promise = new Promise(function(resolve, reject){
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open(method, url);
    xmlHttp.send();
    xmlHttp.onload = function () {
      if (this.status == 200 ) {
        resolve(this.response);
      } else {
        reject(this.statusText);
      }
    };
    xmlHttp.onerror = function () {
      reject(this.statusText);
    };
  })
  return promise;
}
getData('get','www.xxx.com').then(successFun, failFun)

Promise详解

ES6规定,Promise对象是一个构造函数,用来生成Promise实例。Promise 实例生成以后,可以用then 方法分别指定成功状态和失败状态的回调函数。
先提前准备几个后端接口

var express = require("express");
var app = express();

//设置跨域访问(设置在所有的请求前面即可)
app.all("*", function (req, res, next) {
  //设置允许跨域的域名,*代表允许任意域名跨域
  res.header("Access-Control-Allow-Origin", "*");
  //允许的header类型
  res.header("Access-Control-Allow-Headers", "content-type");
  //跨域允许的请求方式 
  res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
  if (req.method == 'OPTIONS')
    res.sendStatus(200); //让options尝试请求快速结束
  else
    next();
});

// 第一个接口
app.get("/one", function (req, res) {
  res.send({
    state: true,
    des: "第一个接口请求成功,允许请求第二个接口"
  })
})
// 第二个接口
app.get("/two", function (req, res) {
  res.send({
    state: true,
    des: "第二个接口请求成功,允许请求第三个接口"
  })
})
// 第三个接口
app.get("/three", function (req, res) {
  res.send({
    state: true,
    des: "第三个接口请求成功!"
  })
})
app.listen(8081, function () {
  console.log("应用实例,访问地址为 http://127.0.0.1:8081");
});
            //这里是对位传参,只要参数名可以随意取,第一个参数可以理解为成功后的回调,第二个参数可以理解为失败后的回调

            const p = new Promise(function(resolve,reject){ 
            //发起异步操作,ajax请求
            ......
            if(/*异步操作成功*/){
                resolve(value); //在异步操作成功时调用,返回异步操作结果; 
            }
            else{
                reject(error); //在异步操作失败时调用,返回异步操作结果; 
            }
            });

            Var p1=p.then(function(data){
                console.info(data);
                //发起第二次请求
                //返回请求结果
            }
            );

then方法

  then方法可以接受两个回调函数作为参数。第一个回调函数是Promise 对象的状态变为resolved时调用,第二个回调函数是Promise 对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise 对象传出的值作为参数。

            var p1 = new Promise(function (reslove, reject) {
                $.getJSON(
                    "http://10.1.0.39:8081/check?key=123456",
                    function (data) {
                        if (data.mes != "正确") reject(data);
                        else reslove(data);
                    }
                );
            });
            var p2 = p1.then(
                // 成功的执行函数
                function (data) {
                    console.log("成功", "数据为:", data);
                },
                // 失败的执行函数
                function (data) {
                    console.log("失败", "数据为:", data);
                }
            );

关于catch方法

  正常情况then方法会接受两个参数,分别表示成功的处理函数和失败的处理函数。
但是很多时候我们可能含有多个then方法,这时如果要每个then里面都写上失败处理函数就太麻烦了,这时我们就可以使用catch方法。

我们在最末尾加上catch方法,那么他就可以捕获前面任何地方产生的错误,如下:
ECMAScript 2015 ES6
注意:
一旦在catch前的某个then方法中写了第二个参数用于捕获错误,那么当前错误就会到此停止,后面就是正确的流程了。
如果在后面的流程中没产生其他错误,那么catch方法也不会再执行,如果出错了,那么catch仍然会继续执行。

Promise对象的两个特点

(1)对象的状态不受外界影响。
Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。
Promise 对象的状态改变,只有两种可能:从进行中变为已成功和从进行中变为已失败。只要这两种情况发生,状态就不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。
Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于进行中状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

promise并发控制

all / race

promise.all

  all和race两个函数都是并发执行promise的方法,他们的返回值也是promise,all会等所有的promise都决议之后决议,而race是只要有一个决议就会决议。

Promise.all([promise1, promise2, promise3]).then(function(values) {
  console.log(values);
});
//注意:如果参数为空,all方法会立刻决议,而race方法会挂住

先来看个列子:

// 假设后端有三个接口,
// 第一个接口验证口令是否正确,
// 如果口令正确就发起第二次请求获取当前用户名
// 如果第二个接口成功获取到了用户名了,就发起第三次请求:通过用户名获取用户的vip等级

// http://10.1.0.39:8081/check?key=123456
// http://10.1.0.39:8081/user
// http://10.1.0.39:8081/leave?username=张三

var p1 = new Promise(function (reslove, reject) {
$.getJSON('http://10.1.0.39:8081/check?key=123456', function (data) {
if (data.mes == '正确') {
reslove(data)
}else {
reject(data)
}
})
})

var p2 = p1.then(function (preData) {
return new Promise(function (resolve, reject) {
$.getJSON('http://10.1.0.39:8081/user', function (data) {
if (data.username == '张三') {
resolve(data)
}else {
reject(data)
}
})
})
})

var p3 = p2.then(function (preData) {
$.getJSON('http://10.1.0.39:8081/leave?username=张三', function (data) {
console.log(data)
})
})

是不是觉得不优雅,在追求优雅的道路上永无止境 !(ovo)这时候promise.all就派上用场了。

let p1 = new Promise((resolve, reject) => {
  resolve('成功了')
})

let p2 = new Promise((resolve, reject) => {
  resolve('success')
})

let p3 = Promse.reject('失败')

Promise.all([p1, p2]).then((result) => {
  console.log(result)               //['成功了', 'success']
}).catch((error) => {
  console.log(error)
})

Promise.all([p1,p3,p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)      // 失败了,打出 '失败'
})

你学费了吗。。。。。。
  Promse.all在处理多个异步处理时非常有用,比如说一个页面上需要等两个或多个ajax的数据回来以后才正常显示,在此之前只显示loading图标。
  需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚。这带来了一个绝大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。

面试题:封装一个promise.all方法(重点)

Promise.prototype.all = function(promises) {
  let results = [];
  let promiseCount = 0;
  let promisesLength = promises.length;
  return new Promise(function(resolve, reject) {
    for (let val of promises) {
      Promise.resolve(val).then(function(res) {
        promiseCount++;
        // results.push(res);
        results[i] = res;
        // 当所有函数都正确执行了,resolve输出所有返回结果。
        if (promiseCount === promisesLength) {
          return resolve(results);
        }
      }, function(err) {
        return reject(err);
      });
    }
  });
};

Promise.race的使用

顾名思义,Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success')
  },1000)
})

let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('failed')
  }, 500)
})

Promise.race([p1, p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)  // 打开的是 'failed'
})

原理是挺简单的,但是在实际运用中还没有想到什么的使用场景会使用到.自己也还没用过!

Es6中字符串的一些新方法(6/7/8):

模版字符串

  1. 使用反引号表示模板字符串
  2. 将表达式嵌入字符串中进行拼接。用${}来界定。
  3. 允许直接定义多行字符串
    ECMAScript 2015 ES6
    注意:这三个方法都支持第二个参数,表示从哪里开始检索。其中,includes()和startsWith()的默认值是0,表示检索范围是参数值检索到末尾,很简单不多说。endsWith()很特殊,它第二个参数的默认值是字符串总长度值,表示检索范围是从开头检索到这个值。

repeat()

表示重复多少次。如果参数是正小数,会取整。如果参数是负数,会报错。如果参数是0,会得到空串。如果参数是字符串、布尔型或其他类型,会先换算成整数。

padStart(),padEnd()

这两个是ES8(也就是2017)新增方法,注意打开实验性JavaScript。

用于在开头补全字符和在末尾补全字符,padStart和padEnd一共接受两个参数,第一个参数用来指定字符串的最小长度,第二个参数是用来补全的字符串。

如果原字符串的长度,等于或大于指定的最小长度,则返回原字符串。

有一个问题是,如果用来补全的字符串与原字符串,两者的长度之和超过了指定的最小长度,js会截去右边超出位数的补全字符串,而原字符串是不会碰的。即使是padEnd也是截去右边超出的位数。

'abc'.padStart(10, '0123456789')
// '0123456abc'
'abc'.padEnd(10, '0123456789')
// 'abc0123456'

如果没有缺省第二个参数,默认填充空格。

数组方法

forEach(ES5)

需要指出的是:
在遍历的回调函数里的第三个参数array指的就是当前正在遍历的数组

var arr = ['Dary', 'Tom', 'Jim', , 'Lom']
arr.forEach(function (item, index, array) {
    // array就是arr本身
})

forEach除了传一个回调函数以外,后面还有可选的第二个参数,传递一个对象,这样在遍历的时候this就指向这个对象

var arr = ['Dary', 'Tom', 'Jim', , 'Lom']
arr.forEach(function (item, index) {
    // 这里的this就指向document
}, document)

但是一般不会在这里对数组进行操作,forEach就单纯的负责遍历数组,如果要对数组做操作可以使用下面介绍的一些方法

map(ES5)

遍历的同时返回一个新的数组,由每趟遍历的回调函数里返回值组成,一般可以用于对数组里的数据做修改。需要特别指出的是每一次遍历都要返回一个结果,否则最后你会得到一个稀疏数组。

var arr = [1, 4, 9, 16]
var arr1 = arr.map(function (item, index) {
    if (item % 2) return item * 2
    return item
})
console.log(arr1) // [2, 4, 18, 16]

当然,这里的回调里也是有第三个参数指当前数组本身,回调后面也有第二个可选参数绑定this指向的,这里就不赘述了。
map方法一般用来修改数组,可以修改整个数组也可以根据一些条件修改数组中的某个值

filter(ES5)

过滤,遍历的同时返回一个新的数组。在回调函数里返回一个条件,满足条件的数据会被保留,不满足的被过滤掉。

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present']
const result = words.filter(function (word, index) {
    return word.length > 6
})
console.log(result)  // ["exuberant", "destruction", "present"]

毫无疑问,这个方法的回调里也有第三个参数以及回调后面的参数。这个方法一般用于删除数组元素

some(ES5)

返回一个布尔值,在回调函数里返回一个条件,只要在遍历的过程中有任意一条数据满足条件,就终止遍历,并且最终得到的值就是true,否则会一直遍历到结束,最终得到false.

const arr = [1, 2, 3, 4, 5]
const even = arr.some(function (element, index) {
    return element % 2 === 0
})
console.log(even) // true

这个方法也有上述方法提到过的可选参数.

every(ES5)

返回一个布尔值,在回调函数里返回一个条件,在遍历的过程中只要有一条数据不满足条件,就终止遍历,并且最终得到false,否则会一直遍历到结束,最终得到true

const arr = [1, 30, 39, 29, 10, 13];
const isBelowThreshold = arr.every(function (currentValue) {
    return currentValue < 40
})
console.log(isBelowThreshold) // true

这个方法也有上述方法提到过的可选参数

reduce、reduceRight(ES5)

归并,返回一个新值,在每一趟遍历时返回一个值,这个值会继续作为下一次遍历的初始值来使用,最终遍历完成得到最后返回的值。一般在处理整个数组需要最终得到一个值的情况下使用,比如计算总价,合并数组等。
reduce是从左往右归并,而reduceRight是从右往左,只是顺序不一样并不影响结果,reduceRight一般用的很少。

var arr = [1, 2, 3, 4]
// acc是累计器,他的值是每一次回调里的返回值
// curr是当前正在处理的数组元素
// 1 + 2 + 3 + 4
var count = arr.reduce(function (acc, curr) {
    return acc + curr
})
console.log(count) // 10

// 在回调函数的后面可以给一个初始值,这样初次acc的值就是这个初始值
// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(function (acc, curr) {
    return acc + curr
}, 5)) // 15

reduce的回调里还有另外两个可选参数index和array

var arr = [1, 2, 3, 4]
arr.reduce(function (acc, cur, index, array) {
    // index指cur的索引
    // array就是源数组arr
})

reduce的高级用法
(1)计算数组中每个元素出现的次数

let names = ['peter', 'tom', 'mary', 'bob', 'tom','peter'];

let nameNum = names.reduce((pre,cur)=>{
  if(cur in pre){
    pre[cur]++
  }else{
    pre[cur] = 1
  }
  return pre
},{})
console.log(nameNum); //{ peter: 2, tom: 2, mary: 1, bob: 1 }

(2)数组去重

let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((pre,cur)=>{
    if(!pre.includes(cur)){
      return pre.concat(cur)
    }else{
      return pre
    }
},[])
console.log(newArr);// [1, 2, 3, 4]

(3)将多维数组转化为一维

let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(arr){
   return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[])
}
console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]

另外看看高频考点这几个api原生初步实现吧(重点)

// 手动实现map方法	[1,2],function(){}
		function map(arr,mapCallback){
			if(!Array.isArray(arr) || !arr.length || typeof mapCallback!=='function'){
				return [];
			}else{
				let result = [];
				for(let i =0,len=arr.length;i<len;i++){
					result.push(mapCallback(arr[i],i,arr))
				}
				return result;
			}
		}
		// filter
		function filter(arr,filterCallback){
			if(!Array.isArray(arr) || !arr.length || typeof filterCallback!=='function'){
				return [];
			}else{
				let result = [];
				for(let i=0,len=arr.length;i<len;i++){
					if(filterCallback(arr[i],i,arr)){
						result.push(arr[i]);
					}
				}
				return result;
			}
		}
		// reduce
		function reduce(arr,reduceCallback,initialValue){
			if(!Array.isArray(arr) || !arr.length || typeof reduceCallback!=='function'){
				return [];
			}else{
				let hansInitialValue=initialValue!==undefined;
				let value =hansInitialValue?initialValue:arr[0];
				for(let i=hansInitialValue?0:1,len=arr.length;i<len;i++){
					value =reduceCallback(value,arr[i],i,arr)
				}
				return value;
			}
		}

接下来就是一些ES6新增方法了

Array.from()(ES6)

这是Array对象本身的方法,所以调用方式是Array.from(),它可以将一个可迭代对象,例如NodeList、classList等转换成一个数组

Array.from(document.querySelesctorAll('.delete'))
Array.from(document.querySelesctor('.delete').classList)

Array.of()

用于将一组值,转换为数组。

Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]

实验性的API

copyWithin

在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。

array. copyWithin(target, start = 0, end = this.length);

target(必需):从该位置开始替换数据。如果为负值,表示倒数。
start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示倒数。
end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数。

// 将3号位复制到0号位
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
// [4, 2, 3, 4, 5]

// -2相当于3号位,-1相当于4号位
[1, 2, 3, 4, 5].copyWithin(0, -2, -1)
// [4, 2, 3, 4, 5]

fill

使用给定值,填充一个数组。

array. copyWithin(target, start = 0, end = this.length);

target(必需):从该位置开始替换数据。如果为负值,表示倒数。
start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示倒数。
end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数

['a', 'b', 'c'].fill(7);   // [7, 7, 7]

let arr = new Array(3).fill([]);
arr[0].push(5);       // [[5], [5], [5]]

find

查找数组中符合条件的元素,若有多个符合条件的元素,则返回第一个元素。

let arr = Array.of(1, 2, 3, 4);
console.log(arr.find(item => item > 2)); // 3
 
// 数组空位处理为 undefined
console.log([, 1].find(n => true)); // undefined

findIndex()

查找数组中符合条件的元素索引,若有多个符合条件的元素,则返回第一个元素索引。

let arr = Array.of(1, 2, 1, 3);
// 参数1:回调函数
// 参数2(可选):指定回调函数中的 this 值
console.log(arr.findIndex(item => item = 1)); // 0
 
// 数组空位处理为 undefined
console.log([, 1].findIndex(n => true)); //0

entries

返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对

const array1 = ['a', 'b', 'c'];

const iterator1 = array1.entries();

console.log(iterator1.next().value);  // [0, "a"]
console.log(iterator1.next().value);  // [1, "b"]
console.log(iterator1.next().value);  // [2, "c"]

flat(ES2019)

var arr1 = [1, 2, [3, 4]];
arr1.flat();   // [1, 2, 3, 4]

var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();   // [1, 2, 3, 4, [5, 6]]

var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);  // [1, 2, 3, 4, 5, 6]

//使用 Infinity,可展开任意深度的嵌套数组
var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// 移除数组中的空项
var arr5 = [1, 2, , 4, 5];
arr5.flat(); // [1, 2, 4, 5]

includes()

数组是否包含指定值。

注意:与 Set 和 Map 的 has 方法区分;Set 的 has 方法用于查找值;Map 的 has 方法用于查找键名。

// 参数1:包含的指定值
[1, 2, 3].includes(1);    // true
 
// 参数2:可选,搜索的起始索引,默认为0
[1, 2, 3].includes(1, 2); // false
 
// NaN 的包含判断
[1, NaN, 3].includes(NaN); // true

keys()

遍历键名。

for(let key of ['a', 'b'].keys()){
    console.log(key);
}
// 0
// 1
 
// 数组含空位
console.log([...[,'a'].keys()]); // [0, 1]

values()

遍历键值。

for(let value of ['a', 'b'].values()){
    console.log(value);
}
// "a"
// "b"
 
// 数组含空位
console.log([...[,'a'].values()]); // [undefined, "a"]

最后附上一张数组,字符串方法图

    /*数组的方法
    会改变原数组:1.pop();返回值删除的那一项
                 2.push(“”);返回值改变后的数组长度
                 3.shift();返回值删除的那一项
                 4.unshift('');返回值改变后的数组长度
                 5.splice(1,2,3);返回值是截取后的数组  第一个值从哪开始截取,第二个截取多少个,第三可以不写替换的新元素
                 6.arr.reverse();返回值是新数组;返转数组
                 7.arr.sort();返回值是新数组;给数组排序
    不会改变原数组:1.arr.concat();返回值是拼接好的新数组
                  2.arr.join("拼接方式")返回值是拼接好的字符串
                  ES5中方法
                  3.indexOf(你要找的数组中的项)返回值对应下标
                  4.arr.forEach(function(item,index,arr){})item数组中的每一项,index数组索引,arr原始数组
                                用来遍历数组,不能对数组进行操作,返回值undefind
                  5.arr.map(function(item,index,arr){})可以对数组中的每一项进行操作,返回值是一个新的数组
                  6.arr.filter(function (item, index, arr) {})返回值过滤过后的数组,不会改变原数组。
                  把原始数组中满足条件的筛选出来,组成一个新的数组返回
                  7.some()   只要数组中有一个满足条件那就返回 true 都不满足那就返回 false 
                 8.every()  数组每一个都要满足条件就返回 true  只要有一个不满足那就返回 false
                 9.arr.reduce() 经常用来做数组的累加等。reduce可以遍历调用该方法的数组并使用传入参数方法,返回遍历完成后最终的执行结果,
                 不会修改原数组。reduce可以接受两个参数,reduce接受的第一个参数是一个方法,该方法可以接受四个参数,
                 第一个参数为上一次函数调用的返回值(第一次调用时默认是数组的第一个元素),第二个参数为当前被遍历的元素,
                 第三个参数为当前遍历元素的下标,第四个参数为执行reduce方法的原数组,
                 reduce接受的第二个参数是第一个参数方法第一次调用的返回值的初始值(默认是数组的第一个元素)。
ES6新增方法:    findIndex() 方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置。
                findIndex() 方法为数组中的每个元素都调用一次函数执行:
                当数组中的元素在测试条件时返回 true 时, findIndex() 返回符合条件的元素的索引位置,之后的值不会再调用执行函数。
                如果没有符合条件的元素返回 -1
                注意: findIndex() 对于空数组,函数是不会执行的。
                注意: findIndex() 并没有改变数组的原始值。
                fill() 方法。填充。参数1:用什么填充。参数2起始位置。参数3结束位置(包前不包后)
                Array.of() 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型
                Array.from()
                copyWithin() 方法 copyWithin()方法允许你在数组内部复制自身元素。为此你需要
                传递两个或者3个参数给 copyWithin()方法:从什么位置开始进行填充,以及被用来复制的数据的起
                始位置索引,结束索引。
                let numbers = [1, 2, 3, 4];
                从索引 2 的位置开始粘贴
                从数组索引 0 的位置开始复制数据
                numbers.copyWithin(2, 0);
                console.log(numbers.toString()); // 1,2,1,2
     字符串方法:
     不会改变原字符串:
                1.str.charAt(索引)是找到字符串中指定索引位置的内容返回 。不会改变原字符串。返回值:对应下标的字符。
                2.str.indexOf('J')返回值 如果有这个数据就是 这个数据的下标  如果没有就是返回 -1
                3.substring(从哪个索引开始,到哪个索引截止)(包前不包后)
                4.substr(从哪个索引开始,截取多少个)substr(从哪个索引开始,截取多少个) 返回值 就是截取出来的字符串
                5.toLowerCase 和 toUpperCase返回值字符串转成小写字母和大写字母,都不会改变原来的字符串。
                6.split() 方法用于把一个字符串分割成字符串数组(伪数组)。
                            str.split(str,length):返回一个数组,length参数可省略,限制生成数组的长度,
                            把str作为分割字符串的标准,str.split(“”)则回把每个字符串都分割 
                7.replace()
                字符串配合正则表达式:
                8.search(“正则表达式”)和indexof一样,区别是可以用正则表达式
                9.math(“正则表达式”)正则表达式不写g返回一个数组,如果写了g则返回所有条件数组
                语法 字符串.replace(参数1,参数2)  参数1 是要替换的字符  参数2 用什么进行替换
                不会改变原来的字符串
                返回值就是替换过后的字符串 
    数组和字符串都能用的方法:
                1.indexOf
                2.concat
                3.slice(值1,值2)截取字符串或者数组(包前不包后),不会改变原字符串或者数组,返回值截取后的数据。
                                第二个值如果是负数,可以当做是截取到  length-n的位置

你的点赞和观看是我坚持的动力,感谢各位老铁。持续更新中~~~

本文地址:https://blog.csdn.net/Gabbyt/article/details/112794572

相关标签: es6 javascript