Javascript.RU

PHP-функция: empty

Пермалинк: http://javascript.ru/php/empty

Javascript:

function empty( mixed_var ) {	// Determine whether a variable is empty
	// 
	// +   original by: Philippe Baumann

	return ( mixed_var === "" || mixed_var === 0   || mixed_var === "0" || mixed_var === null  || mixed_var === false  ||  ( is_array(mixed_var) && mixed_var.length === 0 ) );
}

Примеры:

empty(null);
true


Автор: hacpaka (не зарегистрирован), дата: 22 августа, 2010 - 20:01
#permalink

Приведенная функция не аналогична PHP-шной функции empty. В PHP функция empty применима к переменным которые не определены, то есть перед проверкой на пустоту фактически производится скрытый вызов isset(). На самом деле все немного сложнее, но, если смотреть "невооруженным" глазом - все именно так. Полностью смоделировать такое поведение в javascript, к сожалению, невозможно, так как в PHP возможен вариант когда в качестве параметра функции empty передается НЕСУЩЕСТВУЮЩАЯ переменная, например:

empty($undefinedVariable)

В данном случае результат будет, естественно, true.
В javascript (булыжник в огород эксмо), передать в качестве параметра несуществующую переменную попросту невозможно - интерпретатор нам тут же надает по рукам - мол нефиг впихивать несуществующее. Однако представьте себе такой вариант:

function doTest (test){
alert(empty(test));
}

Так вот, если вызвать doTest() и не передавать в качестве параметра ничего, что собственно (второй булыжник в огород эксмо), нам никто делать не запрещает, то функция empty, вернет false, что, как мне кажется, не совсем гуд. В принципе это всего-лишь одна из возможных ситуаций, но иллюстрирует проблему она очень даже неплохо.
Отсюда вывод - надо бы добавить в условие проверки строку следующего вида:

mixedValue === undefined

При таком подходе результат приведенной функции действительно, за исключением мелких особенностей обоих языков, будет практически соответствовать PHP-шному аналогу.

С уважение
hacpaka

P.S. Автору сайта огромный поклон как профессионалу и истинному мастеру своего дела.


Автор: Гость (не зарегистрирован), дата: 29 сентября, 2010 - 15:21
#permalink

Именно так))) спс, помогло не таскать лишних функций
Добавлю, что при таком коде:
if(a.value != undefined)
задача у меня решается в 99 случаях из 100, так как возвращаемые значения обычно сгенерированная строка.


Автор: B@rmaley.e><e, дата: 30 сентября, 2010 - 08:40
#permalink

JS умеет работать с необъявленными переменными, но только внутри оператора typeof:

alert( typeof someUndefinedVariable )

Автор: hacpaka, дата: 21 ноября, 2010 - 16:20
#permalink

Однако речь идет не об использовании несуществующей переменной, а о заявленном параметре функции который не был передан в некоторой цепочке вызовов. С точки зрения javascript такая переменная вроде как и существует, но равна 'undefined'.
То есть в таком варианте:

empty(undefinedVar);

На нас будут ругаться. Долго и матом.
В то же время в таком варианте:

function test(value){
	alert(jcc.empty(value));
}
test();

что эквивалентно фактически:

alert(jcc.empty(value));

Все пройдет как по маслу. А вышеприведенная функция в исходном виде вернет неверный результат. И если использовать её без указанного мною изменения - такое обстоятельство вполне способно подпортить нервы непосвященным во все тонкости стандартизированного ЭКСМО эфира, обывателю)


Автор: B@rmaley.e><e, дата: 21 ноября, 2010 - 16:21
#permalink

Вы говорили, что в JS нельзя определить передачу несуществующей переменной, я показал как это сделать средствами языка. Что же касается передачи необъявленной переменной в функцию или использование ее в выражении, то тут JS делает все правильно: использование необъявленных переменных - дурной тон.

Да, и если Вам нужно отдельно обрабатывать случай, когда в функцию ничего не передали, проверяйте

arguments.length

P.S. ЭКСМО это издательство в РФ, а организация, стандартизирующая JS (ECMAScript) зовется ECMA.


Автор: hacpaka, дата: 21 ноября, 2010 - 16:33
#permalink

