console.log(
'******set******');
const s=
new Set();
[
2,
3,
5,
4,
5,
2,
2].forEach(x=>s.add(x));
for (
let i 
of s){
    
console.log(i);
}
console.log(
'spread');
const set2=
new Set([
1,
2,
3,
4,
5,
5,
5]);
console.log(...[
1,
2,
3]);
console.log(
1,...[
2,
3,
4],
5);
let arr1=[
0,
1,
2];
let arr2=[
3,
4,
5];
arr1.push(...arr2);
console.log(arr1);
let a=[
'a',
'b',
'c'];
let b=[
'e',
'f',
'g'];
let c=[
'j',
'k',
'l'];
console.log([...a,...b,...c]);
console.log([...
'hello world']);
console.log(
'x\uD83D\uDE80y'.length);
console.log(
'x\uD83D\uDE80y')
console.log([...
'x\uD83D\uDE80y'].length)
let map=
new Map([
    [
1,
'one'],
    [
2,
'two'],
    [
3,
'three']
]);
let map_arr=[...map.keys()];
console.log(
'*****map******')
console.log(map_arr)
console.log([...map.values()])
let go=
function *() {
    yield 
1;
    yield 
2;
    yield 
3;
};
console.log(
'generator')
console.log([...go()])
//TypeError: Obj[Symbol.iterator] 
is not a 
function
// let Obj={
a:
1,
b:
2}
// console.log([...Obj]);
let arrayLike={
  
'0':
'a',
  
'1':
'b',
  
'2':
'c',
  
length:
3
};
console.log(Array.from(arrayLike))
//只要是部署了Iterator接口的数据结构,Array.from都能将其转为数组
console.log(Array.from(
'hello'))
console.log(Array.from(
new Set([
'a',
'b'])))
console.log(Array.from([
1,
2,
3]))
console.log(
typeof Array.
of(
3,
11,
8))
console.log(Array.
of(
3))
console.log(
new Array(
3,
23,
2222))
console.log(Array())
console.log(Array(
3))
console.log([
1,
2,
3,
4,
5,
6,
7].copyWithin(
0,
3,
4))
console.log([
1,
2,
3,
4,
5].copyWithin(
0,-
2,-
1));
console.log([].copyWithin.call({
length:
5,
3:
1},
0,
3))
console.log([].copyWithin.call(
new Int32Array([
1,
2,
3,
4,
5]),
0,
3,
4))
// [
1,
4,-
5,
10].find
((n) => {n<0})
console.log('---------');
let x=[1,5,10,15];
let y=x.find(function (value,index,arr) {
    // console.log(index)
    // console.log(arr)
    return value>9;
});
console.log(y);
console.log('---------');
let n=x.findIndex(function (value,index,arr) {
    return value >10;
});
console.log(n);
console.log('---------');
console.log([NaN].indexOf(NaN))
console.log('---------');
// console.log([NaN].findIndex(y => Object.is(NaN,y)))
console.log([NaN].findIndex(function (value) {
    return Object.is(NaN,value);
}));
console.log([NaN].findIndex(function (y) {
    return Object.is(NaN,y)
}));
//用于填充数组
console.log(['a','b','c'].fill(7))
//指定位置填充数据
console.log(['a','b','c','d'].fill('yang',1))
console.log('数组遍历');
let ss=['a','b'];
for (let index of ss.keys()){
    console.log(index);
}
// for (let elem of ss.values()){
//     console.log(elem)
// }
for (let [index,elem] of ss.entries()){
    console.log(index,elem)
}
let letter=['a','b','c'];
let entries=letter.entries()
console.log(entries.next().value)
console.log(entries.next().value)
console.log(entries.next().value)
console.log('Array.prototype.includes')
console.log([1,2,3].includes(2))
console.log(['yamng','yan','yang'].includes('yan'))
console.log([1,2,NaN].includes(NaN))
console.log('---------');
console.log(isNaN(NaN))
console.log(Object.is(NaN,NaN))
console.log(Object.is(NaN,0))
//Map 结构的has方法,是用来查找键名的
//Set 结构的has方法,是用来查找值的
let getJSON=function (url) {
    let promise=new Promise(function (resolve,reject) {
        let client=new XMLHttpRequest();
        client.open('GET',url);
        client.onreadystatechange=handler;
        client.responseType="json";
        client.setRequestHeader("Accept","application/json");
        client.send()
        function handler() {
            if (this.readyState!==4){
                return;
            }
            if (this.stats===200){
                resolve(this.response);
            } else {
                reject(new Error(this.statusText))
            }
        }
    })
    return promise;
}
getJSON("/posts.json").then(function (json) {
    console.log('Contents:'+json)
},function (error) {
    console.log('出错了',error)
})
//如果调用resolve函数和reject函数时带有参数,
// 那么它们的参数会被传递给回调函数。
// reject函数的参数通常是Error对象的实例,表示抛出的错误
// resolve函数的参数除了正常的值以外,还可能是另一个 Promise 实例
let p1=new Promise(function (resolve,reject) {
    //.....
});
let p2=new Promise(function (resolve,reject) {
    //.....
    resolve(p1);
});
let x1=new Promise(function (resolve,reject) {
    setTimeout(() => reject(new Error('fail')),3000);
});
let x2=new Promise(function (resolve,reject) {
   setTimeout(() => resolve(x1),1000);
   setTimeout(() => resolve(x1),2000);
   setTimeout(function () {
       resolve(x1);
   },5000)
});
x2
    .then(result => console.log(result))
    .catch(error => console.log(error));
