为了深入了解vue的原理,Object.defineProperty这个方法必须会。
Object.defineProperty(obj, prop, descriptor)
该方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
- obj:要定义属性的对象。
- prop:要定义或修改的属性的名称或 Symbol 。
- descriptor:描述符对象,要定义或修改的属性描述符。
属性/方法 | 语义 | 默认值 |
---|---|---|
configurable | 对象的属性是否可以被删除, 以及除 value 和 writable 特性外的其他特性是否可以被修改。 | false(不可删) |
enumerable | 定义了对象的属性是否可以在 for…in 循环和 Object.keys() 中被枚举。 | false(直接定义的属性为true) |
value | 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。 | undefined |
writable | writable 属性设置为 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 的双向绑定奠定基础