Dies ist eine Frage dazu, wie JavaScript einen Verweis auf vorhandene hinzufügen kann, anstatt neue zu erstellen.Behält JavaScript einen Verweis auf vorhandene Variablen bei, wenn Objekte mithilfe der Objektliteralsyntax erstellt werden?
Hier sind einige Beispiele, die hoffentlich illustrativ-genug, im Rahmen eines Redux Minderer sind, weil es ein vertrauter Ort für spread operator
oder Object.assign()
ist:
Hier sehen wir kehren nur eine wörtliche Objekt mit einem String, also gibt es nichts, was in einer Referenz zu etwas ziehen könnte, das an anderer Stelle existiert.
export default (state = {}, action) => {
switch (action.type) {
case SOME_ACTION:
return {
props: 'something arbitray'
}
}
}
Dieses ist der Verdächtige Problem:
Wir ein Objektliteral zurückkehren, aber wir haben Bezug auf
args[type]
enthalten. Zuerst muss ich sicher wissen, ob dies ein Objekt zurückgibt, das einen Link zu was auch immerargs[type]
derzeit festgelegt ist? Wennargs[type]
später mutiert werden, würde dies in diesem zurückgegebenen Objekt widergespiegelt werden?
export default (state = {}, action) => {
switch (action.type) {
case SOME_ACTION:
return {
props: args[type]
}
}
}
Hier sind zwei Beispiele, die ich vermute, würde dieses Problem nicht:
Verstehe ich das richtig? Kopiert JavaScript nur die Eigenschaft und behält keinen Bezug auf
args[type]
?
export default (state = {}, action) => {
switch (action.type) {
case SOME_ACTION:
return Object.assign({}, state, { props: args[type] })
}
}
Hier ist ein weiteres Beispiel, das ich könnte syntaktisch identisch sein mit dem Object.assign()
Syntax vor kurzem gelernt:
export default (state = {}, action) => {
switch (action.type) {
case SOME_ACTION:
return { ...state, props: args[type] }
}
}
Die Fragen:
Ist der Spread Betreiber tun das gleiche wie
Object.assign()
in diesem Zusammenhang und erstellen ein völlig neues Objekt ohne Risiko der illegalen Veränderung durch die Beibehaltung eines Verweises aufargs[type]
? Ich muss mich auf den unveränderlichen Zustand des Objekts verlassen können, nachdem es erstellt wurde.Würde das zweite Beispiel, das ich zeigte, eine Live-Referenz zu
args[type]
beibehalten?
Ich habe einige Code, der normalerweise in etwas verbreitet, und ich habe einen Anwendungsfall, der diese Verbreitung auslässt, so dass ich bin gespannt, ob das ein Problem sein könnte. Wie kann ich garantieren, dass zufällige Änderungen von args[type]
dieses zurückgegebene Objekt nicht beeinträchtigen?
Wäre das die richtige Antwort?:
export default (state = {}, action) => {
switch (action.type) {
case SOME_ACTION:
return Object.assign({}, { props: args[type] })
}
}
[bearbeiten] Ich bin das Problem reproduzieren können, indem Sie diese:
const arr = ['one', 'two', 'three']
const args = {
type: arr
}
const something = {
props: args.type
}
arr.push('four') // Notice how this appears in something.props
console.log(something)
Und dies behebt es (so scheint es, etwas zu haben, mit Primitiven im Vergleich zur Pflege einer Objektreferenz):
const arr = ['one', 'two', 'three']
const args = {
type: arr[2]
}
const something = {
props: args.type
}
arr[2] = 'what' // Notice how this doesn't appear in something.props
console.log(something)
Aktualisiert Frage
Gibt es eine Möglichkeit, einen non-primitive
zu kopieren (dh: Objekt/Array), so dass sie diese Referenz bricht?
Ich bemerkte es nicht mit Object.assign()
Es ist, weil ein primitiv ist. probiere 'var a = [5]; var b = a; a.push (2); console.log (b); ' – agm1984
Ich möchte wissen, wie ich sicherstellen kann, dass dieses Verhalten nicht auftritt. – agm1984
In Ihrem Beispiel hat b immer noch keinen Bezug zu a. Sie zeigen beide auf dasselbe Objekt, aber nicht auf einander. dh. wenn Sie "a" etwas anderes zuweisen. und dann irgendeine Operation an "a". Das hat keinen Einfluss auf "b". –