精读阮一峰 ECMAScript 6 入门 阶段1

72 阅读6分钟
  console.log(codePoint)
}

let greeting = `\`Yo\` World!`;
console.log(greeting);

let greetings=`${{i:5}}`
console.log(greetings);

const tmpl = addrs => `
  <table>
  ${addrs.map(addr => `
    <tr><td>${addr.first}</td></tr>
    <tr><td>${addr.last}</td></tr>
  `).join('')}
  </table>
`;

const data = [
    { first: '<Jane>', last: 'Bond' },
    { first: 'Lars', last: '<Croft>' },
];

console.log(tmpl(data));

let a = 5;
let b = 10;

function tag(s, v1, v2) {
    console.log(s[0]);
    console.log(s[1]);
    console.log(s[2]);
    console.log(v1);
    console.log(v2);
  
    return "OK";
  }
  
tag`Hello ${ a + b } world ${ a * b }`;
等同于
tag(['Hello ', ' world ', ''], 15, 50);

let total = 30;
let msg = passthru`The total is ${total} (${total*1.05} with tax)`;

function passthru(literals) {
    console.log(literals,arguments);

  let result = '';
  let i = 0;

  while (i < literals.length) {
    result += literals[i++];
    if (i < arguments.length) {
      result += arguments[i];
    }
  }

  return result;
}

console.log(msg);
let sender = '<script>alert("abc")</script>'; // 恶意代码
let message =
  SaferHTML`<p>${sender} has sent you a message.</p>`;

function SaferHTML(templateData) {
  let s = templateData[0];
  for (let i = 1; i < arguments.length; i++) {
    let arg = String(arguments[i]);

    // Escape special characters in the substitution.
    s += arg.replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;");

    // Don't escape special characters in the template.
    s += templateData[i];
  }
  return s;
}

console.log(message);

console.log`123`

var s = "𠮷";

s.length // 2
s.charAt(0) // ''
s.charAt(1) // ''
s.charCodeAt(0) // 55362
s.charCodeAt(1) // 57271

let s = 'Hello world!';

s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true

console.log('aabbcc'.replaceAll('b', '_'));

console.log('abbc'.replaceAll('b', '$&'));

console.log('abbc'.replace(/(ab)(bc)/g, '$2$1'));

const str = '123abc456';
const regex = /(\d+)([a-z]+)(\d+)/g;

function replacer(match, p1, p2, p3, offset, string) {
  return [p1, p2, p3].join();
}

let a =str.replace(regex, replacer)
console.log(a);


const str = 'hello';
str.at(1) // "e"

console.log(str.at(1))

console.log(/^\uD83D/u.test('\uD83D\uDC2A'));//UTF-16
console.log(/^\uD83D/.test('\uD83D\uDC2A'));//UTF-8

var s = '𠮷';

console.log(/^.$/.test(s) );// false
console.log(/^.$/u.test(s)); // true

/\u{61}/.test('a') // false
/\u{61}/u.test('a') // true
/\u{20BB7}/u.test('𠮷') // true

console.log(Number('0b111'));

console.log(Number.isInteger(25.0));
function throwIfMissing() {
    throw new Error('Missing parameter');
  }
  
  function foo(mustBeProvided = throwIfMissing()) {
    return mustBeProvided;
  }
  
  foo('fff')

function doSomething(value = 070) {
    'use strict';
    return value;
  }

const doSomething = (function () {
    'use strict';
    return function(value = 42) {
      return value;
    };
  }());

console.log((new Function).name);

function foo() {
    setTimeout(() => {
      console.log('id:', this.id);
    }, 100);
  }
  
  var id = 21;
  
  foo.call({ id: 42 });

function Timer() {
    this.s1 = 0;
    this.s2 = 0;
    // 箭头函数
    setInterval(() => this.s1++, 1000);
    // 普通函数
    setInterval(function () {
      this.s2++;
    }, 1000);
  }
  
  var timer = new Timer();
  
  setTimeout(() => console.log('s1: ', timer.s1), 3100);
  setTimeout(() => console.log('s2: ', timer.s2), 3100);

