概述
export function defineReactive(data, key, val) {
Object.defineProperty(data, key, {
enumarable: true,
configurable: true,
get: function () {
return val;
}),
set: function (newVal) {
if (val === newVal) {
return;
} else {
val = newVal;
}
}
}
为什么这里要定义一个val
的形参呢!我一开始觉得这个形参是没有任何必要的,因为我们已经有了data
和key
,那我们自然而然就能得到val
对应的值:
export function defineReactive(data, key) {
Object.defineProperty(data, key, {
enumarable: true,
configurable: true,
get: function () {
return data[key];
}),
set: function (newVal) {
if (data[key] === newVal) {
return;
} else {
//导致溢出的代码
data[key] = newVal;
}
}
}
上述代码是存在很大的问题的:在**set**
中,又进行值的设置必然会导致再次触发set方法,从而导致这个set函数一直被推入执行栈中导致栈溢出。这里显然是我对**Object.defineProperty**
API理解不够深入。所以,必然我是要在**Object.defineProperty**
的外围声明一个变量。在**get**
函数中返回这个变量。在**set**
函数中修改这个变量。所以这个形参**val**
是必需的。
实际上,这里形成了一个闭包。这个val变量所在的函数执行上下文(也就是这次defineReactive
函数调用产生的执行上下文)是不会销毁的。