Mengapa tidak didefinisikan tidak dapat ditulis dalam JavaScript?

59

Menurut dokumentasi MDN tentangundefined :

Di browser modern (JavaScript 1.8.5 / Firefox 4+), undefined adalah properti yang tidak dapat dikonfigurasi, tidak dapat ditulis sesuai dengan spesifikasi ECMAScript 5. Bahkan ketika ini bukan masalahnya, hindari menimpanya.

Salah satu atribut properti yang tidak terdefinisi adalah yang tidak dapat ditulis.

Tetapi jika saya lakukan:

var undefined = 'hello';
var test = undefined;
console.log(typeof test);
//string

Apakah itu berarti saya dapat menimpa nilai undefined? Apa yang terjadi jika seseorang melakukan itu? Haruskah JavaScript memperingatkan tentang itu?

pmiranda
sumber
5
dapatkah Anda memberi tahu kami browser mana yang Anda gunakan? (Firefox 72.0b10 (64 bit) di Linux berfungsi sebagaimana mestinya typeof test === "undefined")
jonatjano
3
@DmitryReutov typeof undefinedkembali "undefined"dalam keadaan normal.
Amy
3
@ DmitryReutov Tentu saja "undefined"adalah sebuah string. Pertanyaannya bukan menanyakan apa yang typeof (typeof undefined)dievaluasi. Ia bertanya apa yang typeof undefineddievaluasi. Ia kembali "undefined", bukan"string"
Amy
2
@DmitryReutov typeof ______adalah ekspresi yang mengevaluasi string yang berisi tipe ______. Anda salah mengerti pertanyaan itu.
Amy
3
@Amy saya tahu, tetapi Edge mengembalikan "string" dan Chrome "undefined"
Alon Eitan

Jawaban:

50

Komentar yang dihapus oleh Amy memberikan solusi. Anda membuat variabel bernama undefined, dan itu tidak berfungsi jika Anda membuat cuplikan Anda di lingkup global:

var undefined = 'hello';
var test = undefined;
console.log(typeof test);

Tapi itu efektif jika Anda melakukannya dalam lingkup lokal di mana undefined tidak lagi merujuk ke variabel global:

(()=>{
  var undefined = 'hello';
  var test = undefined;
  console.log(typeof test);
})()

Untuk mencegah kesalahan ini, Anda dapat menggunakan 'use strict';arahan:

'use strict';
var undefined = 'hello';
var test = undefined;
console.log(typeof test);

Jika Anda menulis kode di mana Anda tidak dapat mengontrol di mana itu akan dieksekusi (misalnya perpustakaan, embed, dll) itu adalah pola yang baik untuk menggunakan IIFE yang membuatnya sehingga Anda dapat menjamin bahwa undefined akan selalu benar / dapat digunakan. Berikut ini sebuah contoh:

(function(undefined){
  // undefined will equal `undefined` because we didn't pass in an argument to the IIFE
  
  console.log(undefined); // always `undefined`, even if undefined !== `undefined`outside of the IIFE scope
})(); // No argument supplied


Semua pengujian saya dibuat menggunakan Firefox 72.0b10 (64 bit) di Ubuntu, dan hasil untuk cuplikan pertama mungkin berbeda di browser yang lebih lama.

Jonatjano
sumber
3
@panda bukan milikku, merasa sangat menarik
jonatjano
2
Terima kasih lagi. Semua keraguan ini berasal dari ini: pengembang baru di sini menerjemahkan beberapa variabel nama Spanyol ke bahasa Inggris. Dalam kode kami, kami memiliki variabel yang disebut let indefinido= dataArray( (a) => (anotherArray.includes(someName)));kami sedang memeriksa apakah var itu 'tidak terdefinisi' (hasil findtanpa elemen ditemukan) atau tidak. Lalu dia menerjemahkan indefinidoke undefinedsaya melihat bahwa saya mengujinya di Chrome dan Edge, melihat beberapa perbedaan. Itu sebabnya saya datang ke sini untuk meminta pendapat yang lain, karena saya juga belajar.
pmiranda
@ pmiranda Jawaban ini tidak sepenuhnya menjawab bagian "mengapa". Tapi itu jawaban yang bagus.
Ismael Miguel
2
Jika Anda akhirnya membutuhkan nilai sebenarnya dari undefined, gunakanvoid 0
Pengguna yang bukan pengguna
2
@Jon karena untuk beberapa alasan Konsorsium Ecmascript memilih untuk tidak membuat kata kunci yang tidak ditentukan tetapi milik properti global
jonatjano
17

Meskipun dimungkinkan untuk menggunakannya sebagai pengidentifikasi (nama variabel) dalam lingkup apa pun selain lingkup global (karena undefined bukan kata yang dilindungi undang-undang), melakukan hal itu adalah ide yang sangat buruk yang akan membuat kode Anda sulit untuk dipelihara dan di-debug.

Sumber https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined

undefinedadalah tidak disediakan karena itu adalah mungkin untuk menetapkan nilai baru.

Ketika Anda tidak menggunakan strict modeAnda pada dasarnya membuat variabel yang disebut undefineddalam lingkup lokal dan memberikan stringnilai padanya.

undefinedadalah properti dari objek global . Nilai awal yang tidak terdefinisi adalah nilai primitifundefined.

use strict akan membantu mencegah kesalahan ini dalam lingkup global sementara itu masih bisa ditimpa dalam lingkup lokal.

Jika Anda ingin lebih aman, Anda harus menggunakannya void 0daripada undefined selalu kembali undefined.

'use stict'

const test = (() => {
  let undefined = "test"
  console.log(typeof undefined)
  console.log(typeof void 0)
})()

kooskoos
sumber
1
inilah daftar kata kunci untuk lebih jelasnya
jonatjano
1
Patut dicatat bahwa dalam IIFE seperti itu orang juga bisa mendapatkan referensi undefineddengan membacanya sebagai argumen. Karena IIFE tidak pernah mengeluarkan argumen apa pun di sini, mereka akan berada undefineddi dalamnya. Misalnya((undefined) => console.log(typeof undefined))()
SeinopSys