一、Let和Const
let声明变量,可重复定义
const定义常量,不可重复定义
产生块级作用域;可能会出现暂时性死区,在块级作用域外不能访问
二、解构赋值
对象解构
let person = {
name: 'zangsan',
age: 20,
//hobby:undefined 一定要是undefined 默认值生效 没有改属性 默认值也生效
//hobby:null 默认值不生效 hobby为null
}
var { name, age, hobby } = person // name:zangsan age:20 hobby:undefined
// 默认值 要想生效与之对应的属性值一定要是undefined
var { name: name, age: age, hobby = "打游戏" } = person// name:zangsan age:20 hobby:打游戏
//{ name:name1, age:age, hobby:hobby } = person //变量名处在后面
数组解构
var [a, b, c] = [1, 2, 3] //a:1 b:2 c:3
var [b, c, a] = [1, 2, 3] //b:1 c:2 a:3 //实现数据交换
/** 数组的本质是对象 对数组进行对象属性的解构 */
var arr = [1, 2, 3]
let { 0: first, [arr.length - 1]: last } = arr //first:1 last:3
let per = {
perInfo: {
basInfo: {
name: 'zhangsan',
age: 20
}
}
}
let { perInfo: { basInfo } } = per
console.log(basInfo.name) //zhangsan
字符串解构
let str1 = "hello";
console.log(str1[1]); 获取字符串中单个字母 e
// 字符串的元素不可以通过下标修改
str1[1] = "4"; //没有报错,但是不会修改
console.log(str1); //hello
// 字符串解构
let [a, b] = str1;
let [, , e, f, g] = str1;
console.log(a, b, e, f, g); // h e l l o
三、字符串的扩展
includes():参数:要查找的字符串。 返回布尔值,表是否找到了参数字符串
let str='hello word'
str.includes('') //true
str.includes(' ') //true
str.includes(' ') //false
str.includes('d') //true
endsWith():参数:要查找的字符串。返回布尔值,表参数字符串是否在源字符串的尾部
let str='hello word'
str.endsWith('') //true
str.endsWith(' ') //false
str.endsWith('d ') //false
str.endsWith('d') //true
starsWith():返回布尔值,表参数字符串是否在源字符串的头部
let str='hello word'
str.startsWith('') //true
str.startsWith(' ') //false
str.startsWith(' h') //false
str.startsWith('h') //true
repeat():参数:次数n。返回一个字符串,表示将原字符串重复n次
str='hello'
//参数是小数,会被取整.参数是负数或Infinity,会报错.参数在0-1之间,参数为NaN则等同于0
str.repeat(0.5)
str.repeat(1.5) //'hello'
str.repeat(2.5) //'hellohello'
padStar():头部补全 padEnd():尾部补全
参数1:指定字符串的最小长度。原字符串的长度等于或大于指定的最小长度,返回原字符串
参数2:用于补全的字符串,省略会用空格补全
若用于补全的字符串与原字符串之和超出了指定的最小长度,则会截去超出位数的补全字符串let date=new Date() //2022-5-19
let mon= (date.getMonth()+1).toString().padStart(2,0)//04 不满足2补0
let day= date.getDate().toString().padStart(2,0) //19 满足2不用补0
str='123'
str.padEnd(5,0) //'12300' 大于字符串长度补齐
str.padEnd(3,0) //'123' 等于字符串长度不用管
str.padStart(5) //' 123'
str.padEnd(2,'a') //'123' 小于字符串长度显示完整字符串
str.padEnd(5,'abcd')//'123ab'补全的字符串与原字符串之和超出了最小长度,截去超出位数的补全字符串
模板字符串
//` ` 变量用${}包裹
var age =28;
var info= `我今年${age}岁了` //我今年28岁了
四、数值的扩展
Number.isNaN():用于检查一个数值是否为NaN
Number.isNaN(NaN)//true
Number.isNaN(null)//false
Number.isNaN(undefined)//false
Number.isInteger():判断一个数是否为整数
Number.isInteger(-4) //true
Number.isInteger(-4.0) //true
Number.isInteger(4.1) //false
Number.isInteger(0) //true
Number.isSafeInteger():判断一个整数是否在这个范围之内(-9007199254740991,9007199254740991),返回布尔值
Number.isSafeInteger(1.4) //false
Number.isSafeInteger(-9007199254740991)//true
Number.isSafeInteger(9007199254740991)//true
Number.isSafeInteger(9007199254740992)//false
五、Math对象的扩展
Math.trunc():用于除去一个数的小数部分,返回整数部分
1. 对于非数值,内部将其先转化为数值 2. 对于空值和无法返回的值,返回NaN
Math.trunc(false)//0
Math.trunc(5.8)//5
Math.trunc(null)//0
Math.trunc(undefined)//NaN
Math.trunc(NaN)//NaN
Math.trunc({})//NaN
Math.trunc([])//0
Math.trunc('') //0
Math.sign():判断一个数到底是正数,负数,还是0
1. 参数为正数,返回+1。2. 参数为负数,返回-1。 3 参数为0,返回0。 4 参数为-0,返回-0。
Math.sign(null)//0
Math.sign([])//0
Math.sign('')//0
Math.sign({})//NaN
Math.sign(undefined)//NaN
Math.sign(NaN)//NaN
六、函数的扩展
ES6允许为函数设置默认值,即直接写在参数定义的后面
箭头函数与普通函数的区别,构造函数可以new生成实例 那箭头函数呢
1体内无this 。 2不可当构造函数。 3 arguments时不可以的。 不可以当作generator函数。
function fn(x =3) {
return function (y=5) {
return x + y
}
}
let fn = x => y => x + y
七、数组的扩展
Array.from():将伪数组(两类对象:类似于数组的对象)转换为真正的数组, 将数组的空位转换成为undefined
1.该类数组对象必须具有length属性,用于指定数组的长度。如果没有length属性,那么转换后的数组是一个空数组。
2.该类数组对象的属性名必须为数值型或字符串型的数字
3.转成数组的长度为leng属性的值
let arrayLike = {
0: 'tom',
1: '65',
2: '男',
3: ['jane','john','Mary'],
'length': 4
}
let arr = Array.from(arrayLike)
console.log(arr) // ['tom','65','男',['jane','john','Mary']]
let arrayLike = {
0: 'tom',
1: '65',
2: '男',
3: ['jane','john','Mary'],
'length': 3
}
let arr = Array.from(arrayLike)
console.log(arr) // ['tom','65','男']
let arrayLike = {
'name': 'tom',
'age': '65',
'sex': '男',
'friends': ['jane','john','Mary'],
length: 4 //
}
let arr = Array.from(arrayLike)
console.log(arr) // [ undefined, undefined, undefined, undefined ]
Array.from
还可以接受第二个参数,作用类似于数组的map
方法,用来对每个元素进行处理,将处理后的值放入返回的数组
let arr = [12,45,97,9797,564,134,45642]
let set = new Set(arr) //伪数组
console.log(Array.from(set, item => item + 1)) // [ 13, 46, 98, 9798, 565, 135, 45643 ]
let str = 'hello world!';
console.log(Array.from(str)) // ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d", "!"]
Array.of(一组值):将一组数转换为数组,若没有参数,则返回空数组
//这个方法的主要目的,是弥补数组构造函数Array()的不足
Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1
Array.of() // []
Array.of(undefined) // [undefined]
//Array当参数个数不少于2个时,Array()才会返回由参数组成的新数组。参数个数只有一个时,实际上是指定数组的长度
Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]
copyWithin():在当前数组内部将指定位置的成员复制到其他地方,然后返回数组(会修改数组)会将空位一起复制
target(必选):从该位置开始替换数据start(可选):从该位置开始读取数据,默认值为0,如果为负数,表示倒数end(可选):到该位置停止读取数据,默认等于数组长度,若为负,表示倒数[1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5]
//3号位直到数组结束的成员(4 和 5),复制到从 0 号位开始的位置,结果覆盖了原来的 1 和 2
[1, 2, 3, 4, 5].copyWithin(0, 3, 4) // [4, 2, 3, 4, 5] 将3号位复制到0号位
[1, 2, 3, 4, 5].copyWithin(0, -2, -1)// [4, 2, 3, 4, 5] -2相当于3号位,-1相当于4号位
[].copyWithin.call({length: 5, 3: 1}, 0, 3) // {0: 1, 3: 1, length: 5} 将3号位复制到0号位
fill():用于填充数组 , 会将空位视为数组正常的位置
1(必填):用于填充的给定值。2(可选):填充的起始位置。3(可选):填充的结束位置
new Array(len).fill(null) //创建长度为len的数组,每项赋值为null
new Array(3).fill(null) //[null,null,null]
new Array(3).fill(false) //[false,false,false]
new Array(6).fill(false,1,7) // [空白, false, false, false, false, false]
["New Delhi", "Mumbai", "Chennai", "Banglore"].fill(false,2,3)//['New Delhi', 'Mumbai', false, 'Banglore']
entries():对键值对的遍历; 把一个对象的键值以数组的形式遍历出来,结果和 for…in 一致,但不会遍历原型属性
const obj = { name: 'xixixi', age: '23' };
console.log(Object.entries(obj)); // [['name', 'xixixi'], ['age', '23']]
const arr1 = [{ a: 1 }, 2, 3];
console.log(Object.entries(arr1)); // [['0', { a: 1 }], ['1', '2'], ['2', '3']]
keys():对键名的遍历
var obj2 = {'name':'a','list':{'a':'value1','b':'value2'},'num':13}
var keyValue2 = Object.keys(obj2)
console.log(keyValue2) // ["name","list","num"]
var arr = ["a", "b", "c"];
console.log(Object.keys(arr)); // console: ["0", "1", "2"]
values():对键值的遍历
let person = {name:"张三",age:25,address:"深圳",getName:function(){}};
Object.values(person) // ["张三", 25, "深圳", ƒ]
//如果属性是数字,则会按照属性的大小按顺序返回
let obj={4:'a',2:'b',90:'c'};
Object.values(obj)//["b", "a", "c"]
Object.values([1,2,3,4])// [1, 2, 3, 4]
includes():表示某个数组是否包含给定的值,返回一个布尔值
1:给定值。2:搜索的起始位置,默认为0,如果为负值,则按升序从 array.length + 索引开始搜索。
var arr = [10,20,30,40,50];
arr.includes(10); //true
arr.includes(10,1); //false
var arr = [1,2,3,4];
arr.includes(1,-1); //false
arr.includes(2,-4); //true
八、对象的扩展
Object.is():比较两个值是否严格相等,与严格相等运算符(===)的行为基本一致(注:有两个不同之处1:+0不等于 -0、2:NaN等于自身)
Object.is(0, -0); // false
Object.is(-0, -0); // true
Object.is(NaN, 0 / 0); // true
Object.is([],[]) //false
Object.assign():将源对象的所有可枚举属性复制到目标对象 。 第一个参数是目标对象,后面的参数是源对象
不会在那些source对象值为 null 或 undefined 的时候抛出错误。其他类型的值(即数值、字符串和布尔值)不在首参数,也不会报错。但是,除了字符串会以数组形式,拷贝入目标对象,其他值都不会产生效果
const source1 = "aaa"; //当值为null
const source2 = false;
const source3 = 666
const currentTarget = Object.assign({}, source1, source2, source3);
console.log(currentTarget); //这里不会拷贝目标对象,还是{}
//{0: "a", 1: "a", 2: "a"}
JSON.Stringify(value[, replacer [, space]]):该函数的作用是:系列化对象,系列化对象说白了就是把对象的类型转换为字符串类型
只有一个参数
/**布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值**/
JSON.stringify({}); // 输出结果:{}
JSON.stringify(true); // 输出结果:true
JSON.stringify("foo"); // 输出结果:"foo"
JSON.stringify([1, "false", false]); // 输出结果:[1,"false",false]
JSON.stringify({ x: 5 }); // 输出结果:{"x":5}
JSON.stringify({x: 5, y: 6}); //输出结果:{"x":5,"y":6}
JSON.stringify([new Number(1), new String("false"), new Boolean(false)]); //输出结果[1,"false",false]
/**undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)**/
JSON.stringify({x: undefined, y: Object, z: Symbol("")}); // 输出结果:{}
JSON.stringify([undefined, Object, Symbol("")]); // 输出结果:[null,null,null]'
JSON.stringify({[Symbol("foo")]: "foo"}); // 输出结果:{}
JSON.stringify({[Symbol.for("foo")]: "foo"}, [Symbol.for("foo")]);// 输出结果:{}
JSON.stringify(
{[Symbol.for("foo")]: "foo"},
function (k, v) {
if (typeof k === "symbol"){
return "a symbol";
}
}
);
//输出结果:undefined
replacer 可选可以为数组或函数如果为数组:则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中,replacer作key值
如果为函数:则把系列化后的每一个对象(记住是每一个)传进方法里面进行处理
/**第二个参数为函数**/
function replacer(key, value) {
if (typeof value === "string") {
return undefined;
}
return value;
}
var foo = {foundation: "Mozilla", model: "box", week: 45, transport: "car", month: 7};
var jsonString = JSON.stringify(foo, replacer);
//输出结果:{"week":45,"month":7}
/** 第二个参数为数组 **/
var students = new Array();
students[0] = "pika";
students[1] = "hello";
students[2] = "hey";
var stu= new Array();
stu[0] = "how";
stu[1] = "are";
stu[2] = "u";
var json = JSON.stringify(students,stu);
alert(json);
//输出结果:["pika","hello","hey"]
space 可选
指定缩进用的空白字符串
如果省略的话,那么显示出来的值就没有分隔符。直接输出来
如果是一个数字的话,那么它就定义缩进几个字符,范围是:0到10(数字小于1,则默认为0,大于10,则默认为10)
如果是一些转义字符,比如“\t”,表示回车,那么它每行一个回车。
如果仅仅是字符串,就在每行输出值的时候把这些字符串附加上去就OK。当然,最大长度也是10个字符
JSON.stringify({ a: 2 }, null, " "); // 输出结果:{\n "a": 2\n}
JSON.stringify({ uno: 1, dos : 2 }, null, '\t')
/* 输出结果:
{
"uno": 1,
"dos": 2
}
*/
var students = new Object();
students.name = "pika";
students.age = 19;
students.qq = "12345678";
var stu= new Array();
stu[0] = "name";
stu[1] = "qq";
var json = JSON.stringify(students,stu,"test")
alert(json);
/* 输出结果:
{
test"name": "pika",
test"qq": "12345678"
}
*/
_ _ proto _ _属性:用于读取或者设置当前对象的prototype属性。缺点:兼容性和语义都不是很好
Object.setPrototypeOf(obj):用来设置一个对象的prototype属性,返回参数对象本身
参数:第一个参数若不是对象,则会自动转化为对象(undefined和null时会报错)
Object.getPrototypeOf():用于读取一个对象的prototype属性
参数:参数若不是对象,则会自动转化为对象(undefined和null时会报错)
Object.reate():生成对象
九、Symbol
/**
* symbol: 为了解决属性一样而导致后面覆盖前面的问题而诞生,
* symbol()创建的都是唯一值,除非使用symbol.for()创建
*/
Symbol('pg') == Symbol('pg') //false
Symbol.for('pg') == Symbol.for('pg') //true
let sym = Symbol.for('foo')
let asd = Symbol('foo')
Symbol.keyFor(sym) //foo
Symbol.keyFor(asd) //undefined
var person = {
name: 'xiaoming',
age: 12,
[Symbol('level')]: 'A'
}
// for in key不能拿到symbol属性
// for of key不能拿到symbol属性
// Object.keys() 不能拿到symbol属性
// Object.getOwnPropertyNames() 不能拿到symbol属性
// Object.getOwnPropertySymbols() 能拿到symbol属性和其他属性
// Reflect.ownKeys() 只拿到symbol属性和其他属性
十、Set:类似于数组,其成员唯一,不重复,Set本身是一个构造函数,用于生产Set数据结构
Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等。有几个特殊值需要特殊对待:
1.+0 与 -0 在存储判断唯一性的时候是恒等的,所以不重复;
2.undefined 与 undefined 是恒等的,所以不重复;
3.NaN 与 NaN 是不恒等的,但是在 Set 中只能存一个,不重复
const s2 = new Set(['a', 'b']);
console.log(s2); // Set(2)[a,b]
console.log(s2.size); // 2
const s3 = new Set(['a', 'a', 'b', 'b']);
console.log(s3.size); // 2
console.log(s3); //Set(2)[a,b] //set自动去重
/** 数组方法 **/
const s4 = new Set();
s4.add('a').add('b'); // 向set结构中添加值 使用add方法
console.log(s4.size) // 2
// s4 = Set{'a', 'b'}
const r1 = s4.delete('c'); 从set结构中删除值 用到的方法是delete 有返回值为布尔值
console.log(s4.size) // 2
console.log(r1); // false 表示删除失败
const r2 = s4.has('d'); // 判断某一个值是否是set数据结构中的成员 使用has
console.log(r2) // false 表示没有d这个成员
s4.clear(); // 清空set数据结构中的值 使用clear方法
console.log(s4.size); // 0
十一、Map 类似于对象,也是键值组合,其键的范围不限于字符串,可为各种数据类型的值(包括对象)均可当做键
map()
不会对空数组进行检测map()
不会改变原始数组(返回新数组)map()
不会为数组中缺少的元素调用回调函数除数组对象外,map()
可由具有length属性且具有已按数字编制索引名的任何对象使用(如字符串对象)
//array.map(function(currentValue, index, arr), thisIndex)
//currentValue:必须。当前元素的的值。
//index:可选。当前元素的索引。
//arr:可选。当前元素属于的数组对象。
//thisValue:可选。对象作为该执行回调时使用,传递给函数,用作"this"的值
var arr = [1,2,3].map(parseInt);
document.write(arr); //1,NaN,NaN
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);//Map(3) {'Michael' => 95, 'Bob' => 75, 'Tracy' => 85}
m.get('Michael'); // 95
1、size()返回Map结构的成员总数
2、set(key,value)设置key值所对应的键,然后返回Map结构, 若key已经有值,则赋值更新,否则新生成该键值
3、get(key)获取key对应的值,若找不到key则返回undefined
4、has(key)返回一个布尔值,表示ley是否在Map结构中
5、delete(key)删除某个键,删除成功则返回true,反之返回false
6、clear()清除所有成员,无返回值
十二、proxy
let p = new Proxy(target,handler);
//target:目标对象
//handler:用来定制拦截行为的对象(若不设置任何拦截,等同于直接通向原对象)
//get(target,propKey,receiver)拦截对象某个属性的读取,最后一个参数为可选对象
//set(target,propKey,value,receiver)
const target = { msg: "hello"};
const handler = {
set: function(target, prop, value, receiver){
target[prop] = value // return true
}};
const proxy = new Proxy(target, handler);
proxy.msg = 'wow' // 'wow'
//has(target,propKey)
var obj = {}
Object.defineProperty(obj, 'year', {
configurable: false,
value: 2})
var proxy = new Proxy(obj, {
has: function(target, prop) {
console.log('called: ' + prop);
return false;
}})
console.log('year' in proxy); //Identifier 'proxy' has already been declared
//deleteProperty(target,propKey)
var p = new Proxy({}, {
deleteProperty: function(target, prop) {
console.log('called: ' + prop);
return false; }});
delete p.a; // 会走deleteProperty函数
//defineProperty 拦截Object.getOwnPropertyDescriptor(proxy,propKey),返回属性的描述对象或undefined
//...
十三、Reflect
//设置target的name属性等于value,若name属性设置了赋值函数,则赋值函数的this绑定receiver,若第一个参数不是对象,则报错
Reflect.set(target,name,value,receiver)
var obj = {
name: 'houfee',
set func(value) {
return this.name = value
}
}
var obj2 = {
name: 'houyue'
}
console.log(Reflect.set(obj, 'name', 'houyue')) // true
console.log(Reflect.set(obj, 'func', 'houyue')) // true
console.log(obj) // {name: "houyue", age: 24}
Reflect.get(target,name,receiver)//查找并返target对象的那么属性,若没有则返回undefined
var obj = {
name: 'houfee',
age: 24,
get func() {
return this.name + this.age
}
}
console.log(Reflect.get(obj, 'name')) // houfee
console.log(Reflect.get(obj, 'age')) // 24
console.log(Reflect.get(obj, 'func')) // houfee24
若那么属性部署了读取函数,则读取函数的this绑定receiver
Reflect.has(obj,name)//对应name in obj中的in运算符
var myObject = {
foo: 1,
};
console.log('foo' in myObject); // true // 旧写法
console.log(Reflect.has(myObject, 'foo')); // true // 新写法
Reflect.deletePrototypety(obj,name)//删除对象的属性,等同于delete obj[name]
const myObj = {
foo: 'bar'
};
delete myObj.foo; // 旧写法
Reflect.deleteProperty(myObj, 'foo');// 新写法
Reflect.getPrototyprOf(obj)//读取对象的 _ _ proto _ _属性,等同于Object.getPrototype(obj)
function Func(name) {
this.name = name
}
// new 的写法
const instance = new Func('张三')
Object.getPrototypeOf(instance) === Func.prototype
// Reflect.construct 的写法
const instance = Reflect.construct(Func, ['张三'])
Reflect.getPrototypeOf(instance) === Func.prototype
十四、promise
promise对象代表一个异步 *** 作,三种状态: 1. Pending:进行中 2. Fulfilled:已成功 3. Rejected:已失败
//1. then , catch
function promiseClick(){
let p = new Promise(function(resolve, reject){
setTimeout(function(){
var num = Math.ceil(Math.random()*20); //生成1-10的随机数
console.log('随机数生成的值:',num)
if(num<=10){
resolve(num);
}
else{
reject('数字太于10了即将执行失败回调');
}
}, 2000);
})
return p
}
promiseClick().then(
function(data){ //resolve成功走这里
console.log('resolved成功回调');
console.log('成功回调接受的值:',data);
},
function(reason){ //reject 失败走这里
console.log('rejected失败回调');
console.log('失败执行回调抛出失败原因:',reason);
}
).catch(function(reason, data){ //分开catch reject 失败走这里
console.log('catch到rejected失败回调');
console.log('catch失败执行回调抛出失败原因:',reason);
});
//2. Promise.all() 等到它们都执行完后才会进到then里面
function promiseClick1(){
let p = new Promise(function(resolve, reject){
setTimeout(function(){
var num = Math.ceil(Math.random()*20); //生成1-10的随机数
console.log('随机数生成的值:',num)
if(num<=10){
resolve(num);
}
else{
reject('数字太于10了即将执行失败回调');
}
}, 2000);
})
return p
}
function promiseClick2(){
let p = new Promise(function(resolve, reject){
setTimeout(function(){
var num = Math.ceil(Math.random()*20); //生成1-10的随机数
console.log('随机数生成的值:',num)
if(num<=10){
resolve(num);
}
else{
reject('数字太于10了即将执行失败回调');
}
}, 2000);
})
return p
}
function promiseClick3(){
let p = new Promise(function(resolve, reject){
setTimeout(function(){
var num = Math.ceil(Math.random()*20); //生成1-10的随机数
console.log('随机数生成的值:',num)
if(num<=10){
resolve(num);
}
else{
reject('数字太于10了即将执行失败回调');
}
}, 2000);
})
return p
}
Promise
.all([promiseClick3(), promiseClick2(), promiseClick1()])
.then(function(results){
console.log(results);
});
//3. promise.race()先执行完成就先执行回调。先执行完的不管是进行了race的成功回调还是失败回调,其余的将不会再进入race的任何回调
function promiseClick1(){
let p = new Promise(function(resolve, reject){
setTimeout(function(){
var num = Math.ceil(Math.random()*20); //生成1-10的随机数
console.log('2s随机数生成的值:',num)
if(num<=10){
resolve(num);
}
else{
reject('2s数字太于10了即将执行失败回调');
}
}, 2000);
})
return p
}
function promiseClick2(){
let p = new Promise(function(resolve, reject){
setTimeout(function(){
var num = Math.ceil(Math.random()*20); //生成1-10的随机数
console.log('3s随机数生成的值:',num)
if(num<=10){
resolve(num);
}
else{
reject('3s数字太于10了即将执行失败回调');
}
}, 3000);
})
return p
}
function promiseClick3(){
let p = new Promise(function(resolve, reject){
setTimeout(function(){
var num = Math.ceil(Math.random()*20); //生成1-10的随机数
console.log('4s随机数生成的值:',num)
if(num<=10){
resolve(num);
}
else{
reject('4s数字太于10了即将执行失败回调');
}
}, 4000);
})
return p
}
Promise
.race([promiseClick3(), promiseClick2(), promiseClick1()])
.then(function(results){
console.log('成功',results); //接收最先执行完的回调,最先执行的返回是resolve
},function(reason){
console.log('失败',reason); //接收最先执行完的回调,最先执行的返回是reject
});
十五、Iterato和for…of循环
Iterator遍历过程
创建一个指针对象,指向当前数据结构的起始位置(遍历器对象本质是一个指针对象)
第一次调用指针对象的next()方法,将指针指向数据结构的第一个成员
第二次使用指针对象的next()方法,指针就指向数据结构的第二个成员
不断调用指针对象的next()方法,直到指针指向数据结构的结束位置
var arr = [1, 2, 3]
console.log(arr[Symbol.iterator]) // ƒ values() { [native code] }
var iterator = arr[Symbol.iterator]()
console.log(iterator.next()) //{value: 1, done: false} 数组1
console.log(iterator.next()) //{value: 2, done: false} 数组2
console.log(iterator.next()) //{value: 3, done: false} 数组3 当为false 继续执行
console.log(iterator.next()) //{value: undefined, done: true}当为true 停止迭代
var oj = {
name: 'zs',
age: 20,
[Symbol('level')]: 'A'
}
Object.keys(oj) //[name , age] 遍历不出第三个
Reflect.ownKeys(oj) //[name , age ,Symbol(level) ] 能遍历出第三个
//例: let obj={x:1,y:2,z:3} console.log(obj)=>[1,2,3]
var obj = { x: 1, y: 2, z: 3 }
console.log([...obj]) //此时报错 obj is not iterable
obj[Symbol.iterator] = function () {
return {
next: function () {
let objarr = Reflect.ownKeys(obj)//Object.keys(oj) 不严谨 如上
if (this.index < objarr.length - 1) {
let key = objarr[this.index]
this.index++
return {
value: obj[key]
}
} else {
return { done: true }
}
},
index: 0
}
};
console.log([...obj]) //此时能解构 [1,2,3]
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)