2.1 ECMAScript 2015+ 新特性

proxy

基本用法

const person = {
  name: 'zhangsan',
  age: 20
}

const personProxy = new Proxy(person, {
  get(target, property) {
    return property in target ? target[property] : 'default';
  }
  set(target, property, value) {
    if (property === 'age') {
      if (!Number.isInteger(value)) {
      	throw new TypeError(`${value} is not an int number`);
      }
    }
    target[property] = value
  }
})

personProxy.age = '23424'; // TypeError
personProxy.gender = true;

console.log(personProxy.name);
console.log(personProxy.xxx);

对比 defineProperty

const person = {
  name: 'zhangsan',
  age: 20,
}

const personProxy = new Proxy(person, {
  deleteProperty(target, property) {
    console.log('delete', property);
    delete target[property];
  }
})

delete personProxy.age;
console.log(age);

reflect

import React, { useEffect } from 'react';

function append(content, container = 'content', tagname = 'p') {
  const tag = document.createElement(tagname);
  const text = document.createTextNode(content);
  tag.appendChild(text);
  document.getElementById(container).appendChild(tag);
}

function reflect() {
  const obj = {
    foo: '123',
    bar: '456',
  };

  const proxy = new Proxy(obj, {
    get(target, property) {
      return Reflect.get(target, property);
    },
  });

  append(JSON.stringify(proxy));

  const object = {
    name: '张三',
    age: 18,
  };

  append(Reflect.has(object, 'name'));
  append(Reflect.deleteProperty(object, 'age'));
  append(Reflect.ownKeys(object));
}

export default function Async() {
  useEffect(reflect, null);

  return (
    <div id="content">
      <p>reflect</p>
    </div>
  );
}

class

utils.js

function append(content, container = 'content', tagname = 'p') {
  const tag = document.createElement(tagname);
  const text = document.createTextNode(content);
  tag.appendChild(text);
  document.getElementById(container).appendChild(tag);
}

export { append };

export default append;

person.js

import { append } from './utils';

export default class Person {
  constructor(name) {
    this.name = name;
  }

  say() {
    append(`Hi, my name is ${this.name}`);
  }

  static create(name) {
    return new Person(name);
  }
}

student.js

import Person from './person';
import { append } from './utils';

class Student extends Person {
  constructor(name, number) {
    super(name);
    this.number = number;
  }

  hello() {
    super.say();
    append(`my school number is ${this.number}`);
  }
}

export default Student;

main.js

import React, { useEffect } from 'react';
import Person from './person';
import Student from './student';

function main() {
  const p = new Person('tom');
  const p2 = Person.create('jerry');
  const p3 = Reflect.construct(Student, ['curry', 26]);

  p.say();
  p2.say();
  p3.hello();
}

export default function Async() {
  useEffect(main, null);

  return (
    <div id="content">
      <p>main</p>
    </div>
  );
}

set

import React, { useEffect } from 'react';
import { append } from './utils';

function set() {
  const s = new Set();

  // eslint-disable-next-line newline-per-chained-call
  s.add(1).add(2).add(3).add(4).add(2);

  // s.size
  // s.has(40)
  // s.delete(3)
  // s.clear();
  append(Array.from(s));

  const arrayNoDupliate = Array.from(new Set([1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]));
  append(arrayNoDupliate);
}

export default function Async() {
  useEffect(set, null);

  return (
    <div id="content">
      <p>set</p>
    </div>
  );
}

map

import React, { useEffect } from 'react';
import { append } from './utils';

function map() {
  const obj = {};
  // eslint-disable-next-line dot-notation
  obj[true] = 'value';
  obj[123] = 'value';
  obj[{ a: 1 }] = 'value';

  append(Object.keys(obj));
  append(obj['[object Object]']);

  append('---------------------');

  // 使用 map 代替
  const m = new Map();
  const tom = { name: 'tom' };

  m.set(tom, 90);

  append(typeof m);
  append(JSON.stringify(m));
  append(m.get(tom));

  m.forEach((value, key) => {
    append(`${JSON.stringify(key)}: ${value}`);
  });
}

export default function Async() {
  useEffect(map, null);

  return (
    <div id="content">
      <p>map</p>
    </div>
  );
}

Symbol

Symbol('foo') === Symbole('foo'); // false

const s1 = Symbol.for('foo');
const s2 = Symbol.for('foo');
s1 === s2 // true

Symbol.iterator
Symbol.hasInstance

const obj = {
  [Symbol.toStringTag]: 'XObject'
}
obj.toString();

const obj = {
  [Symbol.toStringTag]: 'XObject',
};
append(obj.toString());
console.log(obj.toString());

const obj2 = {
  [Symbol()]: 'symbol value', // 无法获取的 key
  foo: 'normal value',
};

for (let key in obj2) {
  append(key);
}
append(JSON.stringify(obj2)) // 仍然无法打印 Symbol key

Object.getOwnPropertySymbols(obj2) // 能获取到私有 Symbol 属性

for of 循环

  const arr = [100, 200, 300, 400];

  // eslint-disable-next-line no-restricted-syntax
  for (const item of arr) {
    append(item);
    // 使用 break 关键字可以跳出循环 for in 循环不可
  }

  const s = new Set(['foo', 'bar']);
  // eslint-disable-next-line no-restricted-syntax
  for (const item of s) {
    append(item);
  }

  const m = new Map();
  m.set('foo', '123');
  m.set('bar', '456');

  // eslint-disable-next-line no-restricted-syntax
  for (const [key, value] of m) {
    append(`${key}: ${value}`);
  }

  const obj = {
    foo: '123',
    bar: '456',
  };
  // eslint-disable-next-line no-restricted-syntax
  for (const item of obj) { // Invalid attempt to iterate non-iterable instance.
    append(item);
  }

可迭代接口

import React, { useEffect } from 'react';
import { append } from './utils';

function main() {
  const arr = [100, 200, 300, 400];

  // eslint-disable-next-line no-restricted-syntax
  for (const item of arr) {
    append(item);
    // 使用 break 关键字可以跳出循环 for in 循环不可
  }

  const s = new Set(['foo', 'bar']);
  // eslint-disable-next-line no-restricted-syntax
  for (const item of s) {
    append(item);
  }

  const m = new Map();
  m.set('foo', '123');
  m.set('bar', '456');

  // eslint-disable-next-line no-restricted-syntax
  for (const [key, value] of m) {
    append(`${key}: ${value}`);
  }

  const obj = {
    foo: '123',
    bar: '456',
  };
  // eslint-disable-next-line no-restricted-syntax
  for (const item of obj) { // Invalid attempt to iterate non-iterable instance.
    append(item);
  }
}

export default function IteratorDemo() {
  useEffect(main, null);

  return (
    <div id="content">
      <p>iterator</p>
    </div>
  );
}

实现可迭代接口

import React, { useEffect } from 'react';
import { append } from './utils';

function main() {
  const arr = [100, 200, 300, 400];
  const iterator = arr[Symbol.iterator]();

  let done = false;

  while (!done) {
    const { value: v, done: d } = iterator.next();
    done = d;
    append(`done: ${d}, value: ${v}`);
  }

  append('----------------------------------------');

  const set = new Set(['张三', '李四', '王五']);
  const iteratorSet = set[Symbol.iterator]();
  done = false;

  while (!done) {
    const { value: v, done: d } = iteratorSet.next();
    done = d;
    append(`done: ${d}, value: ${v}`);
  }
}

export default function iterableDemo() {
  useEffect(main, null);

  return (
    <div id="content">
      <p>iterable</p>
    </div>
  );
}

生成器函数

import React, { useEffect } from 'react';
import { append } from './utils';

function main() {
  function* foo() {
    yield append('foo');
    return 100;
  }

  const f = foo();
  let result = f.next();
  append(JSON.stringify(result));

  result = f.next();
  append(JSON.stringify(result));

  append('------------------------------');

  function* bar() {
    append('1111');
    yield 100;
    append('2222');
    yield 200;
    append('3333');
    yield 300;
  }

  const generator = bar();
  append(JSON.stringify(generator.next()));
  append(JSON.stringify(generator.next()));
  append(JSON.stringify(generator.next()));
  append(JSON.stringify(generator.next()));
}

export default function GeneratorDemo() {
  useEffect(main, null);

  return (
    <div id="content">
      <p>generator</p>
    </div>
  );
}

生成器函数的应用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值