Person(options) {
let vm = this;
vm.$options = options;
if(options.data) {
initData(vm);
}
if(options.methods) {
initMethods(vm, options.methods);
}
function initData(vm) {
let data = vm._data = vm.$options.data;
let keys = Object.keys(data);
let len = keys.length;
while(len--) {
let key = keys[len];
proxy(vm, "_data", key);
}
}
function proxy(target, sourceKeys, key) {
var sharedPropertyDefinition = {
enumerable: true,
configurable: true,
get: noop,
set: noop
}
sharedPropertyDefinition.get = function() {
return this[sourceKeys][key]
}
sharedPropertyDefinition.set = function(val) {
this[sourceKeys][key] = val;
}
Object.defineProperty(target, key, sharedPropertyDefinition);
}
function noop(a,b,c){
console.log(a,b,c);
}
function initMethods(vm, methods) {
for (let key in methods) {
vm[key] = typeof methods[key] === 'function' ? methods[key].bind(vm) : noop;
}
}
},
init() {
let p1 = new this.Person({
data: {
name: 'pino',
age: 18
},
methods: {
sayName() {
console.log('I am' + this.name);
}
}
});
console.log(p1.name);
p1.sayName();
}
主要是 proxy 代理,正常访问是 this.name ,但是挟持了一下就变成了 this. _data.name。赋值的时候同样。
然后把 methods 的中的方法,在 vm 上也来了一份,就可以 vm.方法名。
不懂的是,vm 与 this 怎么交互的,_data 这个东西只给了 vm,结果 this 也有了。