我正在试图找出下面代码中发生的事情,该代码涉及将一个对象复制到另一个对象上。在某些情况下,它们的行为与改变另一个改变另一个的同一个对象相同。我发现了许多关于如何通过引用复制javascript对象的帖子,因此它们实际上是同一个对象。例如,来自http://www.w3schools.com/js/js_object_definition.asp:
var person = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"}
var x = person; // This will not create a copy of person.
x.age = 10; // This will change both x.age and person.age
The object x is not a copy of person. It is person. Both x and person
is the same object. Any changes to x will also change person, because
x and person are the same object.
但是,我还发现了一个对象看起来像是单独对象的情况。它如何在一种情况下像同一个对象一样,但在另一种情况下却不同?我很感激有关情况的任何启示:
示例:http://codepen.io/gratiafide/pen/yagQGr?editors=1010#0
HTML:
<div id="app">
<my-component>
</my-component>
</div>
JS:
var MyComponent = Vue.extend({
template: '<div v-on:click="test()" class="red">1. Click here to copy the name object to message and change the value of name to see if the value of message gets changed also. (It does not).</div> message: {{ message | json}} <br> name: {{ name | json}}<div v-on:click="test2()" class="red">2. Now click here to see if updating the name object also changes the message object. It does! Why here and not in #1?</div><div v-on:click="test3()" class="red">3. Click here to see yet another way of updating the name object also changes the message object. Why here and not in #1?</div>',
data: function () {
return {
message: {},
name: {}
}
},
ready: function(){
this.message = {};
},
methods: {
test: function(){
this.message = {'t1':"m1"};
this.name = this.message;
this.name = {'t2':"m2"};
},
test2: function(){
this.message = {'t1':"m1"};
this.name = this.message;
for (var key in this.name) {
this.name[key] = '';
}
},
test3: function(){
this.message = {'t1':"m1"};
this.name = this.message;
Vue.set(this.name, 't1', 'm2');
}
}
});
Vue.component('my-component', MyComponent);
new Vue({
el: '#app'
});
CSS:
@import url(https://fonts.googleapis.com/css?family=Open+Sans);
.red{
color:red;
}
body {
font-family: 'Open Sans', sans-serif;
background: rgba(0,0,0,.5);
margin: 0;
}
#app {
width: 500px;
margin: 0 auto;
padding: 10px 20px;
background: rgba(255,255,255,.9);
}
答案 0 :(得分:2)
基本上,你要问的是这三者之间的区别:
this.message = {'t1':"m1"};
this.name = this.message;
#1:
this.name = {'t2':"m2"};
#2
for (var key in this.name) {
this.name[key] = '';
}
#3
Vue.set(this.name, 't1', 'm2');
在第一种情况下,您不会更改this.message
,因为您要将全新对象分配给this.name
。这个新对象({'t2':"m2"}
)与this.message
完全无关。
也许您正在尝试/想做的事情是:
this.name.t2 = "m2";
与#2和#3相同,影响this.message
,因为this.name
仍然指的是同一个对象。
要将新属性从另一个对象分配到现有对象,您可以在支持此功能的浏览器中使用Object.assign
:
Object.assign(this.name, {'t2':"m2"});
答案 1 :(得分:1)
有两种类型的变量,值和参考。所有基元(即字符串,数字和布尔值)都按值存储,其他所有基元都通过引用存储,并且可以具有属性。
var a,b;
a={c:1};
b=a;
console.log (b===a); // true;
b={c:1}; // note that b is now being assigned a new reference.
console.log (b===a); // false;
a=b; // now a is being assigned the reference of b.
console.log (b===a); // true;
a.c=2; //note that it is the property of a (c) got changed, not a itself.
console.log (b===a); // true;
a.a = a; //now a has a property (a) that stores the reference of a.
console.log(a === a.a);
console.log(a.a === a.a.a);
console.log(a.a === a.a.a.a.a.a.a.a.a);
a.a.a.a.a.a.a.a.a.a.a.c = 10;
console.log(a.c)//10;
&#13;