Чи можу я встановити змінні для невизначеного або передати невизначений як аргумент?


304

Я трохи розгублений щодо JavaScript undefinedта nullзначень.

Що if (!testvar)насправді робить? Це тест для undefinedта nullчи просто undefined?

Після того, як змінна буде визначена, чи можу я її очистити назад undefined(тому видалення змінної)?

Чи можу я пройти undefinedяк параметр? Наприклад:

function test(var1, var2, var3) {

}

test("value1", undefined, "value2");

Відповіді:


513

Я трохи розгублений щодо невизначеного Javascript і null.

Не плутайте null. Це, як правило, має сенс і поводиться аналогічно поняттям інших мов сценаріїв із позадіапазонних об'єктів "null", "nil" або "None".

undefinedз іншого боку, це дивна химерність JavaScript. Це однотонний об'єкт, який представляє позаполосні значення, по суті другий подібний, але різний null. Виходить:

  1. Коли ви викликаєте функцію з меншою кількістю аргументів, ніж список аргументів у functionсписках висловлювань, встановлюються невикористані аргументи undefined. Ви можете перевірити на це, наприклад:

    function dosomething(arg1, arg2) {
        if (arg2===undefined)
        arg2= DEFAULT_VALUE_FOR_ARG2;
        ...
    }

    За допомогою цього методу ви не можете визначити різницю між dosomething(1)та dosomething(1, undefined); arg2буде однакове значення в обох. Якщо вам потрібно сказати різницю, ви можете подивитися arguments.length, але такі необов'язкові аргументи, як правило, не дуже читабельні.

  2. Якщо функції немає return value;, вона повертається undefined. Взагалі не потрібно використовувати такий результат повернення.

  3. Коли ви оголошуєте змінну, маючи var aоператор у блоці, але ще не призначили їй значення, воно є undefined. Знову ж таки, вам ніколи не потрібно покладатися на це.

  4. Моторошний typeofоператор повертається, 'undefined'коли його операнд є простою змінною, яка не існує, замість того, щоб видавати помилку, як це було б зазвичай, якщо ви намагалися посилатися на неї. (Ви також можете надати йому просту змінну, загорнену в круглі дужки, але не повний вираз із участю неіснуючої змінної.) Не надто корисно для цього.

  5. Це спірне. Коли ви отримуєте доступ до властивості об'єкта, який не існує, ви не одразу отримуєте помилку, як і на будь-якій іншій мові. Натомість ви отримуєте undefinedоб’єкт. (І тоді, коли ви спробуєте використовувати цей undefinedоб’єкт пізніше в сценарії, він піде не так, як це дивно, це набагато складніше відстежити, ніж якби JavaScript щойно видав помилку.)

    Це часто використовується для перевірки наявності властивостей:

    if (o.prop!==undefined) // or often as truthiness test, if (o.prop)
       ...do something...

    Однак, оскільки ви можете призначити, undefinedяк і будь-яке інше значення:

    o.prop= undefined;

    це насправді не визначає, чи є властивість надійно. Краще скористатися inоператором, якого не було в оригінальній версії JavaScript Netscape, але зараз він доступний скрізь:

    if ('prop' in o)
        ...

Підводячи підсумок, undefinedце специфічний для JavaScript безлад, який бентежить всіх. Крім необов'язкових аргументів функцій, де JS не має іншого більш елегантного механізму, undefinedслід уникати. Це ніколи не повинно бути частиною мови; nullпрацював би добре для (2) і (3), а (4) - це невдача, яка існує лише тому, що на початку JavaScript не мав винятків.

що if (!testvar)насправді робить? Чи перевіряється це на невизначений і недійсний чи просто невизначений?

Такий «truthiness» тест перевіряє проти false, undefined, null, 0, NaNі порожні рядки. Але в цьому випадку так, це дійсно undefinedце стосується. ІМО, слід про це більш чітко сказати і сказати if (testvar!==undefined).

як тільки змінна буде визначена, чи можу я очистити її до невизначеної (тому видалення змінної).

Ви, звичайно, можете призначити undefinedйого, але це не видалить змінну. Тільки delete object.propertyоператор дійсно видаляє речі.

deleteнасправді призначений для властивостей, а не змінних як таких. Браузери дозволять вам відійти від прямого delete variable, але це не дуже гарна ідея і не буде працювати в суворому режимі ECMAScript Fifth Edition. Якщо ви хочете звільнити посилання на щось, щоб воно могло бути зібрано сміття, було б звичніше сказати variable= null.

чи можу я пройти невизначений як параметр?

Так.


10
Яка фантастична відповідь. Я щойно провалив тест JavaScript: perfectionkills.com/javascript-quiz. Пізніше я перечитаю вашу відповідь і спробуйте тест ще раз!
Skilldrick

