Var olan bir nesneyi yok etmek mümkün mü? (Javascript ES6)


137

Örneğin iki nesnem varsa:

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

ve

var oof = {}

ve x ve y değerlerini foo'dan oof'a aktarmak istedim. Bunu es6 yıkıcı sözdizimini kullanarak yapmanın bir yolu var mı?

belki şöyle bir şey:

oof{x,y} = foo

10
Tüm özellikleri kopyalamak istiyorsanızObject.assign(oof, foo)
elclanrs

MDN'de birçok yıkıcı örnek var , ancak sorduğunuzu göremiyorum.
jfriend00

Hmm ben de bulamadım ..
majorBummer

İki satırlı çözüm olmadan aşağıdaki Object.assign
cevabıma bakın

Yanıtlar:


118

Çirkin ve biraz tekrarlı olsa da yapabilirsin

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

Bu, foonesnenin iki değerini okuyacak ve bunları oofnesne üzerindeki ilgili konumlarına yazacaktır .

Şahsen hala okumayı tercih ederim

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

veya

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

rağmen.


2
Alternatif ['x', 'y']. ForEach (prop => oof [prop] = foo [prop]); Gördüğüm gibi, şimdiye kadar sadece KURU (kendinizi tekrar etmeyin). "KURU", eşlenecek birkaç anahtar durumunda gerçekten yararlı olacaktır. Yalnızca bir yeri güncellemeniz gerekir. Belki hatalıyım. Yine de teşekkürler!
Vladimir Brasil

1
Üçüncü örnek DRY'dir, ancak javascript normalde örtük olarak yaptığı gibi dizeleri anahtar olarak kullanmanız gerekir. Bunun şu kadar rahatsız edici olduğuna ikna olmadım: const {x, y} = foo; sabit oof = {x, y};
Jeff Lowery

Birisi bana jsfiddle'da ilk önerinin nerede çalıştığını gösterebilir mi? Burada chrome üzerinde çalışmıyor: jsfiddle.net/7mh399ow
techguy2000

@ techguy2000 Sonrasında noktalı virgülü unuttunuz var oof = {};.
loganfsmyth

İlk kodda olmamalı ({x: oof.x, y: oof.y} = foo)mı? Bir tane daha koyduk düşünüyorum f içinde oof .
Sornii

38

Hayır, yok etme, üye ifadelerini kısayollarla desteklemez, şu anda yalnızca düz özellik adlarını destekler. Bu tür tartışmalar hakkında konuşmalar yapıldı, ancak hiçbir teklif ES6'ya girmeyecek.

Object.assignAncak kullanabilirsiniz - tüm mülklere ihtiyacınız yoksa, yine de yapabilirsiniz

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

3
@loganfsmyth, örneğiniz en azından 4.2.2 düğümüyle yaptığım testlerde benim için çalışmıyor. ile --harmony_destructuringsağladı. "SyntaxError: Beklenmeyen belirteç" görüyorum.
jpierson

@loganfsmyth, bu çok yararlı bir yorum imo olduğu için uygun bir cevap göndermelisiniz.
Sulliwane

@Sulliwane: Bunu yaptı (şimdi) . Bergi, muhtemelen bunu sesleniyorum cevabını güncellemek için en iyi olurdu olabilir Logan tarafından gösterildiği gibi üye ifadeler kullanır. (Spesifikasyonun Nisan ve Haziran 2015 arasında bu kadar değiştiği gerçekten doğru mu?)
TJ Crowder

@TJCrowder Hayır, değiştiğini sanmıyorum, sanırım bundan bahsediyordum {oof.x, oof.y} = foo. Ya da belki gerçekten özlemiştim.
Bergi

29

IMO Bu, aradığınız şeyi başarmanın en kolay yoludur:

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

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

Temel olarak, değişkenleri yok edin ve ardından yeni bir nesne oluşturmak için başlatıcı kısayolunu kullanın. İhtiyaç yokObject.assign

Zaten bence bu en okunaklı yol. Bu vesile ile tam olarak someObjectistediğiniz sahne donanımını seçebilirsiniz . Mevcut bir nesneniz varsa, sadece sahne malzemelerini birleştirmek istiyorsanız, bunun gibi bir şey yapın:

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

Tartışmalı olarak daha temiz bir başka yazma yolu şudur:

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

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

Bunu POSTyalnızca birkaç ayrı veriye ihtiyaç duyduğum çok sayıda istek için kullanıyorum . Ancak, bunu yapmak için tek bir yol olması gerektiğine katılıyorum.

DÜZENLEME: PS - Geçenlerde, karmaşık nesnelerden iç içe geçmiş değerleri çıkarmak için ultra yıkmayı ilk adımda kullanabileceğinizi öğrendim! Örneğin...

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

Ayrıca, yeni bir nesne oluştururken Object.assign yerine yayılma operatörünü kullanabilirsiniz:

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

Veya...

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

Bu yaklaşımı seviyorum, pragmatik.
Jesse

2
Yaptığım şey bu ama çok kuru değil. Bence pek çok insanın gerçekten ihtiyacı olan şey sadece bir anahtar çıkarma işlevi.
jgmjgm

@jgmjgm evet, yerleşik bir tane olması güzel olurdu ama sanırım bu da yazmak çok zor değil.
Zfalen

12

Bunun dışında Object.assign, ECMAScript için bir Aşama 2 önerisi olan nesne yayma sözdizimi vardır.

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

