Definisi ulang variabel global Javascript?

Saya punya pertanyaan tentang cakupan variabel dalam Javascript. Saya memiliki serangkaian skrip pada halaman web yang dimuat pada waktu yang berbeda. Saya memerlukan objek global bernama MyVar misalnya agar dapat diakses oleh semuanya. Saya ingin menghindari mendefinisikan ulang tetapi saya kira itu harus didefinisikan pada suatu saat oleh skrip pertama. Pertanyaan saya adalah apakah menggunakan var MyVar = MyVar || {} solusinya?

Terima kasih

 /**
 * Script 1
 */


var MyVar = MyVar || {};
MyVar.config = {
    x : 2,
    y : 3
};


/**
* Script 2
*/

//is this correct?
var MyVar = MyVar || {};
//to which MyVar am I assigning the apple property?
MyVar.apple = 'red';

PEMBARUAN

Jawaban yang bagus sejauh ini kawan, terima kasih.

Namun satu bagian terakhir, apa yang dilakukan pernyataan var kedua ketika saya mengulangi var MyVar = MyVar || {}; untuk kedua kalinya? Apakah itu membuat var baru dalam lingkup global bernama MyVar yang diberi nilai MyVar yang ada?

Poster lain benar untuk berasumsi bahwa saya memiliki skrip ini yang dimuat secara serempak dalam tag <script> namun karena pembagian kerja, saya membuat skrip kemudian tidak mengontrol kapan dan bagaimana skrip tersebut dimuat sehingga memerlukan metode yang sangat mudah untuk membuat/memanfaatkan objek MyVar saya .

Terima kasih


person JackMahoney    schedule 10.01.2013    source sumber
comment
Lihat pertanyaan ini tentang praktik terbaik saat menangani variabel global   -  person sinelaw    schedule 11.01.2013
comment
Ya, kode Anda akan berfungsi. Ya, Anda harus menghindari global bila memungkinkan.   -  person wless1    schedule 11.01.2013
comment
Baca var MyVar = MyVar || {}; sebagai var MyVar = MyVar if it exists (and isn't equal to false or 0) , or a new object if it doesn't.   -  person ic3b3rg    schedule 11.01.2013


Jawaban (4)


Saya memiliki serangkaian skrip pada halaman web yang dimuat pada waktu yang berbeda

Apakah ada di antara mereka yang dimuat secara asinkron? Jika hanya serangkaian tag <script>, maka tag tersebut akan dimuat secara serempak dan berurutan.

ke MyVar mana saya menugaskan properti apple?

Jika Anda mendeklarasikan MyVar pada cakupan global setiap saat, hanya akan ada satu MyVar. Properti apple akan dibuat pada variabel yang ada, jika ada, atau pada objek kosong yang dibuat dengan var MyVar = MyVar || {}; jika tidak.

Intinya: setelah var MyVar = MyVar || {}; pertama, deklarasi berikut akan diabaikan, dan properti baru akan ditambahkan ke variabel yang ada. Berhati-hatilah untuk tidak menimpa properti yang sudah ada.

person bfavaretto    schedule 11.01.2013
comment
Ini adalah penjelasan yang bagus. Namun satu bagian terakhir, apa yang dilakukan pernyataan var kedua ketika saya mengulangi var MyVar = MyVar || {}; untuk kedua kalinya? Apakah itu membuat var baru dalam lingkup global bernama MyVar yang diberi nilai MyVar yang ada? - person JackMahoney; 11.01.2013
comment
Ini akan melakukan MyVar = MyVar (yang pada dasarnya tidak melakukan apa pun). - person bfavaretto; 11.01.2013
comment
@JackMahoney - Untuk memperjelas, hanya definisi var pertama untuk nama variabel tertentu yang benar-benar mendefinisikan variabel tersebut. Pernyataan var berikutnya untuk nama variabel yang sama pada dasarnya tidak menghasilkan apa-apa; khususnya, ia tidak membuat variabel baru dengan nama yang sama. - person David R Tribble; 10.11.2016

Kode Anda benar dan mungkin akan berfungsi seperti yang diharapkan, namun ingatlah cakupan di mana MyVar dibuat. Dengan asumsi file Anda seperti yang diposting, mereka akan membuat MyVar dalam cakupan window (dengan asumsi konteks browser). Jika salah satunya dibungkus dalam fungsi anonim, seperti praktik umum dengan Pola Modul, MyVar hanya akan dibuat dalam lingkup fungsi tersebut:

(function() {
    var MyVar = MyVar || {};
    // If MyVar doesn't already exist in the global context,
    // the current MyVar reference will only be scoped to this function.
})();

Pola yang lebih baik untuk digunakan adalah:

var MyVar = window.MyVar || (window.MyVar = {});

Hal ini akan memastikan hal tersebut selalu dibuat, dan direferensikan, dari lingkup global. Anda bahkan dapat meneruskan konteksnya untuk mempermudah pemfaktoran ulang di masa mendatang:

(function(context) {
    var MyVar = context.MyVar || (context.MyVar = {}));
})(window);
person roryf    schedule 10.01.2013
comment
Terima kasih. Jadi di var MyVar = window.MyVar apakah MyVar merupakan referensi ke window.MyVar atau merupakan pemberian nilai? - person JackMahoney; 11.01.2013
comment
Jika window.MyVar ada, variabel MyVar lokal Anda akan menjadi referensinya. Jika tidak ada, bagian kedua || (window.MyVar = {}) akan membuat objek baru, menugaskannya ke window.MyVar dan mengembalikan referensi yang akan ditetapkan ke variabel MyVar lokal. - person roryf; 11.01.2013

Ini mudah untuk diuji:

var MyVar = MyVar || {};
MyVar.config = {
    x : 2,
    y : 3
};

console.log(MyVar);

var MyVar = MyVar || {};
MyVar.apple = 'red';

console.log(MyVar);
person ic3b3rg    schedule 10.01.2013
comment
Bagaimana jika urutan referensi skrip diubah? Contoh Anda bukanlah pemrograman defensif yang baik. - person roryf; 11.01.2013
comment
Saya membacanya sebagai dua skrip tingkat jendela yang terpisah. Saya kira mereka dapat disusun ulang dalam html, tapi saya pikir itu melampaui pertanyaan Jack. - person ic3b3rg; 11.01.2013
comment
@ ic3b3rg Anda benar, itu adalah dua skrip terpisah dan saya tidak tahu bagaimana urutannya - person JackMahoney; 11.01.2013
comment
Dalam hal ini, saran @roryf lebih baik, meskipun saran saya untuk menguji dengan console.log mungkin berguna. - person ic3b3rg; 11.01.2013

Inilah cara saya melakukannya:

window.myVar||(window.myVar={});

Dengan cara ini Anda tidak mendeklarasikan ulang variabel jika sudah ada.

person Christophe    schedule 11.01.2013