1
фіксований, та. (Я схильний не надто хвилюватися щодо перепризначення, оскільки є так багато речей, які сценарій міг би переробити, щоб зіпсувати все, що загальний випадок неможливо вирішити.)
bobince

2
@bobince undefined- це однотонний об'єкт? Що ви маєте на увазі? Це примітивна цінність, а не предмет.
Šime Vidas

2
@Hortitude: Це точка (4). Я взагалі не хотів typeof foo=='undefined'; це, як правило, використовується для (4a) глобального нюху, і в такому випадку я вважаю за краще явне і скажу 'foo' in window, або (4b) тестування щодо самої undefinedвеличини, і в такому випадку я вважаю за краще читати і говорити foo===undefined. Теоретично тестування typeofпроти 'undefined'може мати корисний випадок, який інші конструкції не могли забезпечити: нюхаючи існування локальних змінних. Однак насправді ви майже завжди знаєте, які змінні оголошуються локальними.
bobince

4
Один застереження з №2, як правило, функція без returnоператора не повертається undefined, але якщо функція є конструктором (викликається newоператором), він поверне новий об'єкт (значення thisвсередині конструктора), незважаючи на те, що не має returnзаяви. console.log((function (){}()));повертає undefined. console.log((new function (){}()));повертає об’єкт.
Марний код

18

Ви не можете (не слід?) Визначати що-небудь як невизначене, оскільки змінна вже не буде невизначеною - ви просто визначили це на щось.

Ви не можете (не повинні?) Переходити undefinedдо функції. Якщо ви хочете передати порожнє значення, використовуйте nullзамість цього.

Оператор if(!testvar)перевіряє булеві істинні / хибні значення, цей конкретний тестує, чи testvarоцінюється false. За визначенням, nullі undefinedйого не слід оцінювати ні як trueабо false, але JavaScript оцінює nullяк false, і видає помилку, якщо ви спробуєте оцінити невизначену змінну.

Щоб правильно протестувати на undefinedабо null, скористайтеся ними:

if(typeof(testvar) === "undefined") { ... }

if(testvar === null) { ... }

1
Перевірка потрійних рівних також для типу, тому примушування типу не проводиться. Дуглас Крокфорд не радить використовувати оператори з примусовим типом ( ==і !=).
Skilldrick

3
Ви можете визначити щось як невизначене. var a= undefined. Можна пройти fn(undefined). Якщо ви хочете знайти різницю між невизначеним властивістю pоб’єкта oі властивістю p, яке визначило та встановило undefined, вам потрібно скористатися 'p' in oоператором.
bobince

1
Чи є причина, чому не слід проходити тести на testvar === undefinedшвидше, ніж на складніші typeof(testvar) === "undefined"?
ddaa

4
Є ще одна вагома причина використання typeofтесту для невизначених змінних: на відміну від цього null, undefinedце просто властивість глобального об'єкта і може бути перероблена. Він приймає лише певний стиль кодування та пропущений знак рівності і undefinedмовчки змінюється:if (undefined = someVar) {...}
Tim Down

1
@IanGrainger: ECMAScript 5 (реалізований у сучасних версіях усіх браузерів) здебільшого виправляє це, роблячи undefinedнезмінне властивість глобального об’єкта, тому це безпечніше, ніж раніше. Однак все-таки можна визначити змінну змінну, яку називають undefinedу межах функції, тому проблема не повністю зникла.
Тім Даун

13

Основна відмінність полягає в тому , що undefinedі nullпредставляють різні концепції.

Якби тільки nullбуло доступно, ви не зможете визначити, чи nullбуло задано навмисно як значення чи значення ще не встановлено, якщо ви не використали громіздку помилку: наприклад

var a;

a == null; // This is true
a == undefined; // This is true;
a === undefined; // This is true;

Однак, якщо ви навмисно встановили це значення null, сувора рівність з undefinedпомилками, тим самим дозволяючи вам розмежувати значення nullта undefinedзначення:

var b = null;
b == null; // This is true
b == undefined; // This is true;
b === undefined; // This is false;

Ознайомтесь з посиланням тут, а не покладаючись на те, що люди зневажливо говорять мотлох на кшталт "Підсумовуючи, невизначений - це безладдя, пов’язане з JavaScript, який бентежить усіх". Тільки тому, що ви розгублені, це не означає, що це безлад.

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

Така поведінка також не відноситься до JavaScript і завершує узагальнене поняття , що логічний результат може бути true, falseневідомий ( null), немає значення ( undefined), або що - щось пішло не так ( error).

http://en.wikipedia.org/wiki/Undefined_value


І все одно nullб добре працювали. a == nullце trueтому, що примус типу Javascript.
sleepwalkerfx

11

Найкращий спосіб перевірити наявність нульових значень - це

if ( testVar !== null )
{
    // do action here
}