function foo() {
    return () => {
      return () => {
        return () => {
          console.log('id:', this.id);
        };
      };
    };
  }
  
  var f = foo.call({id: 1});
  
  var t1 = f.call({id: 2})()(); // id: 1
  var t2 = f().call({id: 3})(); // id: 1
  var t3 = f()().call({id: 4}); // id: 1

function foo() {
    setTimeout(() => {
      console.log('args:', arguments);
    }, 100);
  }
  
  foo(2, 4, 6, 8)

(function() {
    return [
      (() => this.x).bind({ x: 'inner' })()
    ];
  }).call({ x: 'outer' });

s = 21;

const obj = {
  s: 42,
  m: () => console.log(this.s)
};

obj.m() // 21

function Fibonacci2 (n , ac1 = 1 , ac2 = 1) {
    if( n <= 1 ) {return ac2};
  
    return Fibonacci2 (n - 1, ac2, ac1 + ac2);
  }
  
  Fibonacci2(100) // 573147844013817200000
  Fibonacci2(1000) // 7.0330367711422765e+208
  Fibonacci2(10000) // Infinity

function currying(fn, n) {
    return function (m) {
      return fn.call(this, m, n);
    };
  }
  
  function tailFactorial(n, total) {
    if (n === 1) return total;
    return tailFactorial(n - 1, n * total);
  }
  
  const factorial = currying(tailFactorial, 1);
  
  factorial(5) // 120

function restricted(a,b) {
    console.log(restricted.caller);    // 报错
    console.log(restricted.arguments); // 报错
  }
  restricted(1,2);

function sum(x, y) {
    if (y > 0) {
      return sum(x + 1, y - 1);
    } else {
      return x;
    }
  }
  
  sum(1, 100000)

try {
    // ...
  } catch {
    // ...
  }

const arr = [
    ...(x > 0 ? ['a'] : []),
    'b',
  ];

  console.log(arr);

console.log([...'hello']);

Number.prototype[Symbol.iterator] = function*() {
    let i = 0;
    let num = this.valueOf();
    while (i < num) {
      yield i++;
    }
  }
  
  console.log([...5]) // [0, 1, 2, 3, 4]

let map = new Map([
    [1, 'one'],
    [2, 'two'],
    [3, 'three'],
  ]);
  
  let arr = [...map.keys()]; // [1, 2, 3]

Array.from('hello')
// ['h', 'e', 'l', 'l', 'o']

let namesSet = new Set(['a', 'b'])
Array.from(namesSet) // ['a', 'b']

function typesOf () {
    return Array.from(arguments, value => typeof value)
  }

  console.log(typesOf(null, [], NaN));

  Array.of(3, 11, 8)

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

let letter = ['a', 'b', 'c'];
let entries = letter.entries();
console.log(entries.next().value); // [0, 'a']
console.log(entries.next().value); // [1, 'b']
console.log(entries.next().value); // [2, 'c']

const contains = (() =>
  Array.prototype.includes
    ? (arr, value) => arr.includes(value)
    : (arr, value) => arr.some(el => el === value)
)();
contains(['foo', 'bar'], 'baz'); // => false

console.log([1, 2, [3, 4]].flat());

console.log([1, 2, [3, [4, 5]]].flat(2));

console.log([1, 2, , 4, 5].flat());

[2, 3, 4].flatMap((x) => [x, x * 2])

const cart = {
    _wheels: 4,
  
    get wheels () {
      return this._wheels;
    },
  
    set wheels (value) {
      if (value < this._wheels) {
        throw new Error('数值太小了!');
      }
      this._wheels = value;
    }
  }

const obj = {
    get foo() {},
    set foo(x) {}
  };

  const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');

  console.log(descriptor.get.name);
  console.log(descriptor.set.name);

const key1 = Symbol('description');
const key2 = Symbol();
let obj = {
  [key1]() {},
  [key2]() {},
};
console.log(obj[key1].name); // "[description]"
console.log(obj[key2].name); // ""

const proto = {
    x: 'hello',
    foo() {
      console.log(this.x);
    },
  };
  
  const obj = {
    x: 'world',
    foo() {
      super.foo();
    }
  }
  
  Object.setPrototypeOf(obj, proto);
  
  obj.foo() // "world"

let foo = { ...['a', 'b', 'c'] };

console.log(foo);

console.log({...'hello'});

const target = { a: 1 };

const source1 = { b: 2 };
const source2 = { c: 3 };

let x = Object.assign(target, source1, source2);
console.log(target===x); // {a:1, b:2, c:3}

const obj = {
    foo: 123,
    get bar() { return 'abc' }
  };
  
  console.log(Object.getOwnPropertyDescriptors(obj));

function getOwnPropertyDescriptors(obj) {
    const result = {};
    for (let key of Reflect.ownKeys(obj)) {
      result[key] = Object.getOwnPropertyDescriptor(obj, key);
    }
    return result;
  }

let mix = (object) => ({
    with: (...mixins) => mixins.reduce(
      (c, mixin) => Object.create(
        c, Object.getOwnPropertyDescriptors(mixin)
      ), object)
  });
  
  // multiple mixins example
  let a = {a: 'a'};
  let b = {b: 'b'};
  let c = {c: 'c'};
  let d = mix(c).with(a, b);
  console.dir(d);
  
console.log(Object.getPrototypeOf(1));

console.log(Object.getOwnPropertyDescriptors(Number(12)));

console.log(Object.entries({ [Symbol()]: 123, foo: 'abc' }));

const obj = { foo: 'bar', baz: 42 };
const map = new Map(Object.entries(obj));
console.log(map);

const obj=Object.fromEntries([
    ['foo', 'bar'],
    ['baz', 42]
  ])

  console.log(obj);
console.log(
Object.fromEntries(new URLSearchParams('foo=bar&baz=qux'))
);

let s1 = Symbol('foo');
let s2 = Symbol('bar');

s1 // Symbol(foo)
s2 // Symbol(bar)

console.log(s1.toString()); // "Symbol(foo)"
s2.toString(s2.toString()) // "Symbol(bar)"

const obj = {
    toString() {
      return 'abc';
    }
  };

  const sym = Symbol(obj);

  console.log(typeof sym);

const sym = Symbol('foo');

console.log(String(sym)); // "Symbol(foo)"
console.log(sym.toString()); // "Symbol(foo)"
console.log(sym.description);

const obj = {};
const foo = Symbol('foo');

obj[foo] = 'bar';

for (let i in obj) {
  console.log(i); // 无输出
}

Object.getOwnPropertyNames(obj) // []
Object.getOwnPropertySymbols(obj) // [Symbol(foo)]

let obj = {
    [Symbol('my_key')]: 1,
    enum: 2,
    nonEnum: 3
  };
  
  console.log(Reflect.ownKeys(obj));

console.log(Symbol.for("bar") === Symbol.for("bar"));

function foo() {
    return Symbol.for('bar');
  }
  
  const x = foo();
  const y = Symbol.for('bar');
  console.log(x === y); // true

class MyClass {
    [Symbol.hasInstance](foo) {
        console.log("====================");
      return foo instanceof Array;
    }
  }
  
  console.log([1, 2, 3] instanceof new MyClass() );

class A1 extends Array {
    constructor(args) {
      super(args);
      this[Symbol.isConcatSpreadable] = true;
    }
  }
  class A2 extends Array {
    constructor(args) {
      super(args);
    }
    get [Symbol.isConcatSpreadable] () {
      return false;
    }
  }
  let a1 = new A1();
  a1[0] = 3;
  a1[1] = 4;
  let a2 = new A2();
  a2[0] = 5;
  a2[1] = 6;
 console.log( [1, 2].concat(a1).concat(a2));

class MyArray extends Array {
    static get [Symbol.species]() { return Array; }
  }
  
  const a = new MyArray();
  const b = a.map(x => x);
  
 console.log( b instanceof MyArray); // false
 console.log( b instanceof Array); // true

console.log("e".match("hello xx"));

class MySearch {
    constructor(value) {
      this.value = value;
    }
    [Symbol.search](string) {
        console.log(string);
      return string.indexOf(this.value);
    }
  }
  'foobar'.search(new MySearch('foo')) // 0

const myIterable = {};

myIterable[Symbol.iterator] = function* () {
  yield 1;
  yield 2;
  yield 3;
};

console.log([...myIterable] instanceof Array); // [1, 2, 3]

class Collection {
    *[Symbol.iterator]() {
        console.log("1111111");
      let i = 0;
      while(this[i] !== undefined) {
        yield this[i];
        ++i;
      }
    }
  }
  
  let myCollection = new Collection();
  myCollection[0] = 1;
  myCollection[1] = 2;
  
  for(let value of myCollection) {
    console.log(value);
  }

let obj = {
    [Symbol.toPrimitive](hint) {
      switch (hint) {
        case 'number':
          return 123;
        case 'string':
          return 'str';
        case 'default':
          return 'default';
        default:
          throw new Error();
       }
     }
  };
  
  console.log(2 * obj); // 246
  console.log(3 + obj); // '3default'
  console.log(obj == 'default'); // true
  console.log(String(obj)); // 'str'

console.log({[Symbol.toStringTag]: 'Foox'}.toString());

var obj = new Proxy({}, {
    get: function (target, propKey, receiver) {
      console.log(`getting ${target} ${propKey.toString()} ${receiver}!`);
      return Reflect.get(target, propKey, receiver);
    },
    set: function (target, propKey, value, receiver) {
      console.log(`setting ${target} ${propKey.toString()} ${value} ${receiver}!`);
      return Reflect.set(target, propKey, value, receiver);
    }
  });

  obj.count = 1

var proxy = new Proxy({}, {
    get: function(target, propKey) {
      return 35;
    }
  });
  
  console.log(proxy.time); // 35
  proxy.name // 35
  proxy.title // 35

var target = {};
var handler = {};
var proxy = new Proxy(target, handler);
proxy.a = 'b';
console.log(target.a );// "b"

var proxy = new Proxy({}, {
    get: function(target, propKey) {
      return 35;
    }
  });
  
  let obj = Object.create(proxy);
console.log(  obj.time );// 35

var handler = {
    get: function(target, name) {
      if (name === 'prototype') {
        return Object.prototype;
      }
      return 'Hello, ' + name;
    },
  
    apply: function(target, thisBinding, args) {
        console.log(args);
      return args[0];
    },
  
    construct: function(target, args) {
        console.log(args instanceof Array);
      return {value: args[1]};
    }
  };
  
  var fproxy = new Proxy(function(x, y) {
    return x + y;
  }, handler);
  
  fproxy(1, 2) // 1
  new fproxy(1, 2) // {value: 2}
  fproxy.prototype === Object.prototype // true
  fproxy.foo === "Hello, foo" // true

function createArray(...elements) {
    let handler = {
      get(target, propKey, receiver) {
        let index = Number(propKey);
        if (index < 0) {
          propKey = String(target.length + index);
        }
        return Reflect.get(target, propKey, receiver);
      }
    };
  
    let target = [];
    target.push(...elements);
    return new Proxy(target, handler);
  }
  
  let arr = createArray('a', 'b', 'c');
  console.log(arr[-2]); // c

var pipe = function (value) {
    var funcStack = [];
    var oproxy = new Proxy({} , {
      get : function (pipeObject, fnName) {
          console.log(fnName);
        if (fnName === 'get') {
          return funcStack.reduce(function (val, fn) {
            return fn(val);
          },value);
        }
        funcStack.push(window[fnName]);
        return oproxy;
      }
    });
    return oproxy;
  }
  
  var double = n => n * 2;
  var pow    = n => n * n;
  var reverseInt = n => n.toString().split("").reverse().join("") | 0;
  
  pipe(3).double.pow.reverseInt.get; // 63

const proxy = new Proxy({}, {
    get: function(target, key, receiver) {
      return receiver;
    }
  });

  console.log(proxy.getReceiver == proxy); // true

const proxy = new Proxy({}, {
    get: function(target, key, receiver) {
      return receiver;
    }
  });
  
  const d = Object.create(proxy);
  console.log(d.a === d); // true

const handler = {
    get (target, key) {
      invariant(key, 'get');
      return target[key];
    },
    set (target, key, value) {
      invariant(key, 'set');
      target[key] = value;
      return true;
    }
  };
  function invariant (key, action) {
    if (key[0] === '_') {
      throw new Error(`Invalid attempt to ${action} private "${key}" property`);
    }
  }
  const target = {};
  const proxy = new Proxy(target, handler);
  proxy._prop
  // Error: Invalid attempt to get private "_prop" property
  proxy._prop = 'c'
  // Error: Invalid attempt to set private "_prop" property

var target = function () { return 'I am the target'; };

var handler = {
  apply: function () {
    return 'I am the proxy';
  }
};

var p = new Proxy(target, handler);

console.log(p());

var handler = {
    has (target, key) {
      if (key[0] === '_') {
        return false;
      }
      return key in target;
    }
  };
  var target = { _prop: 'foo', prop: 'foo' };
  var proxy = new Proxy(target, handler);
  console.log('_prop' in proxy); // false

const p = new Proxy(function () {}, {
    construct: function(target, args) {
      console.log('called: ' + args.join(', '));
      return { value: args[0] * 10 };
    }
  });

  console.log((new p(1,2,3)).value);

let target = {};
let handler = {};

let {proxy, revoke} = Proxy.revocable(target, handler);

proxy.foo = 123;
proxy.foo // 123

revoke();
console.log(target); // TypeError: Revoked

const obj={a:1}
console.log(Reflect.has(obj,"a"));

var myObject = {
    foo: 1,
    bar: 2,
    get baz() {
      return this.foo + this.bar;
    },
  };
  
  var myReceiverObject = {
    foo: 4,
    bar: 4,
  };
  
  Reflect.get(myObject, 'baz', myReceiverObject) // 8

console.log(Object.getPrototypeOf(1));
console.log(new Number(1));

console.log(Reflect.setPrototypeOf(Object.freeze({}), null));

const ages = [11, 33, 12, 54, 18, 96];

// 旧写法
const youngest = Math.min.apply(Math, ages);
const oldest = Math.max.apply(Math, ages);
const type = Object.prototype.toString.call(youngest);

// 新写法
const youngest = Reflect.apply(Math.min, Math, ages);
const oldest = Reflect.apply(Math.max, Math, ages);
const type = Reflect.apply(Object.prototype.toString, youngest, []);

const p = new Proxy({}, {
    defineProperty(target, prop, descriptor) {
      console.log(descriptor);
      return Reflect.defineProperty(target, prop, descriptor);
    }
  });
  
  p.foo = 'bar';

var myObject = {
    foo: 1,
    bar: 2,
    [Symbol.for('baz')]: 3,
    [Symbol.for('bing')]: 4,
  };
  
  // 旧写法
  Object.getOwnPropertyNames(myObject)
  // ['foo', 'bar']
  
  Object.getOwnPropertySymbols(myObject)
  //[Symbol(baz), Symbol(bing)]
  
  // 新写法
  Reflect.ownKeys(myObject)
  ['foo', 'bar', Symbol(baz), Symbol(bing)]

  let promise = new Promise(function(resolve, reject) {
    console.log('Promise');
    resolve();
  });
  
  promise.then(function() {
    console.log('resolved.');
  });
  
  console.log('Hi!');

const getJSON = function(url) {
    const promise = new Promise(function(resolve, reject){
      const handler = function() {
        if (this.readyState !== 4) {
          return;
        }
        if (this.status === 200) {
          resolve(this.response);
        } else {
          reject(new Error(this.statusText));
        }
      };
      const client = new XMLHttpRequest();
      client.open("GET", url);
      client.onreadystatechange = handler;
      client.responseType = "json";
      client.setRequestHeader("Accept", "application/json");
      client.send();
  
    });
  
    return promise;
  };
  
  getJSON("/posts.json").then(function(json) {
    console.log('Contents: ' + json);
  }, function(error) {
    console.error('出错了', error);
  });

const p1 = new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('fail')), 3000)
  })
  
  const p2 = new Promise(function (resolve, reject) {
    setTimeout(() => resolve(p1), 1000)
  })
  
  p2
    .then(result => console.log(result))
    .catch(error => console.log(error))

const someAsyncThing = function() {
    return new Promise(function(resolve, reject) {
      // 下面一行会报错,因为x没有声明
      resolve(x + 2);
    });
  };
  
  someAsyncThing().then(function() {
    console.log('everything is great');
  });
  
  setTimeout(() => { console.log(123) }, 2000);

process.on('unhandledRejection', function (err, p) {
    throw err;
  });

const promise = new Promise(function (resolve, reject) {
    resolve('ok');
    setTimeout(function () { throw new Error('test') }, 0)
  });
  promise.then(function (value) { console.log(value) });

const p1 = new Promise((resolve, reject) => {
    resolve('hello');
  })
  .then(result => result)
  .catch(e => e);
  
  const p2 = new Promise((resolve, reject) => {
    throw new Error('报错了');
  })
  .then(result => result)
  .catch(e => e);
  
  Promise.all([p1, p2])
  .then(result => console.log(result))
  .catch(e => console.log(e));
console.log(new Date().getDate());
console.log(parseInt(05));

var resolved = Promise.resolve(42);
var rejected = Promise.reject(-1);
var alsoRejected = Promise.reject(Infinity);

Promise.any([resolved, rejected, alsoRejected]).then(function (result) {
  console.log(result); // 42
});

Promise.any([rejected, alsoRejected]).catch(function (results) {
  console.log(results); // [-1, Infinity]
});

var resolved = Promise.resolve(42);
var rejected = Promise.reject(-1);
var alsoRejected = Promise.reject(Infinity);

Promise.any([resolved, rejected, alsoRejected]).then(function (result) {
  console.log(result); // 42
});

Promise.any([rejected, alsoRejected]).catch(function (results) {
  console.log(results); // [-1, Infinity]
});

let thenable = {
    then: function(resolve, reject) {
      resolve(42);
    }
  };
  
  let p1 = Promise.resolve(thenable);
  p1.then(function (value) {
    console.log(value);  // 42
  });

const p = Promise.resolve('Hello');

p.then(function (s) {
  console.log(s)
});

Promise.reject('出错了')
.catch(e => {
  console.log(e === '出错了')
})

function getFoo () {
    return new Promise(function (resolve, reject){
      resolve('foo');
    });
  }
  
  const g = function* () {
    try {
      const foo = yield getFoo();
      console.log(foo);
    } catch (e) {
      console.log(e);
    }
  };

  function run (generator) {
    const it = generator();

    function go(result) {
      if (result.done) return result.value;
      return result.value.then(function (value) {
        return go(it.next(value));
      }, function (error) {
        return go(it.throw(error));
      });
    }
  
    go(it.next());
  }
  
  run(g);

const f = () => console.log('now');
(
  () => new Promise(
    resolve => resolve(f())
  )
)();
console.log('next');

let arr = ['a', 'b', 'c'];
let iter = arr[Symbol.iterator]();

console.log(iter.next()); // { value: 'a', done: false }
iter.next() // { value: 'b', done: false }
iter.next() // { value: 'c', done: false }
iter.next() // { value: undefined, done: true }

class RangeIterator {
    constructor(start, stop) {
      this.value = start;
      this.stop = stop;
    }
  
    [Symbol.iterator]() { return this; }
  
    next() {
      var value = this.value;
      if (value < this.stop) {
        this.value++;
        return {done: false, value: value};
      }
      return {done: true, value: undefined};
    }
  }
  
  function range(start, stop) {
    return new RangeIterator(start, stop);
  }
  
  for (var value of range(0, 3)) {
    console.log(value); // 0, 1, 2
  }

function Obj(value) {
    this.value = value;
    this.next = null;
  }

  var one = new Obj(1);
  var two = new Obj(2);
  var three = new Obj(3);
  
  one.next = two;
  two.next = three;
  
  Obj.prototype[Symbol.iterator] = function() {
    var iterator = { next: next };
  
    var current = this;
  
    function next() {
      if (current) {
        var value = current.value;
        current = current.next;
        return { done: false, value: value };
      }
      return { done: true };
    }
    return iterator;
  }

  for (var i of one){
    console.log(i); // 1, 2, 3
  }

let obj = {
    data: [ 'hello', 'world' ],
    [Symbol.iterator]() {
      const self = this;
      let index = 0;
      return {
        next() {
          if (index < self.data.length) {
            return {
              value: self.data[index++],
              done: false
            };
          }
          return { value: undefined, done: true };
        }
      };
    }
  };

let iterable = {
    0: 'a',
    1: 'b',
    2: 'c',
    length: 3,
    [Symbol.iterator]: Array.prototype?.[Symbol.iterator]
  };
  for (let item of iterable) {
    console.log(item); // 'a', 'b', 'c'
  }
var obj = {};

obj[Symbol.iterator] = () => 1;

[...obj] // TypeError: [] is not a function

let set = new Set().add('a').add('b').add('c');

let [x,y] = set;
// x='a'; y='b'

let [first, ...rest] = set;
console.log(typeof rest,rest);
first='a'; rest=['b','c'];

var str = 'hello';
[...str] //  ['h','e','l','l','o']

// 例二
let arr = ['b', 'c'];
['a', ...arr, 'd']

let generator = function* () {
    yield 1;
    yield* [2,3,4];
    yield 5;
  };

  var iterator = generator();

iterator.next() // { value: 1, done: false }
iterator.next() // { value: 2, done: false }
iterator.next() // { value: 3, done: false }
console.log(iterator.next()); // { value: 4, done: false }
iterator.next() // { value: 5, done: false }
iterator.next() // { value: undefined, done: true }

var someString = "hi";
typeof someString[Symbol.iterator]
// "function"

var iterator = someString[Symbol.iterator]();

iterator.next()  // { value: "h", done: false }
iterator.next()  // { value: "i", done: false }
iterator.next()  // { value: undefined, done: true }

var str=new String("hi")
// console.log([...str]);
str[Symbol.iterator] = function() {
    return {
      next: function() {
        if (this._first) {
          this._first = false;
          return { value: "bye", done: false };
        } else {
          return { done: true };
        }
      },
      _first: true
    };
  };
  
  console.log([...str] );// ["bye"]
  console.log(str.valueOf()); // "hi"

const arr = ['red', 'green', 'blue'];

for(let v of arr) {
  console.log(v); // red green blue
}

const obj = {};
obj[Symbol.iterator] = arr[Symbol.iterator].bind(arr);

for(let v of obj) {
  console.log(v); // red green blue
}

let arr = [3, 5, 7];
arr.foo = 'hello';
arr["3"]=10
console.log(arr);
for (let i in arr) {
//   console.log(i); // "0", "1", "2", "foo"
}

for (let i of arr) {
//   console.log(i); //  "3", "5", "7"
}

let arr = ['a', 'b', 'c'];
for (let pair of arr.entries()) {
  console.log(typeof pair[0]);
}

for (let x of 'a\uD83F\uDC0B') {
    console.log(x);
  }

let arrayLike = { length: 2, 0: 'a', 1: 'b' };
for (let x of Array.from(arrayLike)) {
    console.log(x);
  }

let es6 = {
    edition: 6,
    committee: "TC39",
    standard: "ECMA-262"
  };
  
  for (let e in es6) {
    console.log(e);
  }
  // edition
  // committee
  // standard
  
  for (let e of es6) {
    console.log(e);
  }

const obj = { a: 1, b: 2, c: 3 }

function* entries(obj) {
  for (let key of Object.keys(obj)) {
    yield [key, obj[key]];
  }
}

for (let [key, value] of entries(obj)) {
  console.log(key, '->', value);
}
let myArray=[1,2,3,4,64,546,654,234,24,234,42,4,235,23,55345,345,345,345]
for (let index in myArray) {
    console.log(index,myArray[index]);
    if(parseInt(index)>6)break;
  }