JavaScriptでundefinedが書き込み不可になっているのはなぜですか?


59

MDNのドキュメントにundefinedよると:

最新のブラウザー(JavaScript 1.8.5 / Firefox 4以降)では、undefinedは、ECMAScript 5仕様に従って、構成および書き込みができないプロパティです。そうでない場合でも、上書きしないでください。

undefinedのプロパティ属性の1つは、書き込み不可です。

しかし、私がするなら:

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

それは私が値を上書きできることを意味しundefinedますか?誰かがそれをしたらどうなりますか?JavaScriptはそれについて警告する必要がありますか?


5
使用しているブラウザを教えてください。(Linux上のFirefox 72.0b10(64ビット)は、で意図したとおりに動作しますtypeof test === "undefined"
jonatjano

3
@DmitryReutov typeof undefined"undefined"通常の状況で戻ります。
エイミー

3
@DmitryReutovもちろん"undefined"文字列です。問題は、何がtypeof (typeof undefined)評価されるかを尋ねることではありません。何がtypeof undefined評価されるかを尋ねています。それは"undefined"ではなくを返します"string"
Amy

2
@DmitryReutov typeof ______は、のタイプを含む文字列に評価される式です______。あなたはその質問を誤解しています。
エイミー、

3
@エイミーは知っていますが、エッジは「文字列」とChromeを「未定義」で返します
アロンエイタン

回答:


50

エイミーによって削除されたコメントは解決策を与えます。という名前の変数を作成しundefinedていますが、グローバルスコープでスニペットを実行しても機能しません。

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

ただし、undefinedがグローバル変数を参照しないローカルスコープで実行すると、効果的に機能します。

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

この間違いを防ぐには、次の'use strict';ディレクティブを使用できます。

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

実行する場所を制御できないコード(ライブラリ、埋め込みなど)を記述している場合は、IIFEを使用することをお勧めします。これにより、undefinedが常に正しい/使用可能になることが保証されます。次に例を示します。

(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


私のテストはすべてUbuntuのFirefox 72.0b10(64ビット)を使用して行われたため、最初のスニペットの結果は古いブラウザーでは異なる場合があります。


3
@pmirandaは私のものではなく、非常に興味深いもの
でした

2
再度、感謝します。このすべての疑いの原因はこれにあります。新しい開発者がスペイン語の名前変数を英語に翻訳していました。私たちのコードでは、変数let indefinido= dataArray( (a) => (anotherArray.includes(someName)));が「未定義」(find要素が見つからない結果)かどうかをチェックするという変数がありました。それから彼indefinidoundefined私がそれをChromeとEdgeでテストするのを見たと翻訳し、いくつかの違いを見ました。だから、私も勉強しているので、他の人の意見を聞くためにここに来ました。
プミランダ

@pmirandaこの答えは、「なぜ」の部分に厳密に答えるものではありません。しかし、それは良い答えです。
Ismael Miguel

2
最終的にundefinedの実際の値が必要になる場合は、次を使用しますvoid 0
ユーザーではないユーザー

2
@Jonは、何らかの 理由でEcmascript Consortiumがundefinedを予約キーワードではなくグローバルオブジェクトのプロパティにすることを選択したため
jonatjano

17

これをグローバルスコープ以外のスコープで識別子(変数名)として使用することは可能ですが(undefinedは予約語ではないため)、これを行うと、コードの保守とデバッグが困難になります。

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

undefinedされて予約されていないので、それを新しい値を代入することが可能です。

使用していないときstrict modeは、基本的undefinedにローカルスコープで呼び出される変数を作成し、それにstring値を割り当てます。

undefinedは、グローバルオブジェクトのプロパティです。undefinedの初期値はプリミティブ値undefinedです。

use strict ローカルスコープで上書きされても、グローバルスコープでのこの間違いを防ぐのに役立ちます。

より安全にしたい場合void 0undefined 、常に返される代わりに使用する必要がありますundefined

'use stict'

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


1
詳細はこちらのキーワードリストをご覧ください
jonatjano

1
そのようなIIFE undefinedでは、それを引数として読み取ることによって参照を取得することもできます。IIFEはここでいかなる引数も渡されないため、それらはそのundefined中に含まれます。例えば((undefined) => console.log(typeof undefined))()
SeinopSys
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.