概述

  1. export function defineReactive(data, key, val) {
  2. Object.defineProperty(data, key, {
  3. enumarable: true,
  4. configurable: true,
  5. get: function () {
  6. return val;
  7. }),
  8. set: function (newVal) {
  9. if (val === newVal) {
  10. return;
  11. } else {
  12. val = newVal;
  13. }
  14. }
  15. }

为什么这里要定义一个val的形参呢!我一开始觉得这个形参是没有任何必要的,因为我们已经有了datakey,那我们自然而然就能得到val对应的值:

  1. export function defineReactive(data, key) {
  2. Object.defineProperty(data, key, {
  3. enumarable: true,
  4. configurable: true,
  5. get: function () {
  6. return data[key];
  7. }),
  8. set: function (newVal) {
  9. if (data[key] === newVal) {
  10. return;
  11. } else {
  12. //导致溢出的代码
  13. data[key] = newVal;
  14. }
  15. }
  16. }

上述代码是存在很大的问题的:在**set**中,又进行值的设置必然会导致再次触发set方法,从而导致这个set函数一直被推入执行栈中导致栈溢出。这里显然是我对**Object.defineProperty**API理解不够深入。所以,必然我是要在**Object.defineProperty**的外围声明一个变量。在**get**函数中返回这个变量。在**set**函数中修改这个变量。所以这个形参**val**是必需的。
实际上,这里形成了一个闭包。这个val变量所在的函数执行上下文(也就是这次defineReactive函数调用产生的执行上下文)是不会销毁的。