一:Let和const

(1)Let定义块级作用域的变量,var定义的变量会提升。Let不会提升。

如下。var可以先用,打印是undefined但是let在定义之前是不能用的。

会报错Uncaught ReferenceError: letter is not defined(…)

console.log(color)

console.log(letter)

var color = 'red';

let letter = 'a'

只要块级作用域内存在let命令,声明的变量不受外部影响。

var tmp = 123;

if (true) {

tmp = 'abc'; //tmp is not defined(…)

let tmp;

}

在代码块内,使用let命令声明变量之前,该变量都是不可用称“暂时性死区”

typeof x;  //使用是在let声明之前x is not defined(…)

let x;

再如function bar(x = y, y = 1) {

return [x, y];

}

bar();// y is not defined(…)x的默认值等于y,此时y还没声明。

2)通过var在块作用域中定义变量在外面可以访问,{}

通过let在块作用域中定义的变量,在外面不可以访问{}

if (true) {

// 块作用域里面都可以访问

var color = 'red';

let letter = 'a'

console.log(color)  //可以访问

console.log(letter)  //可以访问

}

console.log(color)  //可以访问

console.log(letter)  //不能访问 letter is not defined(…)

(3)let保存变量

var arr = []

for (var i = 0; i < 5; i++) {

  arr[i] = function  () {

    console.log(i, 'iii')

  }

}

arr[1]()    //5,‘iii’

i是全局for循环外面也可以访问。For循环完之后i是5

var arr = [];

for (let j = 0; j < 5; j++) {

arr[j] = function  () {

console.log(j, 'jjjj')

}

}

arr[1]();  // 1,’iii’

这个函数的时候,会找到这个块作用域,这个作用域中定义了块作用域变量j

console.log(i, j)   j是外面无法访问的。

(4):不允许重复声明

function () {

let a = 10;

var a = 1;

}

//Uncaught SyntaxError: Unexpected token (

function () {

let a = 10;

let a = 1;

}

//Uncaught SyntaxError: Unexpected token (

2:const

(1)定义之后再也无法修改 (大写,下划线)

var PI = Math.PI;

PI = 3;

console.log(PI)   //3

const PI = Math.PI

PI = 3;

console.log(PI)  // 报错Assignment to constant variable.(…)

(2)在块作用域中定义一个常量  块作用域内访问有效。外面是访问不到的

if (true) {

const PIa = Math.PI

}

console.log(PIa)  //PIa is not defined(…)

(3)必须先定义再使用

console.log(PIa)  //Identifier 'PI' has already been declared(…)

const PI = Math.PI;

二:模板字符串

使用反引号,直接写变量。

多行字符串,不再使用之前的+拼接字符串

例如:

name ="xiaomei"
age=4
之前:console.log("hello"+name+"my age is"+age)
ES6: console.log(`hello ${name} my age is ${age}`)

三:字符串的拓展方法

(1)startsWith   判断字符串是否以某个字符开头

可以传两个参数{第一个参数表示要判断的字符串,第二个参数表示判断的位置(不传参数表示整个字符串)}

注:截取的是字符串后面的部分

返回值是布尔值:true或者false

eg:

var str = '这是一个美好的传说';

var result = str.startsWith('传说', 7);

//result      为true

(2)endsWith   判断字符串是否以某个字符结尾

可以传两个参数{第一个参数表示要判断的字符串,第二个参数表示判断的位置(不传参数表示整个字符串)}

注:截取的是字符串前面的部分

返回值是布尔值:true或者false

eg:

var str = '这是一个美好的传说';

var result = str.startsWith('个', 4);

//result      为true

(3)includes  判断字符串是否包含一个字符串

可以传两个参数{第一个参数表示要判断的字符串,第二个参数表示判断的位置(不传参数表示整个字符串)}

注:截取的是字符串后面的部分

返回值是布尔值:true或者false

eg:

var str = '这是一个美好的传说';

var result = str.includes ('传说', 7);

//result      为true

(4)repeat  字符串的复写

参数是重复次数

eg:

let str = '这是一个美好的传说';

var result = str.repeat(2);

Console.log(result);  //'这是一个美好的传说这是一个美好的传说'

(5)raw String的方法。获取原始字符串  里面转义字符不会被转义

注:标点符号 tab上面的那个``

var result = String.raw`你\n是一个\n好人`;

console.log(result)

//    你\n是一个\n好人

(6)模板字符串

语法是 ${书写表达式}  ``支持多行字符串

eg:

var title = '你';

var str = `${title}是一个好人

啊`

console.log(str)

//你是一个好人

//啊

四:数值的拓展方法

(1)Number.isFinite()      用来检查一个数值是否为有限的(finite);

注:返回值为true表示有限       false表示无限

eg:

Number.isFinite(15);

true

Number.isFinite(0.8);

true

Number.isFinite(NaN);

false

Number.isFinite(Infinity);

false

Number.isFinite(-Infinity);

false

Number.isFinite('foo');

false

Number.isFinite('15');

false

Number.isFinite(true);

false

Number.isFinite(false);

False

(2)Number.isNaN()     检查一个值是否是NaN

注:返回值为true表示是NaN       false表示不是NaN

eg:

Number.isNaN(NaN)

true

Number.isNaN(15)

false

Number.isNaN('15')

false

Number.isNaN(true)

false

Number.isNaN(9/NaN)

true

Number.isNaN('true'/0)

true

Number.isNaN('true'/'true')

True

(3)Number.isInteger()     检查一个值是否是整数

注:返回值为true表示是整数(.0会转化为整数)       false表示不是整数

eg:

Number.isInteger(25)

true

Number.isInteger(25.0)

true

Number.isInteger(25.1)

false

Number.isInteger("15")

false

Number.isInteger(true)

False

(4) Number.parseInt()     Number.parseFloat()  用法同es5

Eg:

es5用法

parseInt('12.34')

parseFloat('123.45#')

123.45

es6用法

Number.parseInt('12.34')

Number.parseFloat('123.45#')

123.45

Number.parseInt === parseInt

true

Number.parseFloat === parseFloat

true

五:Math对象的扩展

(1)Math.trunc()  去除一个数的小数部分,返回整数部分

注:对于非数值,先用Number().转成数值。对于无法截取整数的返回NaN

Eg:

Math.trunc(4.1)

Math.trunc(4.9)

Math.trunc(-4.1)

-4

Math.trunc(-4.9)

-4

Math.trunc(-0.1234)

-0

Math.trunc('123.456')

Math.trunc(NaN);

NaN

Math.trunc('foo');

NaN

Math.trunc();

NaN

(2)Math.sign()  判断一个数字是正数,负数,还是0;

只有5种结果

NaN传递一个非数字

0 传递的是一个正零(0)

-0 传递的是一个负零(-0)

1 传递的是一个正数(有理数和正无穷)

-1 传递的是一个负数(有理数负无穷等)

Eg:

Math.sign(-5)

-1

Math.sign(5)

Math.sign(0)

Math.sign(-0)

-0

Math.sign(NaN)

NaN

Math.sign('foo');

NaN

六:数组对象的扩展

(1) Array.from()

类数组,可以像数组一样访问成员,但是不能使用数组的方法

该方法将类数组对象转化为真正的数组

注:可以传两个参数:

第一个参数是类数组对象

第二个参数是处理函数(value,index,类数组对象,作用域是window,返回值构成from方法处理的结果的一个新数组)

<ul>

<li>1 1 1</li>

<li>2 2 2</li>

<li>3 3 3</li>

</ul>

var lis = document.getElementsByTagName('li');

console.log(lis[1])   //222

但是不能对lis执行forEach方法(类数组不能使用数组的方法)

lis.forEach(function () {

console.log(111)

})

转化:

var result = Array.from(lis);

查看是不是数组:

console.log(Array.isArray(result))            //true

console.log(result instanceof Array)           //true

console.log(result.constructor === Array)       //true

console.log(Object.prototype.toString.call(result) === '[object Array]')    //true

var result = Array.from(lis, function (value, index) {

//value  dom

value.innerHTML += '修改内容' + index;

return value;

})

console.log(result)

Eg:

let arrayLike = {

'0': 'a',

'1': 'b',

'2': 'c',

length: 3

};

let arr2 = Array.from(arrayLike);

console.log(arr2)

//   ["a", "b", "c"]

(2) Array.of()   将一组值转化为数组(不论传递几个参数,得到得都是一个数组。数组的成员就是参数的成员)

var arr = Array.of()

console.log(arr)   //[]

var arr = Array.of(5)

console.log(arr)   //[5]

var arr = Array.of(5,6)

console.log(arr)   //[5,6]

var arr = Array.of([5,6])

console.log(arr)  //[Array[2]]

之前:

var arr = new Array();

console.log(arr); //[]  空数组    arr.lenght=0;

var arr = new Array(5);

console.log(arr); //[]  空数组    arr.lenght=5;

如果参数是一个非数字参数,得到结果是一个包含一个参数成员的数组

var arr = new Array([1,2,3]);

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

var arr = new Array(‘abc’);

console.log(arr);  //["abc"]

var arr = new Array(‘12’);

console.log(arr);  //["12"]

console.log(arr); //[]  空数组    arr.lenght=5;

var arr = new Array(5,6); 传递两个或者更多参数得到一个数组,数组的成员就是传递参数

console.log(arr);  //[5,6]

(3) 数组实例的方法copyWithin()

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

接受三个参数:

target(必需):从该位置开始替换数据。

start(可选):从该位置开始读取数据,默认为0。如果为负值,表示倒数。

end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数。

Eg:

[1, 2, 3, 4, 5].copyWithin(0, 3)

//[4, 5, 3, 4, 5]

[1, 2, 3, 4, 5].copyWithin(0, 3, 4)

//[4, 2, 3, 4, 5]

[1, 2, 3, 4, 5].copyWithin(0, -2, -1)       4表示-2  5表示-1

//[4, 2, 3, 4, 5]

(4) 数组实例的方法find()和findIndex();

find()获取数组成员    返回值是一个成员值  非贪婪搜索找到就停止

findIndex();获取数组成员索引值   返回值是一个索引值  非贪婪搜索找到就停止

都可以接受一个回调函数作为处理函数(value,index,原数组)作用域是window.返回值是判断条件。

Eg:

var arr = ['宋小宝', '小沈阳', '赵四', '刘能'];

var result = arr.find(function (value, index, arr) {

return value.indexOf('小') > -1;

})

console.log(result);   //宋小宝

[1, 4, -5, 10].find((n) => n < 0)

-5

[1, 5, 10, 15].find(function(value, index, arr) {

return value > 9;

})

[1, 5, 10, 15].findIndex(function(value, index, arr) {

return value > 9;

})

(5)数组实例的fill方法   使用给定值填充数组

用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。

(可以接受三个参数。填充值,起始位置,结束位置)

Eg:

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

//  [7, 7, 7]

new Array(3).fill(7)

//    [7, 7, 7]

['a', 'b', 'c'].fill(7, 1, 2)   从1开始到2之前

//["a", 7, "c"]

['a', 'b', 'c'].fill(7, 1, 3)

//   ["a", 7, 7]

(6)数组实例的 includes()返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。

可以接受第二个参数,表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。

Eg:

[1, 2, 3].includes(2)

//  true

[1, 2, 3].includes(4)

//  false

[1, 2, NaN].includes(NaN)

//  True

[1, 2, 3].includes(3, 3);

//  false

[1, 2, 3].includes(3, -1);

//  True

[1, 2, 3].includes(3, -4);

//  true

(7)数组实例的entries(),keys()和values()

这个三个方法返回的都是迭代器对象,可以用for...of循环进行遍历

或者手动调用遍历器对象的next方法,进行遍历。

Keys 表示获取数组中所有成员的索引值(键名)

Values 表示获取数组中所有成员的值(键值)

Entries 表示获取数组中所有成员与索引值组成数组对(键值对)

Eg:

var colors = ['red', 'green', 'blue'];

var keys = colors.keys();

console.log(keys); 迭代器对象

for (var index of keys) {

console.log(index)

}

// 0

// 1

// 2

var colors = ['red', 'green', 'blue'];

var entries = colors.entries();

for (var entry of entries) {

console.log(entry)

}

//  [0, "red"]

//  [1, "green"]

//  [2, "blue"]

七:对象的拓展

a:Object.keys(),Object.values(),Object.entries()方法

const obj={name:"xiaomei",age:"18"};
console.log(Object.keys(obj))
//["name","age"]
console.log(Object.values(obj))
//["xiaomei","18"]
console.log(Object.entries(obj))
//[["name","xiaomei"],["age","18"]]

b:变量

const name="xiaomei";
const obj={
  name
}
console.log(obj)
//{name: "xiaomei"}

c:...运算符合并对象合并对象

const obj1={name:"xiaomei",age:18};
const obj2={name:"xiaoli",age:19};
console.log({...obj1,...obj2});
//{name: "xiaoli", age: 19} 会覆盖
const obj1={name:"xiaomei",age:18};
const obj2={name:"xiaoli",ages:19};
console.log({...obj1,...obj2});
//{name: "xiaoli", age: 18, ages: 19}