Уважаемый коллега - приведенные примеры демонстрируют существование проблемы. Речь идет не о дурном тоне, а о правильности результата функции. Использование arguments.length вообще имеет смысл когда явные параметры функции не заданы. То есть подразумевается их произвольное количество. Если аргументы заданы - как-то весьма глупо проверять arguments.length, если существует способ проверить существует ли переданное значение непосредственно.
Если функция empty используется в составе длинного выражения и в качестве параметра ей передается результат другой функции либо цепочки функций, то логично предположить что проверка на существование аргумента ложна осуществляться внутри самой функции а не полагаться в таких делах на сторонние проверки.
Вынесение проверок, способных повлиять на итоговый результат за пределы функции либо блока кода, который собственно и занимается получением этого результата - это и есть плохой стиль, как вы поспешили отметить)
P.S. Насчет издательства в россии в курсе - но так уж получилось - привык. Это как "чмо" и "мачо" из анекдота, если вы понимаете о чем я)))


Автор: B@rmaley.e><e, дата: 21 ноября, 2010 - 16:47
#permalink

По одному только списку аргументов функции Вы никогда не узнаете, сколько на самом деле было передано аргументов функции. Если они все undefined - еще неизвестно, действительно ли были переданы undefined'ы, или просто функция была вызвана без аргументов. arguments.length позволит точно ответить на этот вопрос.

function isUndefined(variable){
  if(arguments.length == 0) throw new Error('Кого проверять?');
  return typeof variable === 'undefined';
}

try{
  alert(isUndefined(3)); // false
  alert(isUndefined(undefined)); // true
  alert(isUndefined({}.someUndefinedProperty)); // true
  alert(isUndefined()); // error
} catch(e) {
  alert('Shit happen: \n' + e);
}

Почему проверка переменной должна проводиться где-то там, глубоко в других функциях - непонятно. Ведь уже на текущем этапе видно, что переменная не существует и делать с ней нечего.
И еще: в php isset и empty это ни разу не функции. Это конструкции языка. Поэтому такое употребление допустимо.


Автор: hacpaka, дата: 21 ноября, 2010 - 17:19
#permalink

К сожалению, вы разводите холивары по несущественному поводу. Макросы isset и empty в PHP действительно не являются функциями, но задача этого топика - смоделировать их поведения средствами javasctript. Подумайте сами - если существует аргумент функции который может принимать то или иное значение, то проверка допустимых значений должна проводится внутри функции, особенно если при различных значениях аргумента функция может давать неверный результат - что вообще бич слаботипизированных языков. Необходимость такой внутренней проверки, вызвана в первую очередь тем фактом, что вы не в состоянии гарантировать что именно сторонний разработчик передаст в вашу функцию. И полагаться на то что проверка будет произведена до вызова функции - это не просто плохой стиль, это, пардом, говнокод. Причем мне кажется, вы сами это прекрасно понимаете, а спорите просто из желания похоливарить)

Дальше, вы говорите:

По одному только списку аргументов функции Вы никогда не узнаете, сколько на самом деле было передано аргументов функции. Если они все undefined - еще неизвестно, действительно ли были переданы undefined'ы, или просто функция была вызвана без аргументов. arguments.length позволит точно ответить на этот вопрос.

Скажите пожалуйста, уважаемый колега, а зачем мне в данном конкретном случае, знать количество аргументов переданных функции? Как я уже говорил знать количество аргументов мне важно только если функция подразумевает передачу произвольного числа аргументов. Если же количество аргументов фиксировано, то узнать передан аргумент или нет лучше именно по его имени. Это означает в частности, что если количество переданных аргументов больше количества явно объявленных, то объявленные будут иметь какое-нибудь значение, и, соответственно, наоборот.
Скажите пожалуйста почему функция которая должна вести себя аналогично empty в PHP должна вызывать ошибку если ей банально не будет передан аргумент? Она должна вернуть true, потому что ничего - оно и есть ничего, правда физики со мной не согласятся)))

Далее

Если они все undefined - еще неизвестно, действительно ли были переданы undefined'ы, или просто функция была вызвана без аргументов.

А какая именно вам разница? В любом случае вернет true. Или вам так хочется выводить внутри функции алерт с текстом "Чего впихуешь невпихуемое, отрок позорный?!!". Не вижу смысла. Зачем вообще лишняя проверка?

Далее

Почему проверка переменной должна проводиться где-то там, глубоко в других функциях - непонятно. Ведь уже на текущем этапе видно, что переменная не существует и делать с ней нечего.

Я уже писал выше почему. Скажите пожалуйста, а если не видно? Или вы не можете представить себе такую ситуацию?


Автор: uol (не зарегистрирован), дата: 16 ноября, 2010 - 22:34
#permalink

Предлагаю 'mixed_var === "" ' поменять на 'trim(mixed_var) === "" ' для отлавливания и "пробельных" INPUT-ов, а также: return поменять на IF, чтобы функция всегда возвращала только истину или ложь. Окончательный вариант:

  1. function empty(param) {
  2. if (trim(param) === "" || param === "0" || param === 0 ||
  3. param === null || param === false || param === "undefined" ||
  4. (is_array(param) && param.length === 0)) return true;
  5. return false;
  6. }

По trim() см.:
http://javascript.ru/php/trim
http://javascript.ru/php/trim-0


Автор: hacpaka, дата: 22 декабря, 2010 - 04:58
#permalink

насчет trim - оно, пожалуй, таки неплохо будет, а вот if - там грамоздок и излишен. При таком варианте например всегда будет либо истина либо ложь:

function empty (mixedValue){
     return (mixedValue === undefined || 
          mixedValue === null || mixedValue === "" 
          || mixedValue === "0" || mixedValue === 0  
          || mixedValue === false || (this.isArray(mixedValue) 
          && mixedValue.length == 0));
}

Автор: B@rmaley.e><e, дата: 21 ноября, 2010 - 17:47
#permalink

Макросы isset и empty в PHP действительно не являются функциями, но задача этого топика - смоделировать их поведения средствами javasctript.

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

Подумайте сами - если существует аргумент функции который может принимать то или иное значение, то проверка допустимых значений должна проводится внутри функции

Каких значений? У необъявленной переменной нет и не может быть значения. Зачем делать что-то, когда ясно, что нас ждет ошибка (см. ответ на последний абзац)?

Скажите пожалуйста почему функция которая должна вести себя аналогично empty в PHP должна вызывать ошибку если ей банально не будет передан аргумент?

А кто говорит, что она должна вызывать ошибку? Своим примером я лишь хотел указать на возможность индивидуальной обработки случая, в котором переменная не передается.

А какая именно вам разница?

Никакой. Но это единственный способ отличить передачу undefined'а от вызова функции без аргументов. Может ли это понадобится - не знаю, но иметь такую возможность не помешает.

Скажите пожалуйста, а если не видно? Или вы не можете представить себе такую ситуацию?

Нет, не могу. Или Вы рассчитываете, что где-то там, внутри переменная определится? Опять же, это нарушение логики (Вспоминаем про процедуры, возвращающие значение по ссылке, переданной аргументом).


Автор: hacpaka, дата: 21 ноября, 2010 - 18:27
#permalink

Опять вы за свое. неугомонный вы мой, моляр))) (с)

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

Что значит "нельзя реализовать самостоятельно"? А что вам мешает написать, например, свою php-функцию _empty(), которая будет полностью повторять поведение макроса empty? Разница только в том лишь будет что empty "вкомпиливается", если так можно выразиться, непосредственно в исходный код - на то он и макрос, а ваша функция будет вести себя как обычная функция языка. Это конечно "изврат" - но это не означает что этого сделать нельзя))) В большинстве случаев, впрочем, к сожалению)))
Цель топика, еще раз оговорюсь, реализовать аналоги со стороны javascript - понятно дело что доступными средствами. Вы со мной согласны?

Ну и неполноценность многих решений из этого раздела очевидна.

Именно так. Поэтому я и предложил способ сделать приведенный код "более полноценным" что ли. А вы вот чем-то недовольны)

Каких значений? У необъявленной переменной нет и не может быть значения. Зачем делать что-то, когда ясно, что нас ждет ошибка

Такой подход хорош в компилируемых языках. В концепции javascript не объявленная переменная это так сказать "неименованное" ничто - анонимная пустота, если хотите) причем тут ошибка? Если в функцию каким-либо образом запихнули эту самую пустоту - надо бы не ругаться, а деловито сообщить - да, действительно пустота - то есть вернуть true, в нашем случае.

Никакой. Но это единственный способ отличить передачу undefined'а от вызова функции без аргументов. Может ли это понадобится - не знаю, но иметь такую возможность не помешает.

И как по вашему должна повлиять такая возможность "под рукой" на результат ДАННОЙ КОНКРЕТНОЙ функции? Очень интересно услышать)

Нет, не могу. Или Вы рассчитываете, что где-то там, внутри переменная определится? Опять же, это нарушение логики (Вспоминаем про процедуры, возвращающие значение по ссылке, переданной аргументом).

Кхм. А вы о чем?

var test = {a: 'test'};
alert(jcc.empty(test.a) + " " + jcc.empty(test.b));

У меня возвращает "false true". А в исходном варианте? Думаете тоже самое? Я что-то сомневаюсь.
По вашему проверка этой функцией существование, пардон, члена объекта - это тоже "плохой стиль". А для чего она тогда вообще нужна?


Автор: B@rmaley.e><e, дата: 21 ноября, 2010 - 19:27
#permalink

А что вам мешает написать, например, свою php-функцию _empty(), которая будет полностью повторять поведение макроса empty?

Мешает использование необъявленной переменной в этом случае. Покажите мне функцию, полностью повторяющую empty, в том числе и при

error_reporting(E_STRICT | E_NOTICE);
А вы вот чем-то недовольны

Мой первоначальный пост был лишь поправкой, в которой я говорил, что в JS все-таки можно работать с необъявленными переменными, не вызывая ошибок. И, опять же, в пределах конструкции языка.

В концепции javascript не объявленная переменная это так сказать "неименованное" ничто - анонимная пустота, если хотите)

Что-что? Где в стандарте о чем-либо таком написано? В концепции JS, как и многих других языков, необъявленная переменная вообще не существует.

А для чего она тогда вообще нужна?

Очевидно, что для проверки на пустоту. Считать ли необъявленные переменные / свойства объектов пустыми - вопрос (хотя если стоит цель скопировать поведение php, то можно не задумываться об этом)


Автор: hacpaka, дата: 24 ноября, 2010 - 00:53
#permalink

Вот есть такие люди, уважаемый коллега, которые готовы спорить почем зря, проявляя некомпетентность и, даже порой, неграмотность, с той лишь целью, что бы их пост оказался последним) Мир полон загадок как говорится...

Мешает использование необъявленной переменной в этом случае.

Как-то странно получается, уважаемый коллега, вам это мешает а мне нет. Невольно вспоминается поговорка про танцора - уж простите). Делается это просто и валидно - с использованием ссылки:

function _empty(&$var){
	return empty($var);
}

А что бы вы опять не изобретали доводы - вот вам даже код:

error_reporting(E_ALL | E_STRICT);
echo _empty($test) ? 'empty' : 'not empty';
function _empty(&$var){
	return (bool)($var === null || $var === false
			|| $var === 0 || $var === '0' ||  $var === ''
			|| (is_array($var) || count(is_array($var)) == 0)
			|| (is_object($var) && isEmptyObject($var))
	);
}

function isEmptyObject($var){
	if (is_object($var) && count(($objectVars = get_object_vars($var))) > 0){
		foreach($objectVars as $oVaue){
			if (!_empty($oVaue)){
				 return false;
			}
		}
	}
	return true;
}

Что-то типа того. Впрочем может я что-то и не учел - линь читать доку. Естественно использование указателя накладывает некоторые ограничения на использование функции, но в том-то и проблема что макрос empty обладает практически такими же ограничениями, разе что тексты ошибок несколько изменятся)
Далее

Что-что? Где в стандарте о чем-либо таком написано? В концепции JS, как и многих других языков, необъявленная переменная вообще не существует.

Этот так сказать аспект подразумевается не стандартом (любой стандарт о таких вещах попросту умалчивает), а реализацией интерпретатора. Покалупайте как-нибудь на досуге палочкой какую-нибудь реализацию эксмо - убедитесь сами.

Очевидно, что для проверки на пустоту. Считать ли необъявленные переменные / свойства объектов пустыми - вопрос (хотя если стоит цель скопировать поведение php, то можно не задумываться об этом)

