简体   繁体   English

JS函数将一个对象作为输入并返回一个对象,该对象对作为参数传递的对象执行操作

[英]JS function takes an object as input and returns an object that performs actions on the object passed as a parameter

I wrote a function that inputs an object that can set the value to the key or assign an object directly. 我编写了一个函数,该函数输入可以设置键值或直接分配对象的对象。 The setter and getter work fine, but when the object was assigned to another object, it doesn't work well (the object does not change at all). setter和getter可以正常工作,但是将对象分配给另一个对象后,它不能很好地工作(该对象完全不会​​更改)。

The weird thing is when the object was output "inside" the functions the result is correct. 奇怪的是,当对象在函数内部“输出”时,结果是正确的。 But the result is not what I expected "outside" the functions. 但是结果不是我期望的功能“之外”。 Could anyone explain this? 有人可以解释吗?

function foo(input) {
    return {
        set: function(key, value) {
            input[key] = value;
            console.log(input);
        },
        get: function(key) {
            return input[key];
        },
        assign: function(object) {
            input = Object.assign({}, object);
            console.log(input);
        }
    };
};

var obj = {},
    bar = foo(obj);

bar.set('x', 1);    // {x: 1}
console.log(obj);   // {x: 1}
bar.set('y', 2);    // {x: 1, y: 2}
console.log(obj);   // {x: 1, y: 2}   so far so good
bar.assign({        // {a: 5, b: 10}
    a: 5,
    b: 10
});
console.log(obj);   // {x: 1, y: 2}   supposed to be {a: 5, b: 10} but it was not
bar.assign({        // {a: 15}
    a: 15
});
console.log(obj);   // {x: 1, y: 2}   didn't change at all
bar.set('b', 20);   // {a: 15, b: 20}
console.log(obj);   // {x: 1, y: 2}
console.log(bar.get('a'));  // 15

Here: input = Object.assign({}, object) , you are assigning to new object ( {} ), so you aren't editing originally passed object. 在这里: input = Object.assign({}, object) ,您正在分配给新对象( {} ),因此您无需编辑原始传递的对象。 Changing this line just to Object.assign(input, object) should do what you want. 仅将此行更改为Object.assign(input, object)完成您想要的操作。

The issue is that it is creating new object each time you call assign function. 问题在于,每次调用assign函数时,它都在创建新对象。 To extend the input object use Object.assign(input, object) instead of input = Object.assign({}, object); 要扩展输入对象,请使用Object.assign(input,object)而不是input = Object.assign({},object);。

function foo(input) {
    return {
        set: function(key, value) {
            input[key] = value;
            console.log(input);
        },
        get: function(key) {
            return input[key];
        },
        assign: function(object) {
            Object.assign(input, object);
            console.log(input);
        }
    };
};
 var obj = {} 

The above creates an object (which we will call A) and assigns a reference to it to obj . 上面的代码创建了一个对象(我们将其称为A),并将对它的引用分配给obj

 bar = foo(obj); 

Now you pass the value of obj , which is the reference to A, to foo . 现在,将obj的值(即对A的引用)传递给foo

 function foo(input) 

… and then you assign it to input . …然后将其分配给input

So now you have two variables ( input and obj ) which both have values which are a reference to A. 因此,现在您有了两个变量( inputobj ),这两个变量都具有引用A的值。

 input = Object.assign({}, object); 

Now you create a new object (B), copy everything from object on to it, and then assign that to input . 现在,您创建一个新对象(B),将所有内容从该object复制到该object ,然后将其分配给input

So now you have the two variables, input pointing to B and obj pointing to A . 因此,现在有了两个变量, input指向Bobj指向A

 console.log(obj); // {x: 1, y: 2} supposed to be {a: 5, b: 10} but it was not 

That's because you are looking at obj but the values you expect are on input (which you can't access because it isn't in scope). 那是因为您正在查看obj但您期望的值是在input (您无法访问它,因为它不在范围内)。


You can modify the existing object instead of creating a new one: 您可以修改现有对象,而不用创建一个新对象:

    assign: function(object) {
        Object.assign(input, object);
        console.log(input);
    }

… but that won't delete the existing values. …但这不会删除现有值。

If you want to do that, then you have to do so explicitly: 如果要这样做,则必须明确地这样做:

    assign: function(object) {
        for (var prop in object) {
          delete object[prop];
        }
        Object.assign(input, object);
        console.log(input);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM