javascript - Mengubah suai atribut contoh juga mempengaruhi output kandungan ke konsol sebelum pengubahsuaian?
过去多啦不再A梦
过去多啦不再A梦 2017-05-19 10:35:27
0
3
525

Ia bukan masalah dengan dinamik prototaip, ia adalah masalah dengan konsol
Tampal kod saya dahulu

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

Anotasi adalah hasil daripada operasi biasa, tetapi jika ia dibuka dalam penyemak imbas (Firefox dan Chrome), konsol akan mengembalikan 3 tatasusunan yang sama:

dan

Selepas mengklik untuk menyegarkan halaman, hasil normal akan dikembalikan;
atau console.log改为alert, membuka halaman akan mengembalikan hasil normal
Oleh kerana IE perlu memuatkan skrip secara manual setiap kali, yang bersamaan dengan menyegarkan halaman, jadi hasilnya adalah; normal;
Jadi saya Adakah anda fikir cara konsol mengeluarkan keputusan adalah berbeza daripada apa yang saya fikirkan? Minta jawapan.

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

membalas semua(3)
洪涛

Saya juga pernah mengalami masalah sebegini, berikut adalah soalan yang saya bangkitkan:
/q/10...

Jika anda tidak mahu membacanya, secara amnya, console.log mempunyai masalah penilaian yang malas!

Mari kita mulakan dengan kesimpulan: console.log tidak boleh dipercayai kerana ia bukan API yang ditentukan oleh standard, jadi tiada standard untuk pelaksanaan penyemak imbas. Kadangkala terdapat kekeliruan antara console.log segerak dan console.log asynchronous, serta perbezaan antara console.log yang menilai serta-merta dan console.log yang menilai dengan malas. Apa yang anda hadapi adalah yang terakhir.

Rujukan tambahan: http://stackoverflow.com/ques...

Peter_Zhu

Nah, telah dinyatakan dalam soalan bahawa ia bukan masalah prototaip, tetapi masalah konsol. Selepas menaip banyak perkataan, saya rasa masih ada nilai, jadi saya segan untuk memadamnya...
Penjelasan berikut tidak konsisten dengan apa yang ingin diketahui oleh penyoal.
Jawapan saya ialah: Mengapakah perubahan sifat objek contoh mempengaruhi tika lain?
Quan harus memberi penjelasan kepada orang yang tidak memahami warisan prototaip dengan jelas.

Chrome saya (di bawah platform Mac, versi 57.0.2987) tidak mempunyai masalah yang anda nyatakan dan hasil output adalah konsisten dengan jangkaan:

  • Output pertama: ["merah", "hijau", "biru"]

  • Output kedua: ["merah", "hijau", "biru", "hitam"]

  • Output ketiga: ["merah", "hijau", "biru", "hitam"]

Sebelum menjawab soalan, sila lihat contoh untuk menerangkan masalah yang anda hadapi.

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

SEBAB

Baiklah, sekarang kembali kepada soalan anda: Mengapa menukar sifat kejadian anak1 mempengaruhi anak2?

  1. Selepas mencipta tika, atribut __proto__ tika itu akan menunjuk kepada atribut .prototaip kelas induk Ingat, ia adalah penunjuk (rujukan) dan bukannya salinan.

  2. Apabila mengakses atribut contoh, mula-mula cari pada contoh itu sendiri Jika tidak ditemui, gunakan atribut __proto__ untuk mencari atribut prototaip kelas induk: child1.colors menghala ke Father.prototype.colors, jadi untuk Operasi warna akan secara langsung mempengaruhi objek rujukan dalam kelas induk.

  3. child2.colors juga akan mencari Father.prototype.colors, dan hasilnya secara semula jadi akan terhasil selepas anak1 membaiki warna.

Bagaimana untuk mengelakkannya?

child1.colors Jika anda menetapkan semula nilai dan bukannya mengendalikannya secara langsung, tidak akan ada masalah. (Ingat, jangan kendalikan atribut jenis rujukan secara langsung dalam kelas induk!)

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

Jawab sendiri:
Seperti yang dinyatakan oleh jawapan yang diterima, ia adalah masalah penilaian malas console.log; console.log的惰性求值问题;
当输出的内容为引用类型中的ArrayObject时,很有可能会出现问题中的情况;

目前我看到的最佳解决方法是:
将输出的内容改为console.log(JSON.stringify(yourArray))
不会改变输出的类型和内容,却规避了console.logApabila kandungan output adalah Array atau Object, situasi dalam soalan mungkin berlaku;

Penyelesaian terbaik yang saya lihat setakat ini ialah:

Tukar kandungan output kepada console.log(JSON.stringify(yourArray))

Tidak Menukar jenis dan kandungan output mengelakkan masalah penilaian malas console.log #🎜🎜#; #🎜🎜#Akhirnya, terima kasih kepada semua yang menjawab! #🎜🎜#
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan