기존 객체로 구조를 변경할 수 있습니까? (자바 스크립트 ES6)


135

예를 들어 두 개의 객체가있는 경우 :

var foo = {
  x: "bar",
  y: "baz"
}

var oof = {}

x와 y 값을 foo에서 oof로 옮기고 싶었습니다. es6 파괴 구문을 사용하여 그렇게 할 수 있습니까?

아마도 다음과 같은 것 :

oof{x,y} = foo

10
모든 속성을 복사하려면Object.assign(oof, foo)
elclanrs

여기 MDN에 대한 많은 파괴적인 예가 있지만, 당신이 요구하는 것을 보지 못했습니다.
jfriend00

흠 하나도 찾지 못했습니다 ..
majorBummer

없이 2 개 개의 라인 솔루션에 대한 내 대답은 아래를 참조Object.assign
Zfalen

답변:


116

추악하고 약간 반복적이지만

({x: oof.x, y: oof.y} = foo);

foo객체 의 두 값을 읽고 객체의 해당 위치에 씁니다 oof.

개인적으로 나는 아직도 오히려 읽고

oof.x = foo.x;
oof.y = foo.y;

또는

['x', 'y'].forEach(prop => oof[prop] = foo[prop]);

그러나.


2
대안 [ 'x', 'y']. forEach (prop => oof [prop] = foo [prop]); 내가 알다시피, 지금까지 유일한 DRY (반복하지 마십시오)입니다. "DRY"는 여러 키가 매핑되는 경우에 실제로 유용합니다. 한 곳만 업데이트하면됩니다. 어쩌면 내가 틀렸을 수도 있습니다. 어쨌든 고마워!
Vladimir Brasil

1
세 번째 예는 DRY이지만 문자열은 일반적으로 암시 적으로 수행하는 키로 문자열을 사용해야합니다. 그것이 다음보다 덜 귀찮다는 것을 확신하지 못합니다. const {x, y} = foo; const oof = {x, y};
Jeff Lowery

첫 번째 제안이 작동하는 jsfiddle에서 누군가 나를 보여줄 수 있습니까? 크롬에서 작동하지 않습니다 : jsfiddle.net/7mh399ow
techguy2000

@ techguy2000 이후에 세미콜론을 잊어 버렸습니다 var oof = {};.
loganfsmyth

첫 번째 코드에서 ({x: oof.x, y: oof.y} = foo)? 나는 당신이 oof에 여분의 f 를 넣었다고 생각한다 .
Sornii

38

아니요, 구조 해제는 속기의 멤버 표현식을 지원하지 않지만 현재는 일반 속성 이름 만 지원합니다. 그곳에 회담왔다 esdiscuss에 같은 약,하지만 제안 ES6으로하지 않습니다 것입니다.

Object.assign그러나 당신은 사용할 수 있습니다 -당신이 모든 자신의 속성이 필요하지 않은 경우에도 여전히 할 수 있습니다

var foo = …,
    oof = {};
{
    let {x, y} = foo;
    Object.assign(oof, {x, y})
}

3
@loganfsmyth, 귀하의 예제는 노드 4.2.2의 테스트에서 적어도 작동하지 않습니다. 와 함께 --harmony_destructuring사용 가능. "SyntaxError : Unexpected token"이 표시됩니다.
jpierson

@loganfsmyth 매우 유용한 주석이므로 적절한 답변을 제출해야합니다.
Sulliwane

@Sulliwane : 그는 그렇게 했어요 (지금) . Bergi, 아마도 Logan에 표시된 것처럼 멤버 표현식을 사용할 있도록 응답을 업데이트하는 것이 가장 좋습니다 . (사양이 2015 년 4 월과 6 월 사이에 많이 바뀌 었다는 것이 사실입니까?)
TJ Crowder

@ TJCrowder 아니요, 변경되지 않았다고 생각합니다 {oof.x, oof.y} = foo. 아니면 내가 정말로 놓쳤을 수도 있습니다.
Bergi

29

IMO 이것은 당신이 찾고있는 것을 성취하는 가장 쉬운 방법입니다.

let { prop1, prop2, prop3 } = someObject;
let data = { prop1, prop2, prop3 };

  // data === { prop1: someObject.prop1, ... }

기본적으로 변수로 구조를 변경 한 다음 이니셜 라이저 속기를 사용하여 새 객체를 만듭니다. 필요 없음Object.assign

어쨌든 이것이 가장 읽기 쉬운 방법이라고 생각합니다. 원하는 정확한 소품을 선택할 수 있습니다 someObject. 기존 객체가있는 경우 소품을 병합하려는 경우 다음과 같이하십시오.

let { prop1, prop2, prop3 } = someObject;
let data = Object.assign(otherObject, { prop1, prop2, prop3 });
    // Makes a new copy, or...
Object.assign(otherObject, { prop1, prop2, prop3 });
    // Merges into otherObject

또 다른 확실한 방법은 다음과 같습니다.

let { prop1, prop2, prop3 } = someObject;
let newObject = { prop1, prop2, prop3 };

// Merges your selected props into otherObject
Object.assign(otherObject, newObject);

나는 POST몇 개의 이산 데이터가 필요한 많은 요청에 이것을 사용 합니다. 그러나 나는 이것을하기위한 하나의 라이너가 있어야한다는 것에 동의합니다.

편집 : 추신- 최근에 첫 번째 단계에서 울트라 디스트 럭처링을 사용하여 복잡한 객체에서 중첩 된 값을 가져올 수 있다는 것을 배웠습니다! 예를 들어 ...

let { prop1, 
      prop2: { somethingDeeper }, 
      prop3: { 
         nested1: {
            nested2
         } 
      } = someObject;
let data = { prop1, somethingDeeper, nested2 };

또한 새 객체를 만들 때 Object.assign 대신 spread 연산자를 사용할 수 있습니다.

const { prop1, prop2, prop3 } = someObject;
let finalObject = {...otherObject, prop1, prop2, prop3 };

또는...

const { prop1, prop2, prop3 } = someObject;
const intermediateObject = { prop1, prop2, prop3 };
const finalObject = {...otherObject, ...intermediateObject };

나는이 접근법이 실용적이다.
Jesse

2
이것은 내가하는 일이지만 너무 건조하지는 않습니다. 많은 사람들이 실제로 필요한 것은 추출 키 기능이라고 생각합니다.
jgmjgm

@ jgmjgm 그렇습니다. 하나 내장되어 있으면 좋을 것 같지만 쓰기가 너무 어렵지는 않습니다.
Zfalen

12

다른 것보다 Object.assign객체의 확산 구문 ECMAScript를위한 2 단계 제안입니다.

var foo = {
  x: "bar",
  y: "baz"
}

var oof = { z: "z" }

oof =  {...oof, ...foo }

console.log(oof)

/* result 
{
  "x": "bar",
  "y": "baz",
  "z": "z"
}
*/

그러나이 기능을 사용하려면 사용을 필요로 stage-2하거나 transform-object-rest-spread바벨을위한 플러그인. 여기 에 바벨에 대한 데모가 있습니다.stage-2


9
이것은 실제로 기존 객체의 속성을 설정하는 것이 아니라 두 속성의 모든 속성을 포함하는 새 객체를 만듭니다.
Matt Browne

8

BabelJS 플러그인

BabelJS 를 사용하는 경우 이제 플러그인을 활성화 할 수 있습니다 babel-plugin-transform-object-from-destructuring( 설치 및 사용법은 npm 패키지 참조) ).

이 스레드에서 설명한 것과 동일한 문제가 있었으며 파괴 식에서 객체를 만들 때, 특히 속성의 이름을 바꾸거나 추가하거나 제거해야 할 때 매우 소진되었습니다. 이 플러그인을 사용하면 이러한 시나리오를 유지하는 것이 훨씬 쉬워집니다.

객체 예