var oof = { z: "z" }

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

console.log(oof)

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

Ama bu özelliği kullanmak için size kullanımına ihtiyaç stage-2veya transform-object-rest-spreadbabel için eklentisi. İşte babel ile ilgili bir demostage-2


9
Bu aslında var olan nesnenin özelliklerini ayarlamaz, bunun yerine her ikisinin tüm özelliklerini içeren yeni bir nesne oluşturur.
Matt Browne

8

BabelJS eklentisi

BabelJS kullanıyorsanız , şimdi eklentimi etkinleştirebilirsiniz babel-plugin-transform-object-from-destructuring( kurulum ve kullanım için npm paketine bakın ).

Bu iş parçacığında anlatılanla aynı sorunu yaşadım ve özellikle bir özelliği yeniden adlandırmanız, eklemeniz veya kaldırmanız gerektiğinde, yıkıcı bir ifadeden bir nesne oluşturduğunuzda çok yorucuydu. Bu eklenti ile bu tür senaryoları sürdürmek sizin için çok daha kolay hale geliyor.

Nesne örneği

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

şu şekilde yazılabilir:

let myTest = { test1, test3 } = myObject;

Dizi örneği

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

şu şekilde yazılabilir:

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

Tam da istediğim buydu. Teşekkür ederim!
garrettmaring

let myTest = { test1, test3 } = myObject;çalışmıyor
Eatdoku


3

Bunun için yeniden yapılandırmayı kullanabilirsiniz:

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

Veya oof'un değerleri varsa her iki nesneyi birleştirin:

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

Sanırım bu ilk vaka tam olarak aradığım şeydi. Bunu krom konsolda denedim ve işe yarıyor gibi görünüyor. Şerefe! @campsafari
majorBummer

1
@majorBummer Sonunda aramanız, ancak yaklaşımı aslında sorunuza cevap vermemeyi düşünürüm, çünkü her ikisi de başlığınızın sorduğu gibi mevcut nesnelere özellikler eklemek yerine yeni nesneler oluşturur .
loganfsmyth

Bu iyi bir nokta @loganfsmyth. Sanırım campSafari'nin ortaya koyduğu yöntem beni heyecanlandırdı çünkü bunun mümkün olduğunu fark etmemiştim.
majorBummer

1
Yeni bir nesne yaratmanın sakıncası yoksa, yapabilirsinoof = {...oof, ...foo}
Joshua Coady

2

İmha edilen nesneyi bir ok işlevinde geri döndürebilir ve bir değişkene atamak için Object.assign () öğesini kullanabilirsiniz.

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

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

1

KURU

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 }

veya

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

1

Doğrudan başka bir nesne niteliğine atanan bir nesneyi yok edebilirsiniz.

Çalışma örneği:

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

Yakalamak istediğiniz nesne özniteliğiyle aynı ada sahip değişkenleri kullanarak yok etme ile çalışabilirsiniz, bu şekilde yapmanız gerekmez:

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

Bu şekilde kullanın:

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

Aynı nitelik adına sahiplerse, nesne yapılarına yeni değerler ayarlayabilirsiniz.

Şu çalışan örneğe bakın:

// 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

Bu, 53.0.2785.89 numaralı kromda çalışır

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

let oof = {x, y} = foo;

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

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

7
Ne yazık ki, oofsadece bir referans alıyor foove tüm yıkımı atlıyor gibi görünüyor (en azından Chrome'da). oof === foove let oof = { x } = fooyine geri dönüyor{ x, y }
Theo.T

@ Theo.T iyi yakala. bu bir serseri, başka bir yol bulmam gerekecek
user1577390

Bunlar, JS'nin nasıl kafa karıştırıcı olabileceğini göstermek için saklamaya değer.
jgmjgm

0

Bu yöntemi buldum:

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);
};

Bunun gibi kullanabileceğiniz:

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

yani, hangi özellikleri istediğinizi seçebilir ve bunları yeni bir nesneye koyabilirsiniz. Bunun aksine _.pick, aynı anda onları yeniden adlandırabilirsiniz.

Props'u mevcut bir nesneye kopyalamak istiyorsanız, sadece destarg.


0

Bu bir çeşit hile, ama bunun gibi bir şey yapabilirsiniz ...

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

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

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

Pratikte, bunu nadiren kullanmak isteyeceğinizi düşünüyorum. Aşağıdakiler ÇOK daha açık ... ama o kadar eğlenceli değil.

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

Prototiple uğraşmayı içeren tamamen farklı bir rota (şimdi dikkatli olun ...):

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

Bu bulabildiğim en okunaklı ve en kısa çözüm:

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

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

console.log(newProps);

Çıkacak { isValidDate: 'yes' }

Bir gün böyle bir şey söyleyebilmek güzel olurdu let newProps = ({ isValidDate } = props)ama maalesef ES6'nın desteklediği bir şey değil.


0

Bu ne güzel bir yol ne de tavsiye ederim ama bu şekilde mümkündür, sadece bilgi için.

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

Bunu başarmak için JSON sınıfı yöntemlerini aşağıdaki gibi kullanabilirsiniz

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

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

stringifyBir dizi biçiminde işlev görmek için ortaya çıkan nesneye ikinci bağımsız değişken olarak eklenmesi gereken özellikleri iletin.

JSON.stringify için MDN Dokümanı

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.