const obj1={name:"xiaomei",age:18};

const obj2={name:"xiaoli",age:19};
console.log({...obj1,...obj2,date:"1.5"});
//{name: "xiaoli", age: 19, date: "1.5"}

d:结构赋值

const arr=["xiaomei","xiaoli"];
let arr1=arr[0];
let arr2=arr[1];
console.log(arr1,arr2);
//xiaomei xiaoli
let [arr1,arr2]=[arr]
console.log(arr1,arr2);
//["xiaomei", "xiaoli"]

const obj3={name:"xiaoli",ages:19};
const {name,ages}=obj3;
console.log(name,ages)
//xiaoli 19

(1) 如果属性的名称跟设置的变量名称相同,这个名称可以省略

在属性名称中可以使用表达式(表达式一定要用[]括起来)

如果方法的名称跟定义的方法名称相同,我们可以省略function(在定义类的时候一样定义方法)

Eg:

var color = 'red';

var title = '爱';

Es5:

var obj = {

color: color,

title: title

}

Es6:

function f(x, y) {

return {x, y};

}

f(1, 2)

// Object {x: 1, y: 2}

var obj = {color, title, num: 100}

// Object {color: "red", title: "爱", num: 100}

var color = 'red';

var title = '爱';

var obj = {

// 定义一个redgreen的属性

[color + 'green']: 200

}

console.log(obj);

//  Object {redgreen: 200}

var color = 'red';

var title = '爱';

var obj = {

color,

getColor() {

return this.color;

}

}

console.log(obj)

console.log(obj.getColor())

//  Object {color: "red"}

//  red

function getPoint() {

var x = 1;

var y = 10;

return {x, y};

}

getPoint()

//  Object {x: 1, y: 10}

(2)Object.is() 判断两个数据是不是同一个数据

ES5比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。

+0 === -0

//true

NaN === NaN

//false

Object.is('foo', 'foo')

//true

Object.is({}, {})

//false

Object.is(+0, -0)

//false

Object.is(NaN, NaN)

//true

(3)Object.assign()

将源对象(source)的所有可枚举属性,复制到目标对象(target)

第一个参数表示源对象(source),后面的参数表示目标对象

Object.assign(obj1, obj2, obj3)

注:是一个浅复制,只是对对象上的属性做简单copy而已

源对象中如果有相同的属性会被覆盖,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。

Eg:

var target = { a: 1 };

var source1 = { b: 2 };

var source2 = { c: 3 };

Object.assign(target, source1, source2);

console.log(target);

// Object {a: 1, b: 2, c: 3}

var target = { a: 1, b: 1 };

var source1 = { b: 2, c: 2 };

var source2 = { c: 3 };

Object.assign(target, source1, source2);

console.log(target)

// Object {a: 1, b: 2, c: 3}

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

var obj = {a: 1};

Object.assign(obj) === obj

//true

(4)Symbol对象

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

symbol函数前不能使用new命令,否则会报错。因为生成的 Symbol 是一个原始类型的值,不是对象。

Eg:

let s = Symbol();

typeof s

// "symbol"

let s = new Symbol();

typeof s

// Identifier 's' has already been declared at

var s1 = Symbol('foo');

var s2 = Symbol('bar');

s1

// Symbol(foo)

s2

// Symbol(bar)

s1.toString()

// "Symbol(foo)"

s2.toString()

// "Symbol(bar)"

Symbol函数的参数只是表示对当前 Symbol 值的描述,因此相同参数的Symbol函数的返回值是不相等的。

var s1 = Symbol();

var s2 = Symbol();

s1 === s2

//false

var s1 = Symbol('foo');

var s2 = Symbol('foo');

s1 === s2

//false

用途:通常在定义对象属性的时候使用它,(此时对象的属性名就是一个独一无二的字符串),是为了防止重复属性被覆盖的。

var obj = {

color: 'red',

color: 'green'

}

console.log(obj)

//  Object {color: "green"}

var key1 = Symbol('color');

var key2 = Symbol('color');

console.log(key1)  //Symbol(color)

console.log(key2)  //Symbol(color)

console.log(key2 == key1)   false

var obj = {

[key1]: 'red',

[key2]: 'green'

}

console.log(obj[key1])

// red

八:函数的拓展

