Apa artinya “var FOO = FOO || {} ”(Menetapkan variabel atau objek kosong ke variabel itu) dalam Javascript?

99

Melihat kode sumber online saya menemukan ini di bagian atas beberapa file sumber.

var FOO = FOO || {};
FOO.Bar = …;

Tapi saya tidak tahu apa || {}itu.

Saya tahu {}sama dengan new Object()dan saya pikir ||itu untuk sesuatu seperti "jika sudah ada, gunakan nilainya, gunakan objek baru.

Mengapa saya melihat ini di bagian atas file sumber?

Ricardo Sanchez
sumber
Catatan: Pertanyaan diedit untuk mencerminkan bahwa ini adalah pola kode yang biasa terlihat di bagian atas file sumber Javascript.
Robert Harvey

Jawaban:

153

Tebakan Anda tentang maksud dari || {}cukup dekat.

Pola khusus ini bila dilihat di bagian atas file digunakan untuk membuat namespace , yaitu sebuah objek bernama di mana fungsi dan variabel dapat dibuat tanpa terlalu mencemari objek global.

Alasan mengapa itu digunakan adalah jika Anda memiliki dua (atau lebih) file:

var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func1 = {
}

dan

var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func2 = {
}

keduanya berbagi namespace yang sama maka tidak masalah urutan kedua file dimuat, Anda masih mendapatkan func1dan func2mendefinisikan dengan benar dalam MY_NAMESPACEobjek dengan benar.

File pertama yang dimuat akan membuatMY_NAMESPACE objek awal , dan file yang dimuat selanjutnya akan menambah objek.

Berguna, ini juga memungkinkan pemuatan skrip asinkron yang berbagi namespace yang sama yang dapat meningkatkan waktu pemuatan halaman. Jika <script>tag memiliki deferatribut yang disetel, Anda tidak dapat mengetahui dalam urutan mana tag tersebut akan diinterpretasikan, sehingga seperti yang dijelaskan di atas, ini juga memperbaiki masalah tersebut.

Alnitak
sumber
2
Persis seperti itu, ada beberapa file js dengan deklarasi yang persis sama di awal, terima kasih banyak!
Ricardo Sanchez
41
+1 untuk membaca yang tersirat dan menjelaskan alasan melakukannya. Itu selalu baik ketika seseorang memberikan jawaban yang sebenarnya diinginkan pengguna daripada hanya yang dia minta. :)
Spudley
1
saya suka mengatakan itu adalah # ifndef / # define untuk javascript :)
Darren Kopp
1
||juga sangat berguna ketika Anda ingin memberikan argumen opsional dan menginisialisasinya ke default jika tidak disediakan:function foo(arg1, optarg1, optarg2) { optarg1 = optarg1 || 'default value 1'; optarg2 = optart2 || 'defalt value 2';}
crazy2be
1
@ crazy2be yang tidak bekerja jika default adalah truthy, tetapi nilai-nilai falsey juga hukum, karena ||operator yang tidak bisa mengatakan undefineddari falsey.
Alnitak
23
var AEROTWIST = AEROTWIST || {};

Pada dasarnya baris ini mengatakan setel AEROTWISTvariabel ke nilai AEROTWISTvariabel, atau setel ke objek kosong.

Pipa ganda ||adalah pernyataan OR, dan bagian kedua dari OR hanya dijalankan jika bagian pertama mengembalikan false.

Oleh karena itu, jika AEROTWISTsudah memiliki nilai, akan disimpan sebagai nilai tersebut, tetapi jika belum ditetapkan sebelumnya, maka akan ditetapkan sebagai objek kosong.

pada dasarnya sama dengan mengatakan ini:

if(!AEROTWIST) {var AEROTWIST={};}

Semoga membantu.

Spudley
sumber
1
sebenarnya cakupannya akan baik-baik saja dalam contoh terakhir Anda karena JS tidak memiliki cakupan blok
Alnitak
@Alnitak - meh, kamu benar; Akhir-akhir ini saya terlalu banyak bekerja dengan closure dan saya lupa dasar-dasarnya. Saya akan mengedit jawabannya.
Spudley
6

Penggunaan umum lainnya untuk || adalah menyetel nilai default untuk parameter fungsi yang tidak ditentukan juga:

function display(a) {
  a = a || 'default'; // here we set the default value of a to be 'default'
  console.log(a);
}

// we call display without providing a parameter
display(); // this will log 'default'
display('test'); // this will log 'test' to the console

Padanan dalam pemrograman lain biasanya adalah:

function display(a = 'default') {
  // ...
}
alessioalex.dll
sumber
Anda tidak perlu vardi depan a, amemasukkan konteks eksekusi fungsi sebagai parameter formal , maka itu sudah dideklarasikan.
Fabrício Matté
6

Ada dua bagian utama yang var FOO = FOO || {};menutupi.

# 1 Mencegah penggantian

Bayangkan Anda memiliki kode yang dibagi menjadi beberapa file dan rekan kerja Anda juga mengerjakan sebuah Object bernama FOO. Maka itu bisa mengarah pada kasus bahwa seseorang sudah mendefinisikan FOOdan menetapkan fungsionalitas padanya (seperti skateboardfungsi). Kemudian Anda akan menimpanya, jika Anda tidak memeriksa apakah sudah ada.

Kasus bermasalah:

// Definition of co-worker "Bart" in "bart.js"
var FOO = {};

FOO.skateboard = function() {
  alert('I like skateboarding!');
};

// Definition of co-worker "Homer" in "homer.js"
var FOO = {};

FOO.donut = function() {
  alert('I like donuts!');
};

Dalam hal ini skateboardfungsi akan hilang jika Anda memuat file JavaScript homer.jssetelah bart.jsdi HTML Anda karena Homer mendefinisikan FOOobjek baru (dan dengan demikian menimpa yang sudah ada dari Bart) sehingga hanya mengetahui tentang donutfungsi tersebut.

Jadi, Anda perlu menggunakan var FOO = FOO || {};yang artinya "FOO akan ditempatkan ke FOO (jika sudah ada) atau objek kosong baru (jika FOO belum ada).

Larutan:

var FOO = FOO || {};

// Definition of co-worker Bart in bart.js
FOO.skateboard = function() {
  alert('I like skateboarding!');
};

// Definition of co-worker Homer in homer.js
var FOO = FOO || {};

FOO.donut = function() {
  alert('I like donuts!');
};

Karena Bart dan Homer sekarang memeriksa keberadaan FOOsebelum mereka mendefinisikan metodenya, Anda dapat memuat bart.jsdan homer.jsdalam urutan apa pun tanpa menimpa metode satu sama lain (jika mereka memiliki nama yang berbeda). Jadi Anda akan selalu mendapatkan FOOobjek yang memiliki metode skateboarddan donut(Yay!).

# 2 Mendefinisikan objek baru

Jika Anda sudah membaca contoh pertama maka Anda sudah sekarang apa tujuan dari || {}.

Karena jika tidak ada FOOobjek maka OR-case akan menjadi aktif dan membuat objek baru, sehingga Anda dapat menetapkan fungsinya. Suka:

var FOO = {};

FOO.skateboard = function() {
  alert('I like skateboarding!');
};
Benny Neugebauer
sumber
3

Jika tidak ada nilai di AEROTWIST atau null atau tidak ditentukan, nilai yang ditetapkan ke AEROTWIST baru akan menjadi {} (objek kosong)

sudipto
sumber
1

The ||Operator mengambil dua nilai:

a || b

Jika adalah truthy , itu akan kembali a. Jika tidak, itu akan kembali b.

Nilai-nilai falsy adalah null, undefined, 0, "", NaNdan false. Nilai kebenaran adalah segalanya.

Jadi jika abelum diset (apakah undefined) akan kembali b.

pimvdb.dll
sumber
Saya tidak yakin truthy dan falsey harus diabadikan sebagai kata-kata yang sebenarnya. Lucu, tapi tidak terlalu standar. :-)
Orbling
4
@Orbling biasanya digunakan untuk membicarakan nilai-nilai seperti itu di JS.
Alnitak
1 untuk menjelaskan operator dengan benar, karena ini bukan operator logika. Terkadang ini disebut "operator default".
Tim Büthe
@Tim Satu-satunya perbedaan antara ||JS (dan Perl) dan versi di C, C ++ dan Java adalah bahwa JS tidak mentransmisikan hasilnya ke boolean. Ini masih operator logis.
Alnitak
@Alnitak: Mungkin karena latar belakang non-profesional pengembang JS di masa lalu.
Orbling
-1

Perhatikan bahwa di beberapa versi IE kode ini tidak berfungsi seperti yang diharapkan. Karena var, variabel didefinisikan ulang dan ditetapkan jadi - jika saya ingat dengan benar masalahnya - Anda akan selalu memiliki objek baru. Itu seharusnya memperbaiki masalah:

var AEROTWIST;
AEROTWIST = AEROTWIST || {};
ZER0
sumber