program story

JavaScript : 값으로 객체를 전달하는 방법?

inputbox 2020. 9. 18. 08:09
반응형

JavaScript : 값으로 객체를 전달하는 방법?


  • 객체를 매개 변수로 전달할 때 JavaScript는 객체를 참조로 전달하므로 객체의 로컬 복사본을 생성하기 어렵습니다.

    var o = {};
    (function(x){
        var obj = x;
        obj.foo = 'foo';
        obj.bar = 'bar';
    })(o)
    

    o.foo하고 .bar.

  • 복제를 통해이 문제를 해결할 수 있습니다. 간단한 예 :

    var o = {};
    
    function Clone(x) {
       for(p in x)
       this[p] = (typeof(x[p]) == 'object')? new Clone(x[p]) : x[p];
    }
    
    (function(x){
        var obj = new Clone(x);
        obj.foo = 'foo';
        obj.bar = 'bar';
    })(o)
    

    o필요가 없습니다 .foo.bar.


질문

  1. 로컬 복사본 / 복제를 만드는 것 외에 값으로 개체를 전달하는 더 좋은 방법이 있습니까?

별로.

당신이 실제로 필요에 따라 하나의 가능성은 세트에있을 수 있습니다 o새로운 객체의 프로토있다.

var o = {};
(function(x){
    var obj = Object.create( x );
    obj.foo = 'foo';
    obj.bar = 'bar';
})(o);

alert( o.foo ); // undefined

따라서 추가하는 속성 obj은에 추가 되지 않습니다 o. 의 속성 obj과 동일한 속성 이름으로에 추가 된 모든 속성 은 속성을 o섀도 잉합니다 o.

물론에 추가 된 모든 속성 은 그림자가 적용되지 않은 경우 o에서 사용할 수 있으며 프로토 타입 체인에있는 obj모든 개체는 .oo

또한 objArray와 같은 다른 개체를 참조하는 속성이있는 경우 개체에 구성원을 추가하기 전에 해당 개체를 그림자로 처리해야합니다. 그렇지 않으면 해당 구성원이에 추가되고 obj모든 개체간에 공유됩니다. 이 obj프로토 타입 체인에.

var o = {
    baz: []
};
(function(x){
    var obj = Object.create( x );

    obj.baz.push( 'new value' );

})(o);

alert( o.baz[0] );  // 'new_value'

여기에서 당신은 당신의 배열을 그림자하지 않았기 때문에 것을 알 수 있습니다 bazo로모그래퍼 baz에 특성 objo.baz배열이 수정됩니다.

따라서 대신 먼저 그림자를 만들어야합니다.

var o = {
    baz: []
};
(function(x){
    var obj = Object.create( x );

    obj.baz = [];
    obj.baz.push( 'new value' );

})(o);

alert( o.baz[0] );  // undefined

Check out this answer https://stackoverflow.com/a/5344074/746491 .

In short, JSON.parse(JSON.stringify(obj)) is a fast way to copy your objects, if your objects can be serialized to json.


Here is clone function that will perform deep copy of the object:

function clone(obj){
    if(obj == null || typeof(obj) != 'object')
        return obj;

    var temp = new obj.constructor(); 
    for(var key in obj)
        temp[key] = clone(obj[key]);

    return temp;
}

Now you can you use like this:

(function(x){
    var obj = clone(x);
    obj.foo = 'foo';
    obj.bar = 'bar';
})(o)

Use Object.assign()

Example:

var a = {some: object};
var b = new Object;
Object.assign(b, a);
// b now equals a, but not by association.

A cleaner example that does the same thing:

var a = {some: object};
var b = Object.assign({}, a);
// Once again, b now equals a.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign


You're a little confused about how objects work in JavaScript. The object's reference is the value of the variable. There is no unserialized value. When you create an object, its structure is stored in memory and the variable it was assigned to holds a reference to that structure.

Even if what you're asking was provided in some sort of easy, native language construct it would still technically be cloning.

JavaScript is really just pass-by-value... it's just that the value passed might be a reference to something.


Use this

x = Object.create(x1);

x and x1 will be two different object,change in x will not change x1


Javascript always passes by value. In this case it's passing a copy of the reference o into the anonymous function. The code is using a copy of the reference but it's mutating the single object. There is no way to make javascript pass by anything other than value.

In this case what you want is to pass a copy of the underlying object. Cloning the object is the only recourse. Your clone method needs a bit of an update though

function ShallowCopy(o) {
  var copy = Object.create(o);
  for (prop in o) {
    if (o.hasOwnProperty(prop)) {
      copy[prop] = o[prop];
    }
  }
  return copy;
}

As a consideration to jQuery users, there is also a way to do this in a simple way using the framework. Just another way jQuery makes our lives a little easier.

var oShallowCopy = jQuery.extend({}, o);
var oDeepCopy    = jQuery.extend(true, {}, o); 

references :


Actually, Javascript is always pass by value. But because object references are values, objects will behave like they are passed by reference.

So in order to walk around this, stringify the object and parse it back, both using JSON. See example of code below:

var person = { Name: 'John', Age: '21', Gender: 'Male' };

var holder = JSON.stringify(person);
// value of holder is "{"Name":"John","Age":"21","Gender":"Male"}"
// note that holder is a new string object

var person_copy = JSON.parse(holder);
// value of person_copy is { Name: 'John', Age: '21', Gender: 'Male' };
// person and person_copy now have the same properties and data
// but are referencing two different objects

I needed to copy an object by value (not reference) and I found this page helpful:

What is the most efficient way to deep clone an object in JavaScript?. In particular, cloning an object with the following code by John Resig:

//Shallow copy
var newObject = jQuery.extend({}, oldObject);
// Deep copy
var newObject = jQuery.extend(true, {}, oldObject);

With the ES6 syntax:

let obj = Object.assign({}, o);


When you boil down to it, it's just a fancy overly-complicated proxy, but maybe Catch-All Proxies could do it?

var o = {
    a: 'a',
    b: 'b',
    func: function() { return 'func'; }
};

var proxy = Proxy.create(handlerMaker(o), o);

(function(x){
    var obj = x;
    console.log(x.a);
    console.log(x.b);
    obj.foo = 'foo';
    obj.bar = 'bar';
})(proxy);

console.log(o.foo);

function handlerMaker(obj) {
  return {
   getOwnPropertyDescriptor: function(name) {
     var desc = Object.getOwnPropertyDescriptor(obj, name);
     // a trapping proxy's properties must always be configurable
     if (desc !== undefined) { desc.configurable = true; }
     return desc;
   },
   getPropertyDescriptor:  function(name) {
     var desc = Object.getOwnPropertyDescriptor(obj, name); // not in ES5
     // a trapping proxy's properties must always be configurable
     if (desc !== undefined) { desc.configurable = true; }
     return desc;
   },
   getOwnPropertyNames: function() {
     return Object.getOwnPropertyNames(obj);
   },
   getPropertyNames: function() {
     return Object.getPropertyNames(obj);                // not in ES5
   },
   defineProperty: function(name, desc) {

   },
   delete:       function(name) { return delete obj[name]; },   
   fix:          function() {}
  };
}

If you are using lodash or npm, use lodash's merge function to deep copy all of the object's properties to a new empty object like so:

var objectCopy = lodash.merge({}, originalObject);

https://lodash.com/docs#merge

https://www.npmjs.com/package/lodash.merge


use obj2 = { ...obj1 } Now both objects have same value bust different reference

참고URL : https://stackoverflow.com/questions/7574054/javascript-how-to-pass-object-by-value

반응형