defineProperty详解

搁置了几天我还是决定再次重写!

下边我们来具体聊聊先从defineProperty开始说起

defineproperty

//defineproperty 有个定义object属性的功能,应该没几个人用,因为相对于obj.a = 1这种方式简直不能再难用。

//通常我们定义obj属性
let obj = {
      a:1
}
obj.b = 2
obj['c'] = 3
console.log(obj)//{a: 1, b: 2,c: 3}  

Object.defineProperty(obj,'d',{
      value: 4
})

console.log(obj)//{a: 1, b: 2,c: 3,d:4}  //defineProperty可以定义对象属性

//也可以修改
Object.defineProperty(obj,'b',{
      value: 5
})
console.log(obj)//{a: 1, b: 5, c: 3, d: 4}

//对你没看错defineProperty有这个功能,不知可以定义新的属性还可以修改,这么逆天难用的功能为什么还要造出来?说这个有什么用?别急往下看

descriptor详解

defineProperty 接收三个参数
  • object (必须有 操作的对象本身 这个很容易理解不传它操作谁?)
  • propertyname (必须有 属性名 添加修改属性得有属性名)
  • descriptor (必须有 官方说的我理解不了,我理解的是 属性描述
    1、简单点就是 设置属性的值value,
    2、是否可操作属性值 writable,
    3、是否可修改配置configurable如果值为false descriptor内的属性都不可操作
    4、是否可枚举enumerable

    *descriptor内配置可有可无,value默认undefind,其余默认为false

先做了介绍我们下边来证明下

writable
//栗子还是这个栗子
        let obj = {
            a: 1
        }
        Object.defineProperty(obj, 'b', {
            value: 2,
            writable: false//不可修改
        })

        obj.b = 3
        console.log(obj) //{a: 1, b: 2} 还真是不可以
        //难道是姿势不对?
        Object.defineProperty(obj, 'b', {
            value: 3
        })
        console.log(obj)//{a: 1, b: 2} 一样的效果 和姿势无关。
configurable

//configurable 这个比较厉害 控制descriptor内属性都不可改变不知道是不是真的

//还是这个栗子

       let obj = {
            a: 1
        }
        Object.defineProperty(obj, 'b', {
            value: 2,
            //writable: false//不可修改
            configurable: false
        })
        obj.b = 5
        console.log(obj)//[1,2]
enumerable

对否可枚举

 let obj = {
            a: 1
        }
        Object.defineProperty(obj, 'b', {
            value: 2,
            //writable: false//不可修改
            //configurable: false
            enumerable: false
        })
        //obj.b = 5
        console.log(Object.keys(obj))//["a"]

接了下来说到重点: set和get这也是vue3.0前observe的实现原理

let obj = {
            a: 1
        }

        let newValue = 45
        Object.defineProperty(obj, 'b', {
            get(value) {
                console.log('获取')
                return value
            },
            set(newValue) {
                console.log('设置')
                value = newValue
            }
        })
        obj.b = 6 //设置

        obj.b //获取

知道用法了我们来实践一下

      //html
      <div></div>
      <input type="text">
      //js
      //类似 vue的data
        let obj = {}

        /*
         *obj      要劫持的对象
         *name     要劫持对象的属性
         *callback 劫持以后的操作
         */
        function watch(obj, name, callback) {
            let value = obj.name
            Object.defineProperty(obj, name, {
                set(msg) {
                    // 触发setter给obj赋值
                    value = msg
                        //执行劫持后的操作
                    callback(value)
                },
                get() {
                    //返回获取属性值
                    return value
                }
            })
        }

        //
        function doSomething(value) {
            document.querySelector('div').innerHTML = value
            document.querySelector('input').value = value
        }
        //监听input变化 
        //可以参考全兼容版:https://segmentfault.com/a/1190000017524278
        document.querySelector('input').addEventListener('input', (e) => {
            obj['msg'] = e.target.value
        })

        watch(obj, 'msg', doSomething)

效果:
1、input输入改变div内容
image.png
2、改变obj name属性
image.png
3、获取改变后的obj属性name
image.png

简单的用defineProperty实现了双向绑定

欢迎吐槽!您的点赞是我继续的动力!谢谢

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
definePropertyJavaScript中的一个方法,它用于给对象定义属性。通过使用defineProperty方法,我们可以动态地向对象中添加属性,并设置属性的特性,例如属性的值、可枚举性、可配置性等。 在给对象定义属性时,我们可以使用defineProperty方法来实现。这个方法接收三个参数:目标对象、要定义的属性的名称以及一个属性描述符对象。属性描述符对象包含了属性的特性,比如属性的值、可枚举性、可配置性等。 使用defineProperty方法可以给对象添加新的属性,并且可以通过属性描述符对象来设置该属性的特性。通过这个方法,我们可以实现更加灵活的属性定义和控制。 引用给出了一个使用defineProperty方法的示例。在这个示例中,通过遍历源对象obj的属性,并使用Object.defineProperty方法将这些属性添加到目标对象target中。这样,我们可以动态地将一个对象的属性添加到另一个对象中,并且可以控制这些属性的特性。 引用和引用提供了对defineProperty方法的解释,指出了该方法是用于给对象定义属性的。 总结来说,definePropertyJavaScript中的一个方法,用于给对象定义属性。通过使用这个方法,我们可以动态地添加属性,并设置属性的特性。这样可以使我们更灵活地操作对象的属性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [js的defineProperty详解](https://blog.csdn.net/qq_44980680/article/details/126334454)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [js中defineProperty方法说明](https://blog.csdn.net/czhloveca/article/details/108749563)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值