2016-09-23 2 views
1

Я пытаюсь выяснить, что происходит в приведенном ниже коде, который касается копирования одного объекта на другой объект. В некоторых случаях они действуют как один и тот же объект, где изменение меняется другим. Я нашел множество сообщений о том, как объекты 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

В JavaScript * * присваивание * (или аргумент метода) делает * не * создание копии/клонирования/дубликата указанного объекта. Это правило также применяется для свойств * внутри * других объектов. – user2864740

+0

Возможный дубликат [Является ли JavaScript паролем или ссылкой по языку?] (Http://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass -by-value-language) – vlaz

+2

Если вы делаете 'a = {}; b = a; 'и манипулировать' b', вы меняете объект _same_. Если вы делаете 'a = {}; b = a; b = {} 'теперь' b' указывает на объект _different_, поэтому манипулирование одним не меняет другого. На самом деле это очень много. – vlaz

ответ

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

Есть 2 типа переменных, значения и ссылки. Все примитивы (т. Е. Строка, число и логическое значение) сохраняются значениями, а все остальное хранится по ссылкам и может иметь свойства.

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;
Существуют различные способы, чтобы объявить переменные, но это не сфера вопроса.

Смежные вопросы