最近在读vue源码,发现有两种原型链上设置属性的方法:
Vue.prototype.$watch
Object.defineProperty(Vue.prototype, '$data', dataDef)
在疑惑为什么会这么写时,查阅相关资料,有了以下的见解,放出代码,可粘贴到f12中运行:
var obj = {};
Object.defineProperty(obj, 'a', {
enumerable: true,
// 当且仅当该属性的 `enumerable` 键值为 `true` 时,该属性才会出现在对象的枚举属性中。
// 默认为false。
configurable: false,
// 当且仅当该属性的 `configurable` 键值为 `true` 时,
// 该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。
// 默认为false
value: { key: 1 }
});
var obj2 = {}
Object.prototype.b = 'ss'
for(var key in obj){
console.log('key:', key);
}
// b在原型链上,打印出来为空,原型链上可以找到
console.log(obj, obj2, obj.b, obj2.b)
打印下来为:
由此可得出:
-
用
XX.prototype.xx
在(class XX
)类里可以设置属性,var x = new XX()
时,实例化的任何对象可以调用xx这个属性。 -
用
Object.defineProperty(x, xx, { value: 'xxx' })
只适用于x这个实例化对象 -
我们再来看这两句代码:
Vue.prototype.$watch
Object.defineProperty(Vue.prototype, '$data', dataDef)
它的意思为
$watch
可以在任何new Vue()的实例化对象中调用到。如const app2 = new Vue();app2.$watch();
,$data
只有在Vue类的原型链上拿取,const obj = {}
没有$data
这个方法。 -
两者在条件一致(不可改变。不可遍历)时,都可以用没有区别。