2013-12-16 2 views
1

Просто прочитайте this highly-related question, а затем отразите, что я использовал в своей собственной базе кода для проекта на работе.Практика кодирования Javascript: пустые значения в объектах

Я написал простую функцию, чтобы продемонстрировать этот вопрос (с помощью Google Apps Script, таким образом вызовов Logger.log()):

function emptyValueTest() { 

    var object = { 
    prop1: "real_data", 
    prop2: "", 
    prop3: undefined, 
    prop4: null 
    } 

    // What I have used in my code personally. All evaluate to TRUE 
    if (object.prop2 === "") Logger.log("prop2 was empty"); 
    if (typeof object.prop3 === "undefined") Logger.log("prop3 was undefined"); 
    if (object.prop4 === null) Logger.log("prop4 was null"); 

    // The other solution I've seen. All evaluate to FALSE 
    if (object.prop2) Logger.log("prop2 was empty"); 
    if (object.prop3) Logger.log("prop3 was undefined"); 
    if (object.prop4) Logger.log("prop4 was null"); 
} 

Я строил систему в течение последних нескольких месяцев с тысячами строк кода, и я часто обнаруживаю обратное отслеживание, когда вижу конкретное значение, чтобы помнить, что это было предыдущее состояние, до определенного условного выражения.

Поскольку я один пишет код, это не слишком трудно для меня, чтобы понять это, потому что я знаю структуру данных, значение, которые должны быть там, и т.д.

Однако после того, как я окончу свой университет, эта система будет перехвачена другим разработчиком, поэтому я задаюсь вопросом, какая наилучшая практика для , представляющая, что свойство не имеет данных.

Например, мой вариант использования: event Объекты, которые инициализируются пустыми данными и, в течение всего срока службы семестра, в конечном итоге заполняются реальными данными. Лично я использую undefined, потому что для меня имеет смысл читать if (typeof data === "undefined"), имея сходное семантическое значение «если эти данные не определены» (т. Е. Нет значения еще).

Но интересно, в промышленности, в библиотеках и в личных проектах, какие обычно используемые методы делают код более читабельным, понятным? Хотя длина первых трех условных чисел длиннее последних трех, я считаю, что последние три были неоднозначными.

Например, prop2 может иметь непустое строку как "data" или значение true, которое вызвало бы последний условный if (object.prop2) оценить, true в обоих случаях, потому что все в JavaScript является truthy за исключением следующего:

  • нуль
  • неопределенному
  • NaN
  • пустая строка ("")
  • ложные

И это вполне возможно, что данные могут иметь "", 0 и false, как действительные значения, в то время как null, undefined и (особенно) NaN, вероятно, не являются типичными значениями для реальных данных.

Очевидно, что я мы знаем, что структура данных, то мы могли бы ввести более строгие проверки на неоднозначность непустых строк из истинного.Но в проекте с тысячами строк кода мне кажется, что это быстро выходит из-под контроля, особенно если структура данных изменяется с течением времени.

Так что мой вопрос: Есть ли предпочтительный способ представляющего пустых значения в Javascript? И есть ли конкретная причина предпочтения (производительность, читаемость, масштабируемость и т. Д.)?

+1

Вероятно, это делом вкуса, но лично я бы использовать 'null', чтобы легко различать свойства, которые не были определены по сравнению с теми, которые еще не использовались или не были установлены. «NaN» может возникнуть из-за некоторых ошибок в математике, которые не сработают, и было бы гораздо труднее сказать, откуда она (потому что это будет считаться пустой). Кроме того, добавленный бонус заключается в том, что 'null' может возникнуть только в том случае, если вы либо назначили переменную для свойства, которое уже является null, либо напрямую присвоено значение null. Вы не можете получить нуль другим способом (кроме, вероятно, через 'eval ('null')', но это так маловероятно). –

+0

Согласен, это может быть вопрос мнения, например, я уже выразил свое собственное! Однако, я думаю, что здесь есть другие вещи. Например, некоторые операции возвращают нулевые значения, если они не удалось/данные не могут быть найдены: 'var split =" some ",. Split (", ")'; значение в 'split [1]' будет 'null', что в зависимости от системы может быть допустимым значением. Вот почему я склоняюсь к 'undefined', потому что семантически это имеет больше смысла, и вероятность случайного столкновения меньше, чем в примере, который я только что дал. Интересно, если это консенсус, хотя ... –

+0

@ChrisCirefice На самом деле 'split [1] === undefined'. В любом случае, я бы тоже использовал «нуль». 'undefined' используется для * свойств *, которые не определены. Но эти свойства действительно определены ... без ценности. Тогда вы должны использовать 'null', так как это его точное значение. – MaxArt

ответ

1

Javascript особенно коварен в постоянной NaN:

alert(NaN==NaN?"isNaN":"isNotNaN"); // isNotNaN ! 

Наиболее распространенный способ представления пустого объекта является null постоянная. Тем не менее, вы можете столкнуться с проблемами, используя его:

var coords = null; 
if(coords===null) alert("empty object"); 
if(coords.x==0 && coords.y==0) alert("[0,0]"); 
// Uncaught TypeError: Cannot read property 'x' of null 

Существует шаблон дизайна под названием Null object: создать объект, представляющий null значения с правильными свойствами:

var nullcoords = {x:-1,y:-1}; // null object 
var coords = nullcoords; 
if(coords===nullcoords) alert("empty coords"); 
if(coords.x==0 && coords.y==0) alert("[0,0]"); 
// no TypeError 

As RobG точек в комментариях, вы можете позволить себе такое отношение тогда и только тогда

  1. свойства nullobject по умолчанию не являются допустимыми значениями
  2. значения по умолчанию не испортит вам операции

Однако null не является хорошей идеей для COORDS свойств, поскольку он не является числовым типом и может испортить некоторые арифметические операции (не в JS, хотя). Ниже код является более подходящим (и более сложным) решением с пользовательским нулевым обработчиком объекта:

function nullCoordsHandler(obj) { 
    // any error handling you want 
    alert("setting default values..."); 
    obj.x = obj.y = 0; 
} 

function coords() { 
    var _x, _y; 
    var defined = false; 
    Object.defineProperty(this,"x",{ 
    enumerable: true, 
    get:function() { if(!defined) nullCoordsHandler(this); return _x; }, 
    set:function(value) { defined = true; _x = value; } 
    }); 
    Object.defineProperty(this,"y",{ 
    enumerable: true, 
    get:function() { if(!defined) nullCoordsHandler(this); return _y; }, 
    set:function(value) { defined = true; _y = value; } 
    }); 
}; 

var c = new coords(); 
if(c.x==0 && c.y==0) alert("[0,0]"); 
// nullCoordsHandler was called to handle the null object situation 
+0

Интересно ... Я не знал об этом виде шаблона дизайна, и в моем случае это именно та методология, в которой я нуждаюсь. Похоже, мне придется кое-что переделать, но похоже, что это прояснит многие смешные проверки типов, которые я выполнял. Хотя я должен добавить - * объект * не должен был быть «null», а только * некоторыми свойствами * объекта. Хотя я думаю, что я все еще могу включить этот шаблон в свой существующий код. –

+1

Если 'coords === null', почему бы вам тогда попытаться прочитать' coords.x'? Более полезным «нулевым объектом» будет '{x: null, y: null}', так как '-1', скорее всего, является допустимым значением. И проверка 'coords.x === null' немного отличается от' coords.x === undefined' или 'typeof coords.x == 'undefined''. – RobG

+0

@RobG: во избежание проверки 'if (coords === null)' перед любой операцией. Для установки 'null' вместо' -1', вероятно, ОК в JS, но я бы не рекомендовал это отношение в целом, поэтому вместо этого добавил часть обработчика. –

Смежные вопросы