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.
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...
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.
Reason
Okay, now back to your question: Why does changing the attributes of the child1 instance affect child2?
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!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.
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!)
Answer by yourself:
As the accepted answer says, it is a lazy evaluation problem of
console.log
;console.log
的惰性求值问题;当输出的内容为引用类型中的
Array
或Object
When the output content isArray
orin 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.log
It will not change the output type and content, but avoid Fixed the lazy evaluation problem ofconsole.log
;Finally thank you to all the responders!