Rumah  >  Artikel  >  hujung hadapan web  >  Soalan temu bual front-end web biasa yang sering dipandang rendah (JS)_javascript kemahiran

Soalan temu bual front-end web biasa yang sering dipandang rendah (JS)_javascript kemahiran

WBOY
WBOYasal
2016-05-16 15:15:351506semak imbas

Soalan temu bual ialah topik yang amat dibimbangkan oleh syarikat perekrut dan pemaju untuk menggunakannya untuk memahami tahap sebenar pembangun dan keupayaan untuk mengendalikan butiran, manakala pembangun berharap dapat menunjukkan tahap mereka ke tahap yang terbaik. takat (malah prestasi melebihi norma). Artikel ini menyediakan banyak soalan temuduga pembangunan bahagian hadapan, yang patut dibaca untuk kedua-dua perekrut dan pemohon!

Kata Pengantar

Saya baru sahaja meletakkan jawatan beberapa tahun yang lalu Saya ingin berkongsi dengan anda satu soalan temuduga yang pernah saya tanyakan Keupayaan JavaScript yang komprehensif. Sayangnya dalam hampir dua tahun setakat ini, hampir tidak ada yang dapat menjawabnya dengan sepenuhnya.

Topiknya adalah seperti berikut:

function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}
//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName(); 

Jawapannya ialah:

function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}
//答案:
Foo.getName();//2
getName();//4
Foo().getName();//1
getName();//1
new Foo.getName();//2
new Foo().getName();//3
new new Foo().getName();//3 

Soalan ini berdasarkan pengalaman pembangunan saya sebelum ini dan pelbagai masalah yang saya temui dalam JS. Soalan ini melibatkan banyak mata pengetahuan, termasuk promosi definisi berubah-ubah, penunjuk penunjuk ini, keutamaan pengendali, prototaip, warisan, pencemaran berubah global, atribut objek dan keutamaan atribut prototaip, dsb.

Soalan ini mengandungi 7 soalan, sila jelaskan di bawah.

Soalan pertama

Mula-mula kita lihat apa yang kami lakukan pada separuh pertama soalan ini Kami mula-mula menentukan fungsi yang dipanggil Foo, kemudian mencipta sifat statik yang dipanggil getName untuk Foo untuk menyimpan fungsi tanpa nama, dan kemudian mencipta objek prototaip baharu untuk Foo. . Fungsi tanpa nama dipanggil getName. Kemudian fungsi getName dicipta melalui ungkapan pembolehubah fungsi, dan akhirnya fungsi getName diisytiharkan.

Soalan pertama, Foo.getName, secara semula jadi mengakses sifat statik yang disimpan pada fungsi Foo, yang secara semula jadi 2. Tiada apa-apa untuk dikatakan.

Soalan kedua

Soalan kedua ialah memanggil fungsi getName secara langsung. Memandangkan ia dipanggil terus, ia sedang mengakses fungsi yang dipanggil getName dalam skop semasa di atas, jadi ia tiada kaitan dengan 1 2 3. Ramai penemuduga menjawab soalan ini sebagai 5. Terdapat dua perangkap di sini, satu ialah promosi pengisytiharan berubah-ubah, dan satu lagi ialah ungkapan fungsi.

Promosi pengisytiharan berubah

Iaitu, semua pembolehubah yang diisytiharkan atau fungsi yang diisytiharkan akan dinaikkan pangkat ke bahagian atas fungsi semasa.

Contohnya, kod berikut:

console.log('x' in window);//true
var x; x = 0; 

Apabila kod dilaksanakan, enjin js akan menaikkan pernyataan pengisytiharan ke bahagian atas kod dan menjadi:

var x;
console.log('x' in window);//true
x = 0; 

Ekspresi fungsi

var getName dan fungsi getName ialah kedua-dua pernyataan pengisytiharan, var getName ialah ungkapan fungsi, manakala fungsi getName ialah pengisytiharan fungsi. Untuk mendapatkan maklumat lanjut tentang cara mencipta pelbagai fungsi dalam JS, anda boleh membaca soalan temu duga penutupan JS klasik yang kebanyakan orang buat salah Artikel ini mempunyai penjelasan terperinci.

Masalah terbesar dengan ungkapan fungsi ialah js akan memisahkan kod ini kepada dua baris kod dan melaksanakannya secara berasingan.

Sebagai contoh, kod berikut:

console.log(x);//输出:function x(){}
var x=1;
function x(){} 

Kod yang dilaksanakan sebenarnya adalah untuk membahagikan var x=1 terlebih dahulu kepada dua baris: var x; dan x = 1;, dan kemudian menaikkan dua baris var x dan fungsi x(){} ke atas untuk menjadi:

var x;
function x(){}
console.log(x);
x=1; 

Jadi x yang diisytiharkan oleh fungsi akhir meliputi x yang diisytiharkan oleh pembolehubah, dan output log ialah fungsi x.

Begitu juga, pelaksanaan terakhir kod dalam soalan asal ialah:

function Foo() {
getName = function () { alert (1); };
return this;
}
var getName;//只提升变量声明
function getName() { alert (5);}//提升函数声明,覆盖var的声明
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
getName = function () { alert (4);};//最终的赋值再次覆盖function getName声明
getName();//最终输出4 

Soalan ketiga

Dalam soalan ketiga, Foo().getName(); mula-mula melaksanakan fungsi Foo, dan kemudian memanggil fungsi atribut getName bagi objek nilai pulangan bagi fungsi Foo.

Ayat pertama fungsi Foo getName = function () { makluman (1 }); skop fungsi, dan tidak ada. Kemudian lihat ke lapisan atas skop fungsi semasa, iaitu, skop luar, untuk melihat sama ada ia mengandungi pembolehubah getName Ia ditemui, iaitu fungsi amaran(4) dalam soalan kedua pembolehubah kepada function(){alert(1) }.

Di sini, fungsi getName dalam skop luar sebenarnya diubah suai.

Nota: Jika ia masih tidak ditemui di sini, ia akan mencari sehingga ke objek tetingkap Jika tiada atribut getName dalam objek tetingkap, buat pembolehubah getName dalam objek tetingkap.

Selepas itu, nilai pulangan fungsi Foo adalah ini, dan sudah banyak artikel mengenai masalah JS ini di taman blog, jadi saya tidak akan menerangkan lebih lanjut di sini.

Ringkasnya, titik ini ditentukan oleh kaedah panggilan fungsi. Dalam kaedah panggilan langsung di sini, ini menunjuk ke objek tetingkap.

Fungsi Foo mengembalikan objek tetingkap, yang bersamaan dengan melaksanakan window.getName(), dan getName dalam tetingkap telah diubah suai kepada alert(1), jadi 1 akan dikeluarkan pada akhirnya

Dua perkara pengetahuan dikaji di sini, satu ialah isu skop pembolehubah dan satu lagi ialah isu penunjuk ini.

Soalan keempat

Panggil terus fungsi getName, yang bersamaan dengan window.getName(), kerana pembolehubah ini telah diubah suai apabila fungsi Foo dilaksanakan, jadi hasilnya adalah sama dengan soalan ketiga, iaitu

Soalan kelima

Soalan kelima ialah new Foo.getName( , apa yang dikaji di sini ialah isu keutamaan pengendali js.

Keutamaan pengendali js:

Dengan melihat jadual di atas, kita boleh mengetahui bahawa keutamaan titik (.) adalah lebih tinggi daripada operasi baharu, yang bersamaan dengan:

baharu (Foo.getName)();

Jadi fungsi getName sebenarnya dilaksanakan sebagai pembina, dan 2 muncul.

Soalan 6

Soalan keenam ialah Foo().getName(). Pertama sekali, kurungan keutamaan operator adalah lebih tinggi daripada pelaksanaan sebenar ialah

(Foo baharu()).getName()

Kemudian fungsi Foo dilaksanakan terlebih dahulu, dan Foo, sebagai pembina, mempunyai nilai pulangan, jadi di sini kita perlu menerangkan isu nilai pulangan pembina dalam js.

Nilai pulangan pembina

Dalam bahasa tradisional, pembina tidak sepatutnya mempunyai nilai pulangan Nilai pulangan bagi pelaksanaan sebenar ialah objek instantiated bagi pembina ini.

Dalam js, pembina boleh mempunyai nilai pulangan atau tidak.

1. Jika tiada nilai pulangan, objek yang di instantiated akan dikembalikan seperti dalam bahasa lain.

2. Jika terdapat nilai pulangan, semak sama ada nilai pulangan adalah jenis rujukan. Jika ia adalah jenis bukan rujukan, seperti jenis asas (rentetan, nombor, boolean, null, undefined), ia adalah sama seperti tiada nilai pulangan dan objek instantiatednya sebenarnya dikembalikan.

3 Jika nilai pulangan ialah jenis rujukan, nilai pulangan sebenar ialah jenis rujukan ini.

Dalam soalan asal, ini dikembalikan, dan ini pada asalnya mewakili objek instantiated semasa dalam pembina, jadi fungsi Foo akhirnya mengembalikan objek instantiated.

Kemudian panggil fungsi getName bagi objek yang di instantiated Kerana tiada atribut ditambahkan pada objek yang di instantiated dalam pembina Foo, kami mencari getName dalam objek prototaip objek semasa dan mencarinya.

Keluaran akhir ialah 3.

Soalan 7

Soalan ketujuh, new new Foo().getName(); juga merupakan isu keutamaan pengendali.

Pelaksanaan sebenar terakhir ialah:

baharu ((New Foo()).getName)();

Mula-mula mulakan objek Foo yang diinstantiasikan, dan kemudian gunakan fungsi getName pada prototaipnya sebagai pembina baharu semula.

Keputusan akhir ialah 3

Akhir sekali

Setakat jawapan, soalan pertama boleh dijawab dengan betul 100% masa, soalan kedua hanya kira-kira 50% betul, soalan ketiga boleh dijawab tidak banyak, dan soalan keempat sangat, sangat jarang. Sebenarnya, tidak banyak kegunaan yang rumit dan pelik untuk soalan ini. Semuanya adalah senario yang mungkin anda hadapi.

Saya hanya boleh mengatakan bahawa sesetengah orang terlalu tidak sabar dan tidak sabar. Saya harap semua orang dapat memahami beberapa ciri js melalui artikel ini.

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn