字符串扩展的方法

  1. includes
  2. startWith
  3. endsWith

    对象

    Object.assign()合并多个对象,第一个参数就是最终返回的值

    1. let obj1 = {
    2. a: 'aa',
    3. b: 'bb'
    4. }
    5. let obj2 = {
    6. b: 'dd',
    7. c: 'ee'
    8. }
    9. let result = Object.assign({}, obj1, obj2)
    10. result.a = 'cc'
    11. console.log(obj1, result) //{a: "aa", b: "bb"} {a: "cc", b: "dd", c: "ee"}

    Object.is() 判断两个值是否相等,返回布尔值

    es5中,对于0的判断不区分正负值,-0 == +0返回true,NaN == NaN返回 返回false;
    Object.is()规避了这些问题

    1. Object.is(+0, -0)//false
    2. Object.is(NaN, NaN) //true

    Proxy

    1. const person={
    2. name:'heisehuoyan',
    3. age:18
    4. }
    5. const personProxy = new Proxy(person, {
    6. get(target, key) {
    7. return target[key] ? target[key] : 'default'
    8. },
    9. set(target, key, value) {
    10. target[key] = value % 2 ? value : 99
    11. }
    12. })
    1. var obj = {
    2. test:"hello"
    3. }
    4. //对象已有的属性添加特性描述
    5. Object.defineProperty(obj,"test",{
    6. configurable:true | false,
    7. enumerable:true | false,
    8. value:任意类型的值,
    9. writable:true | false
    10. });
    11. //对象新添加的属性的特性描述
    12. Object.defineProperty(obj,"newKey",{
    13. configurable:true | false,
    14. enumerable:true | false,
    15. value:任意类型的值,
    16. writable:true | false
    17. });

    Object.defineProperty:

  4. 兼容性好,而Proxy 是新出的 API,兼容性还不够好,不支持 IE 全系列。

  5. 拦截方式少,Proxy 提供了13种拦截方法,包括拦截 constructor、apply、deleteProperty 等等,而 Object.defineProperty 只有 get 和 set
  6. 不能一次性监听对象所有属性,需要通过递归和遍历来实现;但是proxy一次性监听

    1. let person = {
    2. name: "marry",
    3. age: 22
    4. }
    5. /* Proxy 一次性监听整个对象*/
    6. newPerson = new Proxy(person, {
    7. get() {}
    8. set() {}
    9. })
    10. /* Object.defineProperty */
    11. Object.keys(person).forEach(key => {
    12. Object.defineProperty(person, key, {
    13. set() {},
    14. get() {}
    15. })
    16. })
  7. 无法监听对象新增的属性,需要手动再去做一次监听,在vue中一般用vue.set(person,’newkey’,’我是新加的属性’),但proxy可以

    1. let girl = {
    2. name: "marry",
    3. age: 22
    4. }
    5. /* Proxy 监听整个对象*/
    6. girl = new Proxy(girl, {
    7. get() {}
    8. set() {}
    9. })
    10. /* Object.defineProperty */
    11. Object.keys(girl).forEach(key => {
    12. Object.defineProperty(girl, key, {
    13. set() {},
    14. get() {}
    15. })
    16. });
    17. /* Proxy 生效,Object.defineProperty 不生效 */
    18. girl.hobby = "game";
  8. 无法响应push、pop、shift等数组操作

Object.defineProperty 可以监听数组的变化,Object.defineProperty 无法对 push、shift、pop、unshift 等方法进行响应

  1. const arr = [1, 2, 3];
  2. /* Proxy 监听数组*/
  3. arr = new Proxy(arr, {
  4. get() {},
  5. set() {}
  6. })
  7. /* Object.defineProperty */
  8. arr.forEach((item, index) => {
  9. Object.defineProperty(arr, `${index}`, {
  10. set() {},
  11. get() {}
  12. })
  13. })
  14. arr[0] = 10; // 都生效
  15. arr[3] = 10; // 只有 Proxy 生效
  16. arr.push(10); // 只有 Proxy 生效
  1. let arr = []
  2. let arrProperty = new Proxy(arr, {
  3. set (target, key, value) {
  4. console.log(target, key, value) //[1] "length" 1
  5. target[key] = value
  6. return true
  7. }
  8. })
  9. arrProperty.push(1)
  10. console.log(arrProperty) //[1]

参考

Reflect 封装操作对象的统一API

在之前的es5中,操作对象有很多种方式

  1. const obj = {
  2. name: '111',
  3. age: '22'
  4. }
  5. // 判断对象某个属性是否存在
  6. console.log('name' in obj)
  7. // 删除某个属性
  8. console.log(delete obj['name'])
  9. // 获取对象key
  10. console.log(Object.keys(obj))

对于不同的操作行为,使用的方式却不同,Reflect的目的是使用同一套方式去操作对象

  1. const obj = {
  2. name: '111',
  3. age: '22'
  4. }
  5. // 判断对象某个属性是否存在
  6. console.log(Reflect.has(obj,'name'))
  7. // 删除某个属性
  8. console.log(Reflect.deleteProperty(obj, 'name'))
  9. // 获取对象key
  10. console.log(Reflect.ownKeys(obj))