【问题标题】:Same object in one case, different object in another?在一种情况下是相同的对象,在另一种情况下是不同的对象?
【发布时间】:2017-02-01 16:07:16
【问题描述】:

我试图弄清楚下面的代码中发生了什么,该代码处理将一个对象复制到另一个对象上。在某些情况下,它们就像同一个对象,改变一个对象会改变另一个对象。我发现了许多关于如何通过引用复制 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);
}

【问题讨论】:

  • 在 JavaScript 中,赋值(或方法参数)不会创建所述对象的副本/克隆/副本。此规则也适用于其他对象中的属性。
  • 如果您执行a = {}; b = a; 并操作b,您将更改 same 对象。如果你现在 a = {}; b = a; b = {} b 指向一个 不同的 对象,那么操作一个不会改变另一个。这几乎就是一切,真的。

标签: javascript vue.js vue-component


【解决方案1】:

基本上,您是在问这三个之间的区别:

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

【讨论】:

    【解决方案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;
    声明变量有不同的方法,但这不是问题的范围。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-22
      • 2021-10-04
      • 1970-01-01
      • 2017-08-09
      • 2020-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多