详解Object.defineProperty

简介: 详解Object.defineProperty

Object.defineProperty


3个参数

obj: 可以理解为目标对象。

prop: 目标对象的属性名。

descriptor: 对属性的描述。

descriptor可分为数据属性和访问器属性两类

//4个数据描述符value,configurable,enumerable,writable
  let obj = {};
    Object.defineProperty(obj, "name", {
      value: 'ddd',
      // 这三个参数默认都为false
      configurable: true, // 是否可删除
      enumerable: true,   // 是否可枚举
      writable: true,     //  是否可修改
    })
//访问器描述符的含义是:包含该属性的一对 getter/setter方法的对象
  let obj = {};
    Object.defineProperty(obj, 'name', {
      configurable: false,  //是否可删除
      enumerable: false,// 是否可枚举
      get() {},
      set(newValue) {}
    })


注意:

1,使用访问器描述符中 getter或 setter方法的话,不允许使用 writable 和 value 这两个配置项。

2,不能在set方法里设置当前的属性值.会报栈溢出.原因是会造成死循环。

// 例1   用对象中不存在的属性,借助get和set实现获取和设置对象中存在的属性
    let obj = { name_: '小红' };
    Object.defineProperty(obj, 'name', {
      get() {
        console.log("get被拦截")
        return this.name_
      },
      set(newValue) {
        console.log("set被拦截")
        this.name_ = newValue
      }
    })
    obj.name = "小明"
    console.log(obj.name)   //小明
    console.log(obj)       //{name_:'小明'}


简单实现数据双向绑定

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <h1>简单实现数据双向绑定</h1>
  <input type="text" id="inp">
  <p></p>
</head>
<body>
  <script>
    const inp = document.getElementById('inp')
    const p = document.getElementsByTagName('p')[0]
    const obj = { text: '' }
    inp.oninput = (e) => {
      obj.text = e.target.value
    }
    Object.defineProperty(obj, 'text', {
      set(v) {
        inp.value = v
        p.innerHTML = v
      }
    })
  </script>
</body>
</html>


对数组的监听

const obj = {}
    let a = 1;
    Object.defineProperty(obj, 'arr', {
      get() {
        return a
      },
      set(v) {
        console.log('set执行', v)
        a = v
      }
    })
    obj.arr = []      //set执行
    obj.arr = [1, 2, 3]   // 给obj中的arr属性添加1,2,3, 会执行set方法
    obj.arr[0] = 3        //set不执行
    obj.arr.push(4)        // set不执行
    obj.name.length = 5   // 也不会执行set方法


如上执行结果我们可以看到,当我们使用 Object.defineProperty 对数组赋值有一个新对象的时候,会执行set方法,但是当我们改变数组中的某一项值的时候,或者使用数组中的push等其他的方法,或者改变数组的长度,都不会执行set方法。也就是如果我们对数组中的内部属性值更改的话,都不会触发set方法。因此如果我们想实现数据双向绑定的话,我们就不能简单地使用 obj.name[1] = newValue; 这样的来进行赋值了。那么对于vue这样的框架,那么一般会重写 Array.property.push方法,并且生成一个新的数组赋值给数据,这样数据双向绑定就触发了

相关文章
|
3天前
|
JSON 前端开发 JavaScript
成功解决:[object Object]
这篇文章讨论了在JavaScript中打印对象时出现的"[object Object]"问题的原因,并提供了使用`JSON.stringify()`方法将对象转换为字符串以便于打印和调试的解决方案。
成功解决:[object Object]
|
3月前
|
JavaScript
【Object.defineProperty() | new Proxy()】操作Object
【Object.defineProperty() | new Proxy()】操作Object
|
3月前
|
JavaScript 前端开发
为什么要替换 Object.defineProperty?
为什么要替换 Object.defineProperty?
31 0
|
3月前
Object.defineProperty 使用
Object.defineProperty 使用
18 0
|
JavaScript
Object.defineProperty()
Object.defineProperty()
66 0
|
JavaScript 前端开发
详解Object.defineProperty方法
详解Object.defineProperty方法
详解Object.defineProperty方法
|
JavaScript 前端开发
JavaScript总结:typeof与instanceof的区别,及Object.prototype.toString()方法
JavaScript总结:typeof与instanceof的区别,及Object.prototype.toString()方法
170 0
JavaScript总结:typeof与instanceof的区别,及Object.prototype.toString()方法
|
JavaScript 前端开发
Object.defineProperty() 方法
Object.defineProperty() 方法
80 1
引用数据类型object及object的方法
参数:obj:要返回其自己的可枚举字符串键属性 [key, value] 对的对象。返回值:给定对象自己的可枚举字符串键属性 [key, value] 对的数组。
|
存储 JavaScript 前端开发
如何理解Object.defineProperty()?
如何理解Object.defineProperty()?
如何理解Object.defineProperty()?