【JavaScript】利用defineProperty抛出value is same异常

使用Object.defineProperty这个api,完成当给一个对象重复赋同一个值的时候,抛出value is same异常

data对象如下:

const data = {
  name: 'panda',
  age: 20,
  info: {
    major: "CS"
  }
}

测试代码如下:

// 自己实现observer函数
observer(data);
console.log(data.name); // 输出panda
data.name = "cat"; // 成功赋值为"cat"
data.name = "cat"; // 抛出"value is same"错误
  1. 参考资料准备(用于学习defineProperty的使用)
  • https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

  • https://www.jianshu.com/p/8fe1382ba135

  1. 思路及实现
  • 写函数observer框架,以name属性为例
const observer = (data) => {
  let temp = data.name
  Object.defineProperty(data, item, {
    get: function () {
      return temp;
    },
    set: function (val) {
      if (val === temp) {
        throw new Error('value is same');
      }
      temp = val;
    }
  })
}
  • 上一步测试无误,开始加入for循环(一定注意这一步骤中的temp赋值,是将属性的值赋值给temp)
const observer = (data) => {
  for (let item in data) {
    let temp = data[item] // 注意此处的赋值,是将data[item](即键值对中的值)赋值给temp
    Object.defineProperty(data, item, {
      get: function () {
        return temp;
      },
      set: function (val) {
        if (val === temp) {
          throw new Error('value is same');
        }
        temp = val;
      }
    })
  }
}
  • 对代码进行测试,发现对象中嵌套的对象无法实现功能,经过分析,可以在函数的开始进行一次判断,如果遍历到对象中的某属性类型为对象时,那么再次运行observer函数,直到不是对象为止
const observer = (data) => {
  for (let item in data) {
    let temp = data[item]
    if (typeof temp === 'object') {
      observer(temp)
    }
    Object.defineProperty(data, item, {
      get: function () {
        return temp;
      },
      set: function (val) {
        if (val === temp) {
          throw new Error('value is same');
        }
        temp = val;
      }
    })
  }
}
  • 附上完整源码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>


  <script>
    const data = {
      name: 'panda',
      age: 20,
      info: {
        major: "CS",
        a: {
          b: '123'
        }
      }
    }

    const observer = (data) => {
      for (let item in data) {
        let temp = data[item]
        if (typeof temp === 'object') {
          observer(temp)
        }
        Object.defineProperty(data, item, {
          get: function () {
            return temp;
          },
          set: function (val) {
            if (val === temp) {
              throw new Error('value is same');
            }
            temp = val;
          }
        })
      }
    }

    observer(data);

    // console.log(data.name);
    // data.name = "cat";
    // console.log(data.name);
    // data.name = "cat";

    console.log(data.info.a.b);
    data.info.a.b = '234'
    console.log(data.info.a.b);
    data.info.a.b = '234'
  </script>
</body>

</html>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值