let myObject = {
  test1: "stringTest1",
  test2: "stringTest2",
  test3: "stringTest3"
};
let { test1, test3 } = myObject,
  myTest = { test1, test3 };

다음과 같이 쓸 수 있습니다 :

let myTest = { test1, test3 } = myObject;

배열 예

let myArray = ["stringTest1", "stringTest2", "stringTest3"];
let [ test1, , test3 ] = myArray,
  myTest = [ test1, test3 ];

다음과 같이 쓸 수 있습니다 :

let myTest = [ test1, , test3 ] = myArray;

이것이 바로 내가 원하는 것입니다. 감사합니다!
가렛 마링

let myTest = { test1, test3 } = myObject;작동하지 않음
Eatdoku


3

다음과 같이 구조 조정을 사용할 수 있습니다.

const foo = {x:"a", y:"b"};
const {...oof} = foo; // {x:"a", y:"b"} 

또는 oof에 값이 있으면 두 객체를 병합하십시오.

const foo = {x:"a", y:"b"};
let oof = {z:"c"}
oof = Object.assign({}, oof, foo)

나는이 첫 번째 사건이 내가 찾던 것이라고 생각합니다. 크롬 콘솔에서 사용해 보았지만 작동하는 것 같습니다. 건배! @campsafari
majorBummer

1
@majorBummer 결국 전화가 왔지만 실제로 질문에 대답하지 않는 접근 방식을 고려할 것입니다. 두 가지 모두 제목 요청과 같은 기존 객체에 속성을 추가하는 대신 객체를 생성하기 때문 입니다.
loganfsmyth 19

좋은 지적이야 @loganfsmyth. 나는 그것이 가능하다는 것을 깨닫지 못했기 때문에 campSafari가 제기 한 방법에 흥분했다고 생각합니다.
majorBummer

1
새로운 객체를 만드는 것이 마음에 들지 않으면 그냥 할 수 있습니다oof = {...oof, ...foo}
Joshua Coady

2

화살표 함수에서 비 구조화 된 객체를 반환하고 Object.assign ()을 사용하여 변수에 할당 할 수 있습니다.

const foo = {
  x: "bar",
  y: "baz"
}

const oof = Object.assign({}, () => ({ x, y } = foo));

1

마른

var a = {a1:1, a2: 2, a3: 3};
var b = {b1:1, b2: 2, b3: 3};

const newVar = (() => ({a1, a2, b1, b2})).bind({...a, ...b});
const val = newVar();
console.log({...val});
// print: Object { a1: 1, a2: 2, b1: 1, b2: 2 }

또는

console.log({...(() => ({a1, a2, b1, b2})).bind({...a, ...b})()});

1

다른 객체 속성에 직접 할당 된 객체를 파괴 할 수 있습니다.

작업 예 :

let user = {};
[user.name, user.username] = "Stack Overflow".split(' ');
document.write(`
1st attr: ${user.name} <br /> 
2nd attr: ${user.username}`);

캐치하려는 것과 동일한 이름의 오브젝트 속성을 사용하여 변수를 사용하여 파기 작업을 수행 할 수 있습니다.

let user = { name: 'Mike' }
let { name: name } = user;

이 방법을 사용하십시오 :

let user = { name: 'Mike' }
let { name } = user;

동일한 속성 이름을 갖는 경우 새 값을 객체 구조에 설정할 수있는 것과 같은 방법입니다.

이 작동 예를보십시오.

// The object to be destructed
let options = {
  title: "Menu",
  width: 100,
  height: 200
};

// Destructing
let {width: w, height: h, title} = options;

// Feedback
document.write(title + "<br />");  // Menu
document.write(w + "<br />");      // 100
document.write(h);                 // 200


0

이것은 크롬 53.0.2785.89에서 작동합니다

let foo = {
  x: "bar",
  y: "baz"
};

let oof = {x, y} = foo;

console.log(`oof: ${JSON.stringify(oof)});

//prints
oof: {
  "x": "bar",
  "y": "baz"
}

7
안타깝게도 (적어도 Chrome에서는) 전체 구조를 oof참조 foo하고 무시 하는 것처럼 보입니다 . oof === foo그리고 let oof = { x } = foo아직 반환{ x, y }
Theo.T

@ Theo.T 좋은 캐치. 안됐다가 있다고, 내가 다른 방법 발견 할 것이다
user1577390

이것은 JS가 혼란 스러울 수있는 방법을 보여주기 위해 유지해야 할 가치가 있습니다.
jgmjgm

0

이 방법을 생각해 냈습니다.

exports.pick = function pick(src, props, dest={}) {
    return Object.keys(props).reduce((d,p) => {
        if(typeof props[p] === 'string') {
            d[props[p]] = src[p];
        } else if(props[p]) {
            d[p] = src[p];
        }
        return d;
    },dest);
};

다음과 같이 사용할 수 있습니다.

let cbEvents = util.pick(this.props.events, {onFocus:1,onBlur:1,onCheck:'onChange'});
let wrapEvents = util.pick(this.props.events, {onMouseEnter:1,onMouseLeave:1});

즉, 원하는 속성을 선택하여 새 객체에 넣을 수 있습니다. 달리 _.pick이름을 동시에 바꿀 수도 있습니다.

소품을 기존 객체에 복사하려면 destarg를 설정하십시오 .


0

이것은 일종의 부정 행위이지만, 이런 식으로 할 수 있습니다 ...

const originalObject = {
  hello: 'nurse',
  meaningOfLife: 42,
  your: 'mom',
};

const partialObject = (({ hello, your }) => {
  return { hello, your };
})(originalObject);

console.log(partialObject); // ​​​​​{ hello: 'nurse', your: 'mom' }​​​​​

실제로, 나는 당신이 그것을 거의 사용하고 싶지 않다고 생각합니다. 다음은 훨씬 더 명확하지만 거의 재미는 없습니다.

const partialObject = {
  hello: originalObject.hello,
  your: originalObject.your,
};

또 다른 완전히 다른 경로는 프로토 타입을 사용한 뭉킹을 포함합니다 (지금 조심하세요).

if (!Object.prototype.pluck) {
  Object.prototype.pluck = function(...props) {
    return props.reduce((destObj, prop) => {
      destObj[prop] = this[prop];

      return destObj;
    }, {});
  }
}

const originalObject = {
  hello: 'nurse',
  meaningOfLife: 42,
  your: 'mom',
};

const partialObject2 = originalObject.pluck('hello', 'your');

console.log(partialObject2); // { hello: 'nurse', your: 'mom' }

0

이것은 내가 얻을 수있는 가장 읽기 쉽고 가장 짧은 솔루션입니다.

let props = { 
  isValidDate: 'yes',
  badProp: 'no!',
};

let { isValidDate } = props;
let newProps = { isValidDate };

console.log(newProps);

출력됩니다 { isValidDate: 'yes' }

언젠가 let newProps = ({ isValidDate } = props)ES6가 지원하지 않는 것은 아니지만 불행히도 말할 수 있으면 좋을 것 입니다.


0

그것은 아름다운 방법이 아니며 권장하지는 않지만 지식을 위해서만 가능합니다.

const myObject = {
  name: 'foo',
  surname: 'bar',
  year: 2018
};

const newObject = ['name', 'surname'].reduce(
  (prev, curr) => (prev[curr] = myObject[curr], prev),
  {},
);

console.log(JSON.stringify(newObject)); // {"name":"foo","surname":"bar"}

0

JSON 클래스 메소드를 사용하여 다음과 같이 달성 할 수 있습니다.

const foo = {
   x: "bar",
   y: "baz"
};

const oof = JSON.parse(JSON.stringify(foo, ['x','y']));
// output -> {x: "bar", y: "baz"}

결과 객체에 추가해야하는 속성을 stringify배열 형식으로 작동하기위한 두 번째 인수로 전달 합니다.

JSON 용 MDN Doc.stringify

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.