javascript 为对象中的所有属性设置

javascript get set for all properties in an object

我正在尝试构建一种方法,该方法将自动为对象内的所有属性创建获取和设置函数。理想情况下,当有人更新对象中的 属性 时,我想触发脏数据在界面中更新。

问题:在遍历对象的属性时,最后一个属性的set函数好像应用到之前所有的属性上。我无法弄清楚为什么会发生这种情况,因为 属性 在每个实例中显然都是唯一的(我已经根据原始 属性 名称创建了一个 _prop 版本)。

我用一些准系统代码创建了一个 fiddle。 https://jsfiddle.net/rcmwxzvL/6/

这里是那些非fiddleRS 的代码;这个有显示正在设置的 _prop 值的控制台命令。奇怪!

var superhero = {
        id: 0,
        firstname: 'Duck',
        lastname: 'Darkwing'
    };
    
    for (property in superhero)
    {
        var propertyName = property.toString();
    
        // Store initial value in '_var' before overwriting it with get/set
        this['_' + propertyName] = superhero[property];
    
        Object.defineProperty(superhero, propertyName, {
            set: function(value) {
                this['_' + propertyName] = value;
            },
            get: function() {
                return this['_' + propertyName];
            }
        });
    }
    console.log('--- Initial Value of test ---');
    console.log(superhero);
    console.log('-----------------------------');
    
    superhero.firstname = 'Kal';
    superhero.lastname = 'El';
    
    console.log (superhero.firstname + ' ' + superhero.lastname);

最后一个控制台的输出是:El El 应该是 Kal El

console.log(superhero);的输出:

firstname: "El"
id:(...)
lastname:(...)
_firstname:"Duck"
_id:0
_lastname:"El"
get firstname:ƒ ()
set firstname:ƒ (value)
get id:ƒ ()
set id:ƒ (value)
get lastname:ƒ ()
set lastname:ƒ (value)

我的最终目标是创建一个非常简单的库,可以自动将对象中的所有属性数据绑定到 HTML 界面元素。我写了映射片,由于上述问题,当直接访问对象内部的属性时,我无法让接口更新。

谢谢;感谢社区可以提供的任何帮助。

你需要改变

var propertyName = property.toString();

let propertyName = property.toString();

否则,每当您更新 propertyName 时,它都会更改所有属性,因为 var 创建的范围仅允许单个引用(功能范围),而如果您使用 [=15 创建它=],每个循环步骤都有自己的引用(块作用域)。

var superhero = {
        id: 0,
        firstname: 'Duck',
        lastname: 'Darkwing'
    };
    
    for (property in superhero)
    {
        let propertyName = property.toString();
    
        // Store initial value in '_var' before overwriting it with get/set
        this['_' + propertyName] = superhero[property];
    
        Object.defineProperty(superhero, propertyName, {
            set: function(value) {
                this['_' + propertyName] = value;
            },
            get: function() {
                return this['_' + propertyName];
            }
        });
    }
    console.log('--- Initial Value of test ---');
    console.log(superhero);
    console.log('-----------------------------');
    
    superhero.firstname = 'Kal';
    superhero.lastname = 'El';
    
    console.log (superhero.firstname + ' ' + superhero.lastname);