suchen

Heim  >  Fragen und Antworten  >  Hauptteil

javascript - Hat das Ändern von Instanzattributen auch Auswirkungen auf die Inhaltsausgabe an die Konsole vor der Änderung?

Es ist kein Problem mit der Dynamik des Prototyps, es ist ein Problem mit der Konsole
Fügen Sie zuerst meinen Code ein

function Father(){
    this.colors = ["red", "green", "blue"],
    this.sayColor = function(){
    console.log(this.colors);
    };
}
function Child(){}
Child.prototype = new Father();

var child1 = new Child();
child1.sayColor(); // ["red", "green", "blue"] 原始值

child1.colors.push("black"); // 属性修改
var child2 = new Child();
child2.sayColor(); // ["red", "green", "blue", "black"]
child1.sayColor(); // ["red", "green", "blue", "black"]

Die Anmerkung ist das Ergebnis des normalen Betriebs, aber wenn sie in einem Browser (Firefox und Chrome) geöffnet wird, gibt die Konsole drei identische Arrays zurück:

und

Nachdem Sie zum Aktualisieren der Seite geklickt haben, werden normale Ergebnisse zurückgegeben.
Oder console.log改为alert Beim Öffnen der Seite werden normale Ergebnisse zurückgegeben normal;
Glauben Sie, dass die Art und Weise, wie die Konsole die Ergebnisse ausgibt, anders ist als ich denke? Bitten Sie um Antworten.

过去多啦不再A梦过去多啦不再A梦2752 Tage vor528

Antworte allen(3)Ich werde antworten

  • PHP中文网

    PHP中文网2017-05-19 10:37:27

    我也遇到过这样的问题,以下是我提出的问题:
    /q/10...

    如果你不想看,总的来说console.log 是有惰性求值的问题!

    先说结论:console.log 是不靠谱的由于它并非标准里确定的 API,所以浏览器的实现是没有标准可言的。有时候会出现同步的 console.log 与异步的 console.log 的困惑,也有立刻求值的 console.log 和惰性求值的 console.log 的差异。你遇到的是后者。

    补充参考:http://stackoverflow.com/ques...

    Antwort
    0
  • 天蓬老师

    天蓬老师2017-05-19 10:37:27

    好吧,问题中已经说明不是原型问题,是控制台问题。 敲了这么多字,觉得还有点价值,没舍得删...
    以下解释与提问者所想知道的不一致。
    我回答的是: 为什么实例对象的属性变更会影响另外一个实例?
    权当给对原型继承理解不清的人一个解释。

    我的Chrome(Mac平台下,版本57.0.2987)并没有出现你说的问题,输出结果和期望一致:

    • 第一个输出: ["red", "green", "blue"]

    • 第二个输出: ["red", "green", "blue", "black"]

    • 第三个输出: ["red", "green", "blue", "black"]

    解答问题前,请看一个示例, 可以解释你遇到的问题。

    var father_colors = ["red", "green", "blue"];
    var child1_colors = father_colors
    
    console.log(child1_colors);  // ["red", "green", "blue"] 原始值
    
    child1_colors.push("black");
    var child2_colors = father_colors;
    
    console.log(child2_colors);  // ["red", "green", "blue", "black"]
    console.log(child2_colors);  // ["red", "green", "blue", "black"]
    

    原因

    好,现在回到你的问题: 为什么改了child1实例的属性,确影响到了child2?

    1. 创建实例后,实例的 __proto__ 属性会指向父类的 .prototype 属性, 记住是一个指向(引用)而不是复制!

    2. 访问实例属性时,先在实例自己身上找,如果没有找到,通过 __proto__属性去父类的 prototype属性中寻找: child1.colors 指向 Father.prototype.colors, 因此对colors的操作会直接影响父类中的引用对象。

    3. child2.colors 也会去找 Father.prototype.colors, 结果自然是child1修该colors之后的结果。

    怎样避免?

    child1.colors你重新赋值而不是直接操作,就不会有问题。 (记住,对父类中的引用类型属性都不要直接操作!)

    child1.colors = ["red", "green", "blue", "black"];
    // 或者用
    child1.colors = child1.colors.concat().push["black"];  //concat()方法复制了一份父类的colors数组。

    Antwort
    0
  • 滿天的星座

    滿天的星座2017-05-19 10:37:27

    自答一个:
    正如采纳答案所说,是console.log的惰性求值问题;
    当输出的内容为引用类型中的ArrayObject时,很有可能会出现问题中的情况;

    目前我看到的最佳解决方法是:
    将输出的内容改为console.log(JSON.stringify(yourArray))
    不会改变输出的类型和内容,却规避了console.log的惰性求值问题;

    最后感谢所有回答者!

    Antwort
    0
  • StornierenAntwort