1. 重点方法:
1.1 Object.keys(obj): 得到对象自身可枚举属性组成的数组
前提是指定属性名可以枚举
1.2 Object.defineProperty(obj, prop, descriptor)
示例:
const obj = {
firstName: 'A',
lastName: 'B'
}
//obj.fullName = 'A-B'
Object.defineProperty(obj, 'fullName', {
// 属性描述符:
configurable: false, //是否可以属性
enumerable: true,//是否可以枚举,也就是是否可以调用Object.keys(obj)方法
// 数据描述符
value: '',//初始数据
writable: true,//是否可以改变
//访问描述符
// get : 回调函数, 根据其它相关的属性动态计算得到当前属性值
// set : 回调函数, 监视当前属性值的变化,更新其相关的属性值
// 当读取对象此属性值时自动调用, 将函数返回的值作为属性值, this为obj
get() {
return this.firstName + "-" + this.lastName
},
// 当修改了对象的当前属性值时自动调用, 监视当前属性值的变化, 修改相关的属性, this为obj
set(value) {
const names = value.split('-')
this.firstName = names[0]
this.lastName = names[1]
}
})
2. 源码:
/*
相关于Vue的构造函数
*/
function MVVM(options) {
// 将选项对象保存到vm
this.$options = options;
// 将data对象保存到vm和data变量中
var data = this._data = this.$options.data;
//将vm保存在me变量中
var me = this;
// 遍历data中所有属性
Object.keys(data).forEach(function (key) { // 属性名: name
// 对指定属性实现代理
me._proxy(key);
});
// 对data进行监视
observe(data, this);
// 创建一个用来编译模板的compile对象
this.$compile = new Compile(options.el || document.body, this)
}
MVVM.prototype = {
$watch: function (key, cb, options) {
new Watcher(this, key, cb);
},
// 对指定属性实现代理
_proxy: function (key) {
// 保存vm
var me = this;
// 给vm添加指定属性名的属性(使用属性描述)
Object.defineProperty(me, key, {
configurable: false, // 不能再重新定义
enumerable: true, // 可以枚举
// 当通过vm.name读取属性值时自动调用
get: function proxyGetter() {
// 读取data中对应属性值返回(实现代理读操作)
return me._data[key];
},
// 当通过vm.name = 'xxx'时自动调用
set: function proxySetter(newVal) {
// 将最新的值保存到data中对应的属性上(实现代理写操作)
me._data[key] = newVal;
}
});
}
};
网友评论