Это вопрос с точки зрения философии, уважаемый коллега, а вот с точки зрения программирования они либо являются пустыми, либо нет. Я так понимаю вы предлагаете считать их, так сказать, полными? Чтож, оптимизм - дело похвально. Только малооплачиваемое, к сожалению.

Мой первоначальный пост был лишь поправкой, в которой я говорил, что в JS все-таки можно работать с необъявленными переменными, не вызывая ошибок. И, опять же, в пределах конструкции языка.

Поэтому предлагаю послать все подальше, и по старой славянской традиции, вмазать по пивку)))


Автор: B@rmaley.e><e, дата: 25 ноября, 2010 - 01:24
#permalink

Хорошо, думаю, пора прекратить этот бессмысленный спор.


Автор: hacpaka, дата: 25 ноября, 2010 - 03:55
#permalink

Преабсолютнейше с вами согласен, уважаемый коллега. Тем более пользы от него непосвященному лицу - мало. Надо бы еще уговорить "власть имущих" подправить таки функцию. Не к лицу такому солидному порталу выкладывать дырявый код)


Автор: hacpaka, дата: 25 ноября, 2010 - 03:59
#permalink

*** продублировалось ***
((( в мире нет ничего идеального


Автор: hacpaka, дата: 22 декабря, 2010 - 04:50
#permalink

Что интересно - приведенный код все также остается неизменным))) Несовершенство этого мира иногда просто поражает)


Автор: miXOnIN, дата: 9 февраля, 2011 - 19:06
#permalink

Блин,все примеры - на 0 - говорят что пусто,а НОЛЬ то блэть может изпользоватся как и ЧИСЛО,а оно напишет что числа НЕТ!...

мой вариант:

function empty (mixedValue){
  switch (typeof mixedValue) {
    case 'undefined':
      return true;
    case 'object':
      for(val in mixedValue)return false;
      return true;
    case 'string':
      return (mixedValue.length==0?true:false);
    case 'boolean':
      return false;
    case 'number':
      return isNaN(mixedValue);
    case 'function':
      return false;
    default:
      alert('O_o');
  }
}

Автор: hacpaka, дата: 4 марта, 2011 - 03:47
#permalink

А вы вообще заголовок топика читали? Здесь приводятся аналоги функций PHP и ведется обсуждение насколько, собственно, эти аналоги являются аналогами в действительности. В концепции PHP "0" это действительно, пардон, пусто. Причем пусто, несмотря на то чем этот ноль является в действительности - целочисленным нулевым значением, либо строкой, содержащей "0". Поэтому приведенный вами фрагмент никакого отношения к этому топику не имеет.
Я посоветовал бы вам в следующий раз внимательно читать что и где вы пишете, а заодно и воздержаться от написание подобных "перлов", особенно с использованием switch-блоков где не попадя.
С уважением
hacpaka


Автор: Гость (не зарегистрирован), дата: 5 января, 2012 - 00:00
#permalink

Уважаемые, но is_array - это вообще-то не javascript функция.
Далее. Если я передам в функцию массив вида:
var address = new Array();
address.street = "Строителей";
empty(address); // вернет true. Хотя массив не пустой.


Автор: hacpaka, дата: 20 июля, 2013 - 20:14
#permalink

Классическая ситуация в лучших традициях жанра. "Знаток" пришёл, написал бред и не подписавшись ушел. Наверное что бы потом не краснеть.
Вы, уважаемый комментатор, вообще разницу между массивом и объектом понимаете?

Если вы напишете так:

var address = new Array();
address.street = "Строителей";

То массив останется пустым. Но вот Объект инкапсулирующий функционал массива получит новое свойство "street". Можете проверить длину массива если не верите. Если вы хотите добавить что-то в массив - используйте такой синтаксис:

var address = new Array();
address[0] = "Строителей";

или такой:

var address = new Array();
address.push("Строителей");

Другими словами ваш пример ошибочен, а логика работы функции empty правильная.

Что касается "is_array" - обратите внимание в какой теме вы находитесь и какую статью комментируете. Безусловно is_array не функция javascript, но существует аналог, точно также как и empty.

Учите матчасть, товарищи)


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
3 + 0 =
Введите результат. Например, для 1+3, введите 4.
 
Поиск по сайту
Реклама
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum