Object.defineProperty,以及观察者模式,发布订阅模式

为了深入了解vue的原理,Object.defineProperty这个方法必须会。

Object.defineProperty(obj, prop, descriptor)

MDN

该方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

  • obj:要定义属性的对象。
  • prop:要定义或修改的属性的名称或 Symbol 。
  • descriptor:描述符对象,要定义或修改的属性描述符。
属性/方法语义默认值
configurable对象的属性是否可以被删除,
以及除 value 和 writable 特性外的其他特性是否可以被修改。
false(不可删)
enumerable定义了对象的属性是否可以在 for…in 循环和 Object.keys() 中被枚举。false(直接定义的属性为true)
value该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。undefined
writablewritable 属性设置为 false 时,该属性被称为“不可写的”。它不能被重新赋值false
get执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。undefined
set当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。undefined

get和set特性在设置了configurable为false的时候一样被设置会被忽略,严格模式报错
如果一个描述符同时拥有 value 或 writable 和 get 或 set 键,则会产生一个异常

configurable:

<script>
        let obj = {}
        Object.defineProperty(obj, 'name', {
            configurable: false, //结构的,可配置的,对象的属性是否可以被删除,false不可删除
            //以及除 value 和 writable 特性外的其他特性是否可以被修改。
            enumrable: false, //可枚举
            value: '233', //该属性对应的值
            writable: true,

        })
        console.log(obj.name);
        delete obj.name;
        console.log(obj.name);//233
    </script>

enumerable:

   <script>
        let obj = {}
        Object.defineProperty(obj, 'name', {
            configurable: true,
            enumerable: false,
            value: '233',
            writable: true,

        })
        Object.defineProperty(obj, 'em', {
            configurable: true,
            enumerable: true,
            value: 1,
            writable: true,

        })
        console.log(obj);

        console.log(obj.propertyIsEnumerable('name')); // false
        console.log(obj.propertyIsEnumerable('em')); //false
        console.log(Object.keys(obj));
        for (let i in obj) {
            console.log(i);
        }
        obj.x = 'ddd';//obj.propertyIsEnumerable('x')//true
    </script>

writable:

<script>
        let obj = {}
        Object.defineProperty(obj, 'name', {
            value: 233,
            writable: false,
        })
        obj.name = 99;
        console.log(obj); //{233}
</script>

setget: mdn示例

<script>
        function Archiver() {
            var temperature = null;
            var archive = [];

            Object.defineProperty(this, 'temperature', {
                get: function() {
                    console.log('get!');
                    return temperature;
                },
                set: function(value) {
                    temperature = value;
                    archive.push({
                        val: temperature
                    });
                }
            });

            this.getArchive = function() {
                return archive;
            };
        }

        var arc = new Archiver();
        arc.temperature; // 'get!'
        arc.temperature = 11;
        arc.temperature = 13;
        console.log(arc.getArchive()); // [{ val: 11 }, { val: 13 }]
    </script>

其他细节略。
下一个vue用到的概念:观察者模式

观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新

Tony 是个非常向往 X公司 的程序员,但是 X公司 的 HR跟你说:“非常抱歉,我们公司最近的HC不足。”

于是,Tony真诚地跟HR说“假如贵司有合适岗位,务必及时通知我!”

一个月后,HR打电话通知Tony:“我们公司现在有合适你的岗位了,欢迎来面试!”

上面这个场景中,HR就是 Subject 而Tony是 Observer;当Tony跟HR说有岗位就通知他,作为ObserverTony正在向Subject订阅(subscribe);而HR打电话通知Tony,就是Subject 在 notify Observer

当然可能有不止一个候选人在等X公司的HC,即 Observer 可以有很多个。

发布订阅模式:

举一个例子,你在微博上关注了A,同时其他很多人也关注了A,那么当A发布动态的时候,微博就会为你们推送这条动态。A就是发布者,你是订阅者,微博就是调度中心,你和A是没有直接的消息往来的,全是通过微博来协调的(你的关注,A的发布动态)。

例子来源:
https://zhuanlan.zhihu.com/p/351750593
https://blog.csdn.net/hf872914334/article/details/88899326

这为下一篇vue 的双向绑定奠定基础

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值