有没有一种方法可以强制JavaScript元素根据最初的定义重新定义自己?

5

我正在玩对象和构造函数等内容,我想知道是否有一种方法可以根据变量的初始定义来绑定一个值。我有以下代码:

typescript

let cr = "create",
  ap = "apply",
  $this = {
    set: (prop, value) => {
      this[prop] = value;
    }
  };
function creator() {
  this.$ = (array: Object[]) => {
    array.forEach((kp: Object) => {
      let key = Object.keys(kp)[0];
      let val = kp[Object.keys(kp)];
      $this[key] = val;
      creator.create(key, { value: val });
    });
  };
  this.apply = (...objects: Object[]) => {
    objects.forEach((obj: Object) => {
      creator.call(obj);
    });
  };
}
function create(obj) {
  function createValues(arr) {
    let instance: Object = new obj();
    let vals: any[] = [];
    arr.forEach(name => {
      vals.push(instance[name]);
    });
    return vals;
  }
  let names: string[] = Object.getOwnPropertyNames(new obj());
  let values: string[] = createValues(names);
  return combineArrays(names, values);
}
function combineArrays(arr1, arr2): { $?: any } { // the question mark removes an IDE error
  let newObj: Object = {};
  arr1.forEach(prop => {
    newObj[prop] = arr2[arr1.indexOf(prop)];
  });
  return newObj;
}
Object.prototype.create = function(prop, options) {
  return Object.defineProperty(this, prop, options);
};
create(creator).$([
  { hi: "hi" }, 
  { bye: $this["hi"] } // this is the important stuff
]);

我想知道在$this变量的set函数中,是否有一种方法可以检测它是如何被设置的,从而确定该值是否已更改,因此它的值应该是新的(如果这有任何意义的话)?比方说你有这样一个函数:

let $this = {
  set: function(prop, value) {
    this[prop] = value;
  } 
}
let name = 'Ezra';
$this['name'] = name;
// then :
name = 'Bob';
// change $this.name too, so then:
console.log($this.name);
// >> 'Bob'

我相信这被称为数据绑定,但我不确定如何在不创建无数代理的情况下完成它。

1个回答

3
你所描述的并不是真正的“数据绑定”,而是按引用传递。在你的例子中,你期望对name的更新会反映在$this['name']中。只有当你传递一个引用(或指针)到变量时才可能实现这一点。
然而,在这种情况下,变量是一个string,而JavaScript中的字符串是不可变的

没有任何字符串方法会改变它们操作的字符串,它们都返回新字符串。原因是字符串是不可变的——它们不能改变,我们只能创造新的字符串。

因此,逐步地看你的例子:
这创建了一个名为'Ezra'的新字符串,并将一个名为name的变量赋值为引用该字符串。
let name = 'Ezra';

这将在$this中创建(或设置)一个名为'name'的属性,该属性引用name中的字符串(即'Ezra')。
$this['name'] = name;

这将创建一个名为'Bob'的新字符串,并将其存储在名为name的变量中。该变量已经存在。这不会改变先前保存在其中的值。相反,name正在更新以指向一个新的引用。
// then :
name = 'Bob';

然而,如果你传递一个对象,你会注意到你可以实际上改变它。这是因为对象是按引用传递的,你可以在该引用处改变值。
例如:
// Create a new value that stores an object, with a property 'firstName'
let name = { firstName: 'Ezra' };

// Assign myObject to $this['name']. Now $this['name'] and name both point to the same reference.
$this['name'] = name;

// Change the value in the object pointed-to by name
name.firstName = 'Bob'

console.log($this['name'].firstName); // <- This will output 'Bob'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接