і для невизначених

if ( testVar !== undefined )
{
    // do action here
}

Ви можете призначити доступний за допомогою невизначеного.

testVar = undefined;
//typeof(testVar) will be equal to undefined.

1
Найкращий спосіб перевірити нульові значення - використовувати !==, не!=
MBO

6

ТАК, ви можете, тому що невизначений визначається як невизначений.

console.log(
   /*global.*/undefined === window['undefined'] &&
   /*global.*/undefined === (function(){})() &&
   window['undefined']  === (function(){})()
) //true

ваш випадок:

test("value1", undefined, "value2")

Ви також можете створити власну невизначену змінну:

Object.defineProperty(this, 'u', {value : undefined});
console.log(u); //undefined

5

Щоб відповісти на ваше перше запитання, оператор not ( !) примушує все, що йому задано, булевим значенням. Таким чином null, 0, false, NaNі ""(порожній рядок) буде все , здається помилковою.


А також порожній рядок і NaN (Не число)
MBO

undefinedне відображатиметься як false, він видасть помилку "не визначено".
Тату Ульманен

Тату Ульманен: неправда. if (undefined) {/* Do stuff*/}не дасть помилки, оскільки undefinedіснує як властивість глобального об'єкта. Що призведе до помилки - це щось на кшталтif (someUndeclaredVariable) {/* Do stuff*/}
Tim Down

2

JavaScript, як встановити змінну для невизначеної у командному рядку:

Встановіть змінну до невизначеної в jsтерміналі командного рядка javascript, який поставляється з Java на Ubuntu 12.10.

el@defiant ~ $ js

js> typeof boo
"undefined"

js> boo
typein:2: ReferenceError: boo is not defined

js> boo=5
5

js> typeof boo
"number"

js> delete(boo)
true

js> typeof boo
"undefined"

js> boo
typein:7: ReferenceError: boo is not defined

Якщо ви встановите змінну до невизначеної у javascript:

Помістіть це у myjs.html:

<html>
<body>
    <script type="text/JavaScript">
        document.write("aliens: " + aliens);
        document.write("typeof aliens: " + (typeof aliens));
        var aliens = "scramble the nimitz";
        document.write("found some aliens: " + (typeof aliens));
        document.write("not sayings its aliens but... " + aliens);
        aliens = undefined;
        document.write("aliens deleted");
        document.write("typeof aliens: " + (typeof aliens));
        document.write("you sure they are gone? " + aliens);
    </script>
</body>
</html>

Він друкує це:

aliens: undefined
typeof aliens: undefined
found some aliens: string
not sayings its aliens but... scramble the nimitz
aliens deleted
typeof aliens: undefined
you sure they are gone? undefined

УВАГА! Під час встановлення змінної у невизначеному розмірі ви встановлюєте іншу змінну. Якщо хтось підлий чоловік працює, undefined = 'rm -rf /';то коли ви встановите свою змінну на невизначену, ви отримаєте це значення.

Вам може бути цікаво, як я можу вивести невизначене значення прибульців на старті і чи все ще він працює. Це через підняття JavaScript: http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html



0

Формат "for" if (something)і if (!something)зазвичай використовується для перевірки, чи щось визначено чи не визначено. Наприклад:

if (document.getElementById)

Ідентифікатор перетворюється на булеве значення, тому undefinedйого інтерпретують як false. Звичайно, є й інші значення (наприклад, 0 і ''), які також інтерпретуються як false, але або ідентифікатор не повинен розумно мати таке значення, або ви задоволені тим, що ставитесь до такого значення таким же, як невизначене.

У Javascript є deleteоператор, який може бути використаний для видалення члена об'єкта. Залежно від сфери застосування змінної (тобто вона глобальна чи ні), ви можете її видалити, щоб зробити її невизначеною.

Немає undefinedключового слова, яке можна використовувати як невизначений літерал. Ви можете опустити параметри у виклику функції, щоб зробити їх невизначеними, але це може бути використано лише для надсилання меншої кількості параметрів функції, не можна опустити параметр посередині.


0

Просто для розваги, ось досить безпечний спосіб присвоїти змінної "без призначення". Для цього зіткнення вимагатиме, щоб хтось додав до прототипу для Object точно таке ж ім'я, як і випадково згенерована рядок. Я впевнений, що генератор випадкових рядків може бути вдосконалений, але я просто взяв один із цього питання: Створення випадкових рядків / символів у JavaScript

Це працює, створюючи новий об’єкт і намагаючись отримати доступ до властивості на ньому з випадковим чином згенерованим іменем, яке, як ми вважаємо, звичайно не буде, і, отже, матиме значення невизначеного.

function GenerateRandomString() {
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for (var i = 0; i < 50; i++)
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

var myVar = {}[GenerateRandomString()];
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.