箭头函数:

a:基础语法

function hello(name){
console.log(`hello ${name} !`)
}
const helloa=(name)=>{
console.log(`hello ${name} !`)
}
hello('xiaomei')
helloa('xiaomei')
//hello xiaomei !
//hello xiaomei !

b:this问题

setTimeout(()=>{
console.log("aaa");
// this问题
},1000)

c: 一行省略(){}

const double= x => x*2
console.log(double(5));
//10

d:默认参数问题
const hello = (name = "xiaomei")=>{
console.log(`hello ${name} !`)
}
hello();
// hello xiaomei !
hello("xiaoli");
// hello xiaoli !

d:展开符...
function hello(name1,name2){
console.log(name1,name2);
}
let arr=["xiaomei","xiaoli"];
hello.apply(null,arr);
//xiaomei xiaoli
hello(...arr);
//xiaomei xiaoli

(1)在ES6之前,不能直接为函数的参数指定默认值

function log(x, y) {

y = y || 'World';

console.log(x, y);

}

log('Hello')

//Hello World

log('Hello', 'China')

//Hello China

log('Hello', '')

//Hello World

上面检查函数log的参数y有没有赋值,如果没有,则指定默认值为World。这种写法的缺点在于,如果参数y赋值了,但是对应的布尔值为false,则该赋值不起作用。就像上面代码的最后一行,参数y等于空字符,结果被改为默认值。

解决办法:

if (typeof y === 'undefined') {

y = 'World';

}

先判断再赋值

ES6可以为函数设置默认值,直接写在参数定义的后面

function say (msg = 'hello') {

console.log(msg)

}

say ()

// hello

function log(x, y = 'World') {

console.log(x, y);

}

log('Hello')

//Hello World

log('Hello', 'China')

//Hello China

log('Hello', '')

//Hello

function Point(x = 0, y = 0) {

this.x = x;

this.y = y;

}

var p = new Point();

Log(p)

//Point {x: 0, y: 0}

如下参数变量是默认声明的,在函数体中,不能用let或const再次声明,否则会报错。

function foo(x = 5) {

let x = 1;

}

//Identifier 'x' has already been declared

function foo(x = 5) {

const x = 2;

}

//Identifier 'x' has already been declared

(2)Rest参数即剩余参数

用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

...语法可以实现对剩余参数的定义

注:在箭头函数中不能使用arguments

function add(...values) {

let sum = 0;

for (var val of values) {

sum += val;

}

return sum;

}

add(2, 5, 3)

// 10

function push(array, ...items) {

items.forEach(function(item) {

array.push(item);

console.log(item);

});

}

var a = [];

push(a, 1, 2, 3)

// 1

// 2

// 3

rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。

function f(a, ...b, c) {

// ...

}

//Rest parameter must be last formal parameter

 九:类的拓展

class App{
  constructor(){
    this.name="xiaomei"
  }
  sayhello(){
    console.log(`hello ${this.name} !`)
  }
}
const app=new App();
app.sayhello();
//hello xiaomei !

 十:模块化机制

export const name = "xiaomei";
export function add(){
console.log("xiaoli");
}
export default function minus(){
console.log("xiaolis");
}
import { name , add } from './路径地址';
import minus from './路径地址';
console.log(name);
add();
minus();
//"xiaomei"
//"xiaoli"
//"xiaolis"
*导入文件中所有命名为exportobg
import * as exportobg from './路径地址';

十一:箭头函数详解

箭头函数是ES6中新增一个函数表达形式,它是对函数的一种简化ES6允许使用“箭头”(=>)定义函数。

Eg:

var f = v => v;

等同于之前

var f = function(v) {

return v;

};

const Even = n => n % 2 == 0;

const Square = n => n * n;

注:

箭头函数就是省略了function

参数集与函数体之间一定要有一个箭头=>

对于参数集而言:

零个参数用 () 表示;

一个参数可以省略 ();

多参数不能省略 ();

Eg:

var f = () => 5;

// 等同于

var f = function () { return 5 };

var sum = (num1, num2) => num1 + num2;

// 等同于

var sum = function(num1, num2) {

return num1 + num2;

};

大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号。

Eg:

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

[1,2,3].map(function (x) {

return x * x;

});

//  [1, 4, 9]

[1,2,3].map(x => x * x);

//[1, 4, 9]

不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

const numbers = (...nums) => nums;

numbers(1, 2, 3, 4, 5)

// [1,2,3,4,5]

const haha = (head, ...tail) => [head, tail];

haha(1, 2, 3, 4, 5)

[1, Array[4]]

箭头函数有几个使用注意点。

(1) 箭头函数内部没有constructor方法,也没有prototype,所以不支持new操作。但是它对this的处理与一般的普通函数不一样。箭头函数的 this 始终指向函数定义时的 this,而非执行时。。

function foo() {

setTimeout(() => {

console.log('id:', this.id);

}, 100);

}

var id = 21;

foo.call({ id: 22 });

// id: 22

setTimeout的参数是一个箭头函数,这个箭头函数的定义生效是在foo函数生成时,而它的真正执行要等到100毫秒后。如果是普通函数,执行时this应该指向全局对象window,这时应该输出21。但是,箭头函数导致this总是指向函数定义生效时所在的对象(本例是{id: 22}),所以输出的是22。

var o = {

x : 1,

func : function() { console.log(this.x) },

test : function() {

setTimeout(function() {

console.log(this);

this.func();

}, 100);

}

};

o.test();

//Window {external: Object, chrome: true, document: document, CNT_SELECT: undefined, jQuery17105021754387381239: Object…}

// this.func is not a function(anonymous function)

出现错误,因为this的指向从o变为了全局(函数调用中的this都是指向全局的)。

var o = {

x : 1,

func : function() { console.log(this.x) },

test : function() {

var _this = this;

setTimeout(function() {

_this.func();

}, 100);

}

};

o.test();

// 1

先保存的this就行了。

var o = {

x : 1,

func : function() { console.log(this.x) },

test : function() {

setTimeout(() => { this.func() }, 100);

}

};

o.test();

// 1

(2)this是不会改变指向对象的

var x = 1,

o = {

x : 10,

test : () => this.x

};

o.test();

// 1

o.test.call(o);

//   1

十二:Promise对象

$.ajax({

url: '......',

success: function (data) {

$.ajax({

// 要在第一个请求成功后才可以执行下一步

url: '......',

success: function (data) {

// ......

}

});

}

});

当执行一些异步操作时,我们需要知道操作是否已经完成,当执行完成的时候会返回一个回调函数,表示操作已经完成。 再继续进行下一个接口请求。。。。。

回调函数的形式在实际的应用当中会有以下的缺点:

在需要多个操作的时候,会导致多个回调函数嵌套,导致代码不够直观。

如果几个异步操作之间并没有前后顺序之分(例如不需要前一个请求的结果作为后一个请求的参数)时,同样需要等待上一个操作完成再实行下一个操作。

为了解决上述的问题,Promise 对象应运而生

有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。一个允诺对象有三种状态,

Padding阶段 表示状态在进行

Resolved阶段 表示状态成功的结束

Rejected阶段 表示状态失败的结束

在允诺对象中只有两个两个执行的方向

一个是从padding状态进入resolved状态,表示异步操作成功执行完毕

一个是从padding状态进入rejected状态,表示异步操作失败执行完毕

Promise对象是一个构造函数,用来生成Promise实例。

var promise = new Promise(function(resolve, reject) {

// ... some code

if (/* 异步操作成功 */){

resolve(value);

} else {

reject(error);

}

});

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。

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

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

promise.then(function(value) {

// success

}, function(error) {

// failure

});

Promise实例生成以后,可以用then方法分别指定Resolved状态和Reject状态的回调函数。

then方法可以接受两个回调函数作为参数。

第一个回调函数是Promise对象的状态变为Resolved时调用,

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

允诺对象内部的状态不会受到外部的干扰,只有其内部改动才会改变状态

因此我们无法或者允诺对象当前处在哪个状态,

允诺对象一旦状态改变定义的允诺就会执行

Promise.all可以注册多个允诺对象,

当所有的允诺对象都执行成功时候会,成功回调函数才会执行

当遇到一个失败的就会立即执行失败的回调函数

function helloWorld (ready) {

return new Promise(function (resolve, reject) {

if (ready) {

resolve("Hello World!");

} else {

reject("Good bye!");

}

});

}

helloWorld(true).then(function (message) {

console.log(message);

}, function (error) {

console.log(error);

});

//Hello World!

helloWorld(true).then(function (message) {

console.log(message);

}, function (error) {

console.log(error);

helloWorld(false).then(function (message) {

console.log(message);

}, function (error) {

console.log(error);

});

// Good bye!

helloWord 函数接受一个参数,如果为 true 就打印 "Hello World!",如果为 false 就打印错误的信息。helloWord 函数返回的是一个 Promise 对象。

通过then方法可以定义诺言,两个参数

第一个参数定义成功时候的回调函数resolved状态

作用域是window

参数是执行resolve方法时候传递参数

第二个参数定义失败时候的回调函数rejected状态

作用域是window

参数是执行reject方法时候传递参数

Promise.all()
Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
var p = Promise.all([p1, p2, p3]);
Promise.all方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例

ECMAScript 6(ES6)常用语法的更多相关文章

  1. ES6常用语法

    ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015. 也就是说,ES6就是ES2015. ...

  2. ES6常用语法简介import export

    ES6常用语法简介import export let与var用法区别 //var var a = []; for (var i = 0; i < 10; i++) { a[i] = functi ...

  3. ES5与ES6常用语法教程之 ②解构语法糖、声明变量异同

    js常用语法系列教程如下 es5与es6常用语法教程(1) es5与es6常用语法教程(2) es5与es6常用语法教程(3) es5与es6常用语法教程(4) es5与es6常用语法教程(5) es ...

  4. vue学习(一)ES6常用语法

    1 ES6常用语法 1.1 变量提升 例① # 变量提升 <div id="app"> </div> <script> console.log( ...

  5. ES6 常用语法知识汇总

    ES6模块化如何使用,开发环境如何打包? 1.模块化的基本语法 /* export 语法 */ // 默认导出 export default { a: '我是默认导出的', } // 单独导出 exp ...

  6. ES6常用语法总结

    ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015.也就是说,ES6就是ES2015.虽 ...

  7. ES5与ES6常用语法教程之 ③模板字符串、判断字符串是否包含其它字符串

    这部分教程我们主要讲解以下几个常用语法 模板字符串 带标签的模板字符串 判断字符串中是否包含其他字符串 给函数设置默认值 模板字符串 老式的拼接字符串方法 let dessert = '

  8. ES6常用语法,面试应急专用!

    常用的ES6语法 注:该文章为转载,原地址为https://www.jianshu.com/p/fb019d7e8b15   什么是ES6? ECMAScript 6(以下简称ES6)是JavaScr ...

  9. ES6常用语法整合

    ES6也出来有一会时间了,他新增的语法糖也的确大大提高了开发者的效率,今天就总结一些自己用到最多的. 说到ES6肯定是先介绍Babel了,据阮一峰老师介绍到,Babel是一个广泛使用的转码器,可以将E ...

随机推荐

  1. [bugfix]copy属性参数将NSMutableArray变为NSArray类型

    问题:NSMutableArray 声明为 copy 属性参数后即使接受NSMutableArray变量依然为NSArray变量 测试: 属性申明为: 1 @property (nonatomic, ...

  2. HDU-5335

    Walk Out Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  3. hdu 1065(贪心)

    Wooden Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20938   Accepted: 8872 De ...

  4. Search in Rotated Sorted Array I&&II——二分法

    Search in Rotated Sorted Array I Suppose a sorted array is rotated at some pivot unknown to you befo ...

  5. 197. Rising Temperature

    Given a Weather table, write a SQL query to find all dates' Ids with higher temperature compared to ...

  6. Delphi使程序的窗口出现在最前面并激活

    procedure setAppFront(); //使程序的窗口出现在最前面并激活 var pt, OldPt, NewPt: TPoint; begin //判断Application是否最小化, ...

  7. CentOS7.5安裝配置多协议下载器Aria2

    一.搭建 Aria2 以及 AriaNg Web UI 使用Docker构建的Aria2 参考 aria2-ariang-docker 以及 aria2-ariang-x-docker-compose ...

  8. Kerberos KDC not reachable

    水贴..我这里出现这个问题的原因是服务器上安装的是 oracle  jdk, 但是没有安装 JCE 拓展包. 解决方式有两个: 1. 换成 openJDK 2. 安装上 JCE 拓展包 java 8 ...

  9. Codeforces 1131 A. Sea Battle-暴力 (Codeforces Round #541 (Div. 2))

    A. Sea Battle time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  10. JavaWeb中常见的乱码处理(亲测)

    常见编码方式: ISO-8859-1  西欧码 GB2312  简体中文码 GBK   大五码 UTF-8 全球码(推荐) 1.页面(HTML,JSP,Servlet) <%@ page lan ...