javascript - Modifying instance attributes also affects the content output to the console before modification?
过去多啦不再A梦
过去多啦不再A梦 2017-05-19 10:35:27
0
3
524

It’s not a problem with prototype dynamics, it’s a problem with the console
Paste my code first

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"]

The comment is the result of normal operation, but if it is opened in a browser (Firefox and Chrome), the console will return 3 identical arrays:

as well as

After clicking to refresh the page, normal results will be returned;
Or change console.log to alert, and the normal results will be returned when the page is opened;
Because IE You need to manually load the script every time, which is equivalent to refreshing the page, so the results are normal;
So I think, is the way the console outputs the results different from what I thought? Ask for answers.

过去多啦不再A梦
过去多啦不再A梦

reply all(3)
洪涛

I have also encountered such a problem, the following are the questions I raised:
/q/10...

If you don’t want to read it, generally speaking, console.log has a lazy evaluation problem!

Let me start with the conclusion: console.log is unreliable because it is not an API determined by the standard, so there is no standard for browser implementation. Sometimes there is confusion between synchronous console.log and asynchronous console.log, as well as the difference between console.log that evaluates immediately and console.log that evaluates lazily. What you encounter is the latter.

Additional reference: http://stackoverflow.com/ques...

Peter_Zhu

Okay, it’s already stated in the question that it’s not a prototype problem, it’s a console problem. After typing so many words, I feel that there is still some value, so I am reluctant to delete it...
The following explanation is inconsistent with what the questioner wants to know.
My answer is: Why do property changes of an instance object affect another instance?
Quan should give an explanation to people who don’t understand prototypal inheritance clearly.

My Chrome (under Mac platform, version 57.0.2987) does not have the problem you mentioned, and the output results are consistent with expectations:

  • First output: ["red", "green", "blue"]

  • Second output: ["red", "green", "blue", "black"]

  • The third output: ["red", "green", "blue", "black"]

Before answering the question, please look at an example to explain the problem you are encountering.

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"]

Reason

Okay, now back to your question: Why does changing the attributes of the child1 instance affect child2?

  1. After creating an instance, the __proto__ attribute of the instance will point to the .prototype attribute of the parent class. Remember, it is a pointer (reference) and not a copy!

  2. When accessing instance attributes, first search on the instance itself. If not found, go to the prototype attribute of the parent class through the __proto__ attribute to find: child1.colors points to Father.prototype.colors, so the operation on colors will directly affect Reference object in parent class.

  3. child2.colors will also look for Father.prototype.colors, and the result will naturally be the result after child1 repairs the colors.

How to avoid it?

If you reassign child1.colors instead of directly operating it, there will be no problem. (Remember, do not directly operate the reference type attributes in the parent class!)

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

Answer by yourself:
As the accepted answer says, it is a lazy evaluation problem of console.log; console.log的惰性求值问题;
当输出的内容为引用类型中的ArrayObjectWhen the output content is Array or in the reference type >Object, the situation in the question is likely to occur;

The best solution I have seen so far is:
Change the output content to console.log(JSON.stringify(yourArray)); console.log(JSON.stringify(yourArray))
不会改变输出的类型和内容,却规避了console.logIt will not change the output type and content, but avoid Fixed the lazy evaluation problem of console.log;

Finally thank you to all the responders!

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template