//注意,调用resolve或reject并不会终结 Promise 的参数函数的执行
new Promise((resolve,reject) => {
    resolve(1);
    console.log()
})
new Promise((resolve,reject) => {
    resolve(1);
    console.log(2);
    setTimeout(() => {
        console.log('settimeot 2s exe');
    },2000)
}).then(r => {
    console.log(r)
});
//立即 resolved 的 Promise 是在本轮事件循环的末尾执行,
// 总是晚于本轮循环的同步任务
new Promise((resolve,reject) => {
   return resolve('yangqiang');
   console.log('sync log');
}).then((message) => {
    console.log(message);
    return 'hello'
}).then(function (message) {
    console.log(message)
});
//then()方法返回的是一个Promise对象,
new Promise((resolve,reject) => {
    let post;
    return  post;
    //....
}).then(function (post) {
    return new Promise();
}).then(function (success) {
    console.log(success);
},function (error) {
    return Error();
}).catch(err => {
    console.log(err)
});
//下面三种写法是等价的
let pro=new Promise(function (resolve,reject) {
    throw new Error('test');
});
pro.catch(function (error) {
    console.log(error);
});
let por=new Promise(function (resolve,reject) {
    try {
        throw new Error('test');
    } catch (e){
        reject(e);
    }
});
por.catch(function (error) {
    console.log(error)
});
let opr=new Promise((resolve,reject) => {
    reject(new Error('test'));
});
opr.catch(function (error) {
    console.log(error)
});
let orp=new Promise((resolve,reject) => {
    resolve('ok');
    throw new Error('test');
});
orp.then((value) => {
    console.log(value)
}).catch(function (error) {
    //这里无法捕捉异常,以为promise的状态一旦改变,就会保持状态
    console.log(error)
});
//如果没有使用catch方法指定错误处理的回调函数
// Promise对象抛出的错误不会传递到外层代码,即不会有任何反应
//下面代码说明的是then代替catch捕捉异常,但是部建议这么做
new Promise().then(null,(err) => {
    console.log(err)
});
new Promise().catch((err) => {
    console.log(err)
});
//
let someAsyncThing = function() {
    return new Promise(function(resolve, reject) {
        // 下面一行会报错,因为x没有声明
        resolve(x + 2);
    });
};
someAsyncThing().then(function() {
    console.log('everything is great');
});
//someAsyncThing函数产生的 Promise 对象会报错,
// 但是由于没有指定catch方法,这个错误不会被捕获,也不会传递到外层代码。
// 正常情况下,运行后不会有任何输出,但是浏览器此时会打印出错误“ReferenceError: x is not defined”,
// 不过不会终止脚本执行,如果这个脚本放在服务器执行,退出码就是0(即表示执行成功)
let promisee = new Promise(function (resolve, reject) {
    resolve('ok');
    setTimeout(function () { throw new Error('test') }, 0)
});
promisee.then(function (value) { console.log(value) });
//上面代码Promise指定在下一轮循环再抛出错误,到那个时候promise已经运行结束了
//因为promise的状态已经改变,所以这个错误是在promise函数体外抛出的
//会冒泡到最外层,成了未捕获的错误
//catch()后面还可以接then()方法
//catch()方法里面也可以抛出错误