重学ES6基础语法(四)

本系列博客为ES6基础语法的使用及总结,若有错误,欢迎指正。 重学ES6基础语法(四)主要包括 Array.from()Array.of()find()/findIndex()some()/every()PromiseSymbol() 等。面试

Array.from()/Array.of()

这两个方法不是原型上面的方法,直接使用会报错编程

let arr = [1,2,3];
console.log(arr.from());
//Uncaught TypeError: arr.from is not a function

console.log(arr.of()); 
//Uncaught TypeError: arr.of is not a function
复制代码

Array.from()

1.用法数组

用于把一个类数组对象或者是一个可遍历对象转换为一个真正的数组promise

类数组对象是啥? 具备索引属性(数字),有length属性的对象;好比NodeList对象 可遍历对象是啥? 别问,问就是让你去看前面两篇笔记bash

(1) 格式: Array.from(arrayLike[, mapFn[, thisArg]])app

(2) 参数:异步

  • arrayLike 想要转换成数组的伪数组对象或可迭代对象。
  • mapFn 可选 若是指定了该参数,新数组中的每一个元素会执行该回调函数。
  • thisArg 可选 执行回调函数 mapFn 时 this 对象。

(3) 返回值:一个新的数组实例。异步编程

(4) 示例函数

// 从String生成数组
Array.from('foo'); 
// [ "f", "o", "o" ]

console.log(Array.from([1, 2, 3], x => x + x));
// expected output: Array [2, 4, 6]
复制代码

Array.from(obj, mapFn, thisArg)的格式至关于 Array.from(obj).map(mapFn, thisArg)post

let oLis = document.querySelectorAll('li');
let num = Array.from(oLis).map(li => li.innerHTML);
console.log(num); //["1", "2", "3"]
//等价于
let liArr = Array.from(oLis,li => li.innerHTML);
console.log(liArr); //["1", "2", "3"]
复制代码

2.应用场景

  • 将字符串转为字符串数组
    let arr = Array.from('ridiculous');
    console.log(arr);  //["r", "i", "d", "i", "c", "u", "l", "o", "u", "s"]
    
    let str = 'ridiculous';
    let arr2 = str.split('');
    console.log(arr2); //["r", "i", "d", "i", "c", "u", "l", "o", "u", "s"]
    复制代码

Array.of()

1.用法

Array.of() 方法建立一个具备可变数量参数的新数组实例,而不考虑参数的数量或类型。

Array.of() 和 Array 构造函数之间的区别在于处理整数参数:

  • Array.of(7)建立一个具备单个元素为7的数组(注意:数组的长度是1),

  • Array(7) 建立一个长度为7的空数组(注意:这是指一个有7个空位(empty)的数组,而不是由7个undefined组成的数组)。

let arr = Array(5);
console.log(arr); //[empty × 5] 是一个长度为5,数值都为空的数组
let arr2 = Array.of(5);
console.log(arr2); //[5] 是一个长度为1,元素值为5的数组

let arr = Array(0);
console.log(arr); //[]
let arr2 = Array.of(0);
console.log(arr2); //[0]
复制代码

也就是说使用 Array.of() 可以保证传入的数据和返回结果的一致性,无论传入多少个参数,返回的是由这些元素组成的数组;弥补了Array()构造函数的不足

let arr = Array(1,2,3);
console.log(arr); //[1,2,3]

let arr2 = Array.of(1,2,3);
console.log(arr2); //[1,2,3]
复制代码

find()/findIndex()/some()/every()

find()

find() 方法返回数组中知足提供的测试函数的第一个元素的值。不然返回 undefined。 找到知足条件的第一个就会当即中止

1.用法

格式:arr.find(callback[, thisArg])

参数:① callback 在数组每一项上执行的函数,接收 3 个参数:

  • element 当前遍历到的元素。
  • index 可选 当前遍历到的索引。
  • array 可选 数组自己。

② thisArg 可选 执行回调时用做this 的对象。

返回值:数组中第一个知足所提供测试函数的元素的值,都找不到不然返回 undefined。

let inventory = [
    {name: 'apples', quantity: 2},
    {name: 'bananas', quantity: 0},
    {name: 'cherries', quantity: 5}
];

let cherry = inventory.find(fruit => fruit.name === 'cherries');
console.log(cherry); // { name: 'cherries', quantity: 5 }
复制代码

findIndex()

findIndex()方法返回数组中知足提供的测试函数的第一个元素的索引。找不到则返回-1。

1.用法 格式:arr.findIndex(callback[, thisArg])

参数:① callback 针对数组中的每一个元素, 都会执行该回调函数, 执行时会自动传入下面三个参数:

  • element 当前元素。
  • index 当前元素的索引。
  • array 调用findIndex的数组。

② thisArg 可选。执行callback时做为this对象的值.

返回值:数组中经过提供测试函数的第一个元素的索引。不然,返回-1

let cherryIndex = inventory.findIndex(fruit => fruit.name === 'cherries');
console.log(cherryIndex); //2
复制代码

some()

some() 方法测试数组中是否是至少有1个元素经过了被提供的函数测试。它返回的是一个Boolean类型的值。

找到知足条件的第一个就会当即中止

1.用法

格式:arr.some(callback(element[, index[, array]])[, thisArg])

参数: ① callback用来测试每一个元素的函数,接受三个参数:

  • element 数组中正在处理的元素。
  • index 可选 数组中正在处理的元素的索引值。
  • array 可选 some()被调用的数组。

② thisArg可选 执行 callback 时使用的 this 值。

返回值:数组中有至少一个元素经过回调函数的测试就会返回true;全部元素都没有经过回调函数的测试返回值才会为false。

let isZero = inventory.some(fruit => fruit.quantity === 0);
console.log(isZero); //true
复制代码

every()

every() 方法测试一个数组内的全部元素是否都能经过某个指定函数的测试。它返回一个布尔值。 若是有一个为false,则当即返回false,后面的再也不执行

1.用法

格式:arr.every(callback[, thisArg])

参数:① callback 用来测试每一个元素的函数,它能够接收三个参数:

  • element 用于测试的当前值。
  • index 可选 用于测试的当前值的索引。
  • array 可选 调用 every 的当前数组。

② thisArg 执行 callback时使用的 this 值。

返回值:若是回调函数的每一次返回都为 truthy 值,返回 true ,不然返回 false。

let allZero = inventory.every(fruits => fruits.quantity === 0);
console.log(allZero); //false
复制代码

Promise

官方说法之又臭又长不看版:

Promise 对象用于表示一个异步操做的最终完成 (或失败), 及其结果值.

Promise构造函数执行时当即调用executor函数, resolve 和 reject 两个函数做为参数传递给executor(executor 函数在Promise构造函数返回所建promise实例对象前被调用)。resolve 和 reject 函数被调用时,分别将promise的状态改成fulfilled(完成)或rejected(失败)。executor 内部一般会执行一些异步操做,一旦异步操做执行完毕(可能成功/失败),要么调用resolve函数来将promise状态改为fulfilled,要么调用reject 函数将promise的状态改成rejected。若是在executor函数中抛出一个错误,那么该promise 状态为rejected。executor函数的返回值被忽略。

1.Promise基本概念

1.1 what

promise是ES6中新增的异步编程解决方案。简单说就是一个容器,里面保存着某个将来才会结束的事件的结果。 从语法上说,Promise 是一个对象,从它能够获取异步操做的消息。能够经过new Promise(function(resolve, reject){})来建立

1.2 why

经过Promise就能够实现:用同步的流程来表示异步的操做;解决回调顺序的不肯定性,解决回调地狱的问题

1.3 how

Promise构造函数接受一个函数做为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由JavaScript引擎提供,不用本身部署。

resolve函数的做用是,将Promise对象的状态从“未完成”变为“成功”(即从Pending变为Resolved),在异步操做成功时调用,并将异步操做的结果,做为参数传递出去;

reject函数的做用是,将Promise对象的状态从“未完成”变为“失败”(即从Pending变为Rejected),在异步操做失败时调用,并将异步操做报出的错误,做为参数传递出去。

let p = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操做成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});
复制代码

2.Promise对象三种状态(面试必问)

  • pending:默认状态,只要没有说明promise任务是成功仍是失败就是pending状态
  • fulfilled(resolved):只要调用resolve函数, 状态就会变为fulfilled, 表示操做成功
  • rejected:只要调用rejected函数, 状态就会变为rejected, 表示操做失败

3.Promise 对象的特色

3.1 对象的状态不受外界影响,只有异步操做的操做的结果,能够决定当前是哪种状态,任何其余操做都没法改变这个状态。

3.2 一旦状态改变,就不会再改变,任什么时候候均可以获得这个结果。 Promise 对象的状态改变,只有两种可能:从Pending变为Resolved;从Pending变为Rejected

4.Promise 经常使用的方法有哪些?它们的做用是什么?

4.1 Promise.then()

  • Promise 实例具备then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。
  • 它的做用是为 Promise 实例添加状态改变时的回调函数。
  • then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。

4.2 Promise.catch()

Promise.catch方法是.then(null, rejection).then(undefined, rejection)的语法糖,用于指定发生错误时的回调函数。

4.3 Promise.all()

all方法接收一个数组,,当全部实例promise的结果都是成功时,才会执行后面then方法里面的内容 若是有一个promise实例的状态是失败的,那么就会执行catch方法

const userPromise = new Promise((resolve,reject) =>{
  setTimeout(() => {
      resolve(['lucy','lily','eli']);
  },2000)
});

const moviePromise = new Promise((resolve,reject) => {
  setTimeout(() => {
      // resolve({name: '卡萨布兰卡',score: '9.8', published: '1964'});
      reject('no movie found');
  },500);
});
Promise.all([userPromise,moviePromise])
      .then(response => {
          console.log(response);
          let [user,movie] = response;
          console.log(user);
          console.log(movie);
      })
      .catch(err => console.log(err));
复制代码

已知userPromise的状态已经肯定了是成功的,因此all方法返回的内容取决于moviePromise的状态:

若是moviePromise的状态是成功,则all方法执行then里面的内容。正常打印response、user、movie

若是moviePromise的状态是失败,则all方法执行catch里面的内容。抛出错误

4.4 Promise.race()

race方法由数组里面第一个promise实例返回的状态决定,若是第一个promise返回的状态是成功,那么race方法执行then方法里面的内容; 若是第一个promise实例返回的状态是失败,则race方法执行catch方法里面的内容

const userPromise = new Promise((resolve,reject) =>{
  setTimeout(() => {
      resolve(['lucy','lily','eli']);
  },2000)
});

const moviePromise = new Promise((resolve,reject) => {
  setTimeout(() => {
      resolve({name: '卡萨布兰卡',score: '9.8', published: '1964'});
      // reject(Error('no movie found'));
  },500);
});
Promise.race([userPromise,moviePromise])
        .then(response => {
            console.log(response);
        })
        .catch(err => console.log(err));
复制代码

race方法执行的结果取决于先执行的moviePromise返回的结果,

若是moviePromise的状态是成功的,那么race方法执行then里面的内容。正常打印response

若是moviePromise的状态是失败的,那么race方法执行执行catch里面的内容。抛出错误

5.Promise常见面试题

5.1

let promise = new Promise((resolve, reject)=>{
  console.log('我是promise任务');
  resolve('resolved')
})
promise.then(res =>{
  console.log(res)
})
console.log("我是同步任务");
  setTimeout(()=>{
  console.log("我是延时任务");
}, 0)
复制代码

答案:执行顺序:我是promise任务、我是同步任务、resolved、我是延时任务。

5.2

console.log(1);
setTimeout(()=>{
  console.log(2);
});
setTimeout(()=>{
  console.log(3);
});
const promise = new Promise((resolve) => {
  console.log(4);
  resolve();
});
promise.then(()=>{
  console.log(5);
});
console.log(6); //1 4 6 5 2 3
复制代码

Symbol

symbol 是一种基本数据类型 (primitive data type)。
Symbol()函数会返回symbol类型的值
每一个从Symbol()返回的symbol值都是惟一的。一个symbol值能做为对象属性的标识符。

1.什么Symbol?

  • Symbol是ES6中新增的一种数据类型,被划分到了基本数据类型中

  • Symbol的做用:用来表示一个独一无二的值

  • Symbol的意义:用来解决对象中属性命名的冲突问题

2.如何生成一个Symbol

2.1 采用let xxx = Symbol();便可建立一个独一无二的值;利用typeof 检查这个独一无二的值时,返回symbol(小写s)

每一次建立的Symbol不和其余Symbol相等(独一无二)

const peter = Symbol();
console.log(peter); //Symbol()
console.log(typeof peter); //symbol

const student = Symbol();
console.log(student === peter); //false
复制代码

2.2 能够在括号里面为每个Symbol添加描述,用于区分Symbol

经过Symbol生成独一无二值时传入的字符串仅仅是一个标记, 方便咱们阅读代码, 没有其它任何意义

const peter = Symbol('peter');
console.log(peter); //Symbol(peter)

const student = Symbol('student');
console.log(student); //Symbol(student)
复制代码

3.注意点

3.1 经过Symbol生成独一无二值时须要在后面加上(), 可是前面不能加new, 由于它不是引用类型

3.2 作类型转换的时候不能转换成数值类型,且不能作任何运算

let n = Symbol("name");
console.log(String(n));//字符串Symbol(name)
console.log(Boolean(n));//true
console.log(Number(n));//报错 Uncaught TypeError: Cannot convert a Symbol value to a number
复制代码

3.3 对象的属性名是Symbol类型的话,是不可遍历的

不能用for inObject.keys()Object.getOwnPropertyNames()遍历

const list = {
   [Symbol('Ann')]: {score: 99, gender: 'female'},
   [Symbol('Bob')]: {score: 99, gender: 'male'},
   [Symbol('Eli')]: {score: 99, gender: 'male'},
 };

 for(let key in list){
   console.log(key); //什么也没输出
   console.log(list[key]); //什么也没输出
 }

 let res = Object.keys(list);
 console.log(res); //[]

 let res2 = Object.getOwnPropertyNames(list);
 console.log(res2); //[]
复制代码

3.4 Object.getOwnPropertySymbols()方法遍历属性时返回一个symbol类型的数组。

let res3 = Object.getOwnPropertySymbols(list);
 console.log(res3);
复制代码

3.5 若是想使用Symbol变量做为对象属性的名称, 那么必须使用[],获取的时候也只能用 对象名称[]的方式

const list = {
   [Symbol('Ann')]: {score: 99, gender: 'female'},
   [Symbol('Bob')]: {score: 99, gender: 'male'},
   [Symbol('Eli')]: {score: 99, gender: 'male'},
};

const name = Symbol('Eli');
const say = Symbol('say');
const person = {
    [name] : 'ghk',
    [say]: function () {
         console.log('say');
    }
}
//获取属性的时候
console.log(person[name]);
console.log(person[say]);
复制代码
相关文章
相关标签/搜索