Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Проверки перед присваиванием (https://javascript.ru/forum/misc/28343-proverki-pered-prisvaivaniem.html)

bes 16.05.2012 09:35

Проверки перед присваиванием
 
Одним из распространённых приёмов программирования является проверка на отсутствие в переменной некоторого значения перед присваиванием ей этого значения.

Иногда возникают ситуации, когда можно просто переприсвоить ей это значение, не проверяя есть ли оно там или нет (заведомо знаем, что есть).

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

Разница в производительность этих двух операций не велика, так зачем тогда делать то, чего можно не делать.

Хотелось бы узнать, что это: просто стиль программирования или за этим стоят какие-нибудь другие объективные причины??

nerv_ 16.05.2012 09:41

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

melky 16.05.2012 09:59

Цитата:

Сообщение от bes (Сообщение 174706)
Одним из распространённых приёмов программирования является проверка на отсутствие в переменной некоторого значения перед присваиванием ей этого значения.

а зачем это делать? ну есть в ней значение, и хай с ним.

Цитата:

Сообщение от bes (Сообщение 174706)
Хотелось бы узнать, что это: просто стиль программирования или за этим стоят какие-нибудь другие объективные причины??

примеров кода бы. если я тебя правильно понял, то этот приём - полная дурость.(IMHO)

Цитата:

Сообщение от nerv_ (Сообщение 174707)
пример кода. На мой взгляд javascript в этом отношении вообще супер, в нем можно использовать логические операторы для присваивания значений.

ты хотел сказать, в выражение засунуть присваивание)

DreamTheater 16.05.2012 10:24

function test (options) {
    options = options || {};

    return options.test;
}

melky 16.05.2012 10:27

Цитата:

Сообщение от DreamTheater (Сообщение 174713)
options = options || {};

я неправильно понял :) что плохого в "значениях по умолчанию" ?

bes 16.05.2012 10:45

Цитата:

Сообщение от nerv_
пример кода. На мой взгляд javascript в этом отношении вообще супер, в нем можно использовать логические операторы для присваивания значений.

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

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

<div style="cursor: pointer"
  onclick="
    var span = this.getElementsByTagName('span');
    var dl = span.length;
    var target = event.srcElement || event.target;

    for (var i = 0; i < dl; i++) {
      if (target == span[i])
        span[i].style.background = 'green';
      else 
        span[i].style.background = 'yellow';
    }
">

<span>1</span>
<span>2</span>
<span>3</span>
</div>

bes 16.05.2012 10:49

Цитата:

Сообщение от melky
если я тебя правильно понял, то этот приём - полная дурость.(IMHO)

Так или не так это я и хотел бы выяснить на этой теме.

melky 16.05.2012 10:52

Цитата:

Сообщение от bes (Сообщение 174722)
Так или не так это я и хотел бы выяснить на этой теме.

я все равно не понял, что ты пытаешься обьяснить :) разжуй.

оно?
do {

  var i;

  if(i){
    i += 1;
  } else {
    i = 0;
  }

} while(1);

bes 16.05.2012 11:22

Цитата:

Сообщение от melky
я все равно не понял, что ты пытаешься обьяснить разжуй.

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

Раед 16.05.2012 11:26

У меня тоже возникал такой вопрос. Что лучше?
Это
a = a||7

или это
a||(a=7)

melky 16.05.2012 11:38

Цитата:

Сообщение от bes (Сообщение 174727)
Я привёл пример выше.
Я хочу делать так как в этом примере, то есть переприсваивать значения переменным без проверки существуют они там уже или нет, и не ловить по этому поводу себя на мысли "а не пишу ли я говнокод", вот я и выясняю, говнокод это или нет.

говнокод - понятие субъективное. для меня оное - это изобретение велосипедов, когда существует нативный способ решить задачу. ( например проверять, соответствует ли регвыр строке с помощью String.match )

а так ... пиши как хочешь, и не задумывайся, никогда. потом, как всё будет функционировать, будешь сидеть и исправлять, повышать читаемость. обычно это так делается :)

DreamTheater 16.05.2012 11:40

Цитата:

Сообщение от melky (Сообщение 174715)
я неправильно понял :) что плохого в "значениях по умолчанию" ?

А если значение по-умолчанию undefined или null?

bes 16.05.2012 11:53

Цитата:

Сообщение от melky
а так ... пиши как хочешь

Всё-таки попытаемся выяснить для чего этот приём так часто используется в программировании.

melky 16.05.2012 12:26

Цитата:

Сообщение от DreamTheater (Сообщение 174734)
А если значение по-умолчанию undefined или null?

я в таких случаях не пишу так :) вообще,я уже давно так не делаю. непереданные переменные просто меняют работу кода, они не получают значения.

Цитата:

Сообщение от bes (Сообщение 174737)
Всё-таки попытаемся выяснить для чего этот приём так часто используется в программировании.

необязательные аргументы - которые можно опустить при вызове функции, и которые меняют её поведение (или не меняют). флаги сюда тоже относятся.

пример:

var dump = function(variable, useAlert){ 
  if(useAlert){ 
    alert(variable);
  } else {
    console.log(variable);
  }
};

ещё пример - функция ожидает объект в качестве аргумента. если вызвать её без ничего, то будет ошибка при попытке обращения к info, как к объекту.
var ajax = function(info){
  info = info || {};

  makeReq(  info.url  );
};

сюда же относится обычная строчка в обработчике клика
var handler = function(e){
  e = e || window.event;
  // ....
}


ещё пример - используется в GCC при сжатии - выполнится выражение справа, если выражение слева вернёт false
var foo = function(){ alert("Foo called!"); };

var bar = function(dontCallFoo){
  dontCallFoo || foo();
};

bar("я уже не falsy");

falsy значение :
var foo = function(){ alert("Foo called!"); };

var bar = function(dontCallFoo){
  dontCallFoo || foo();
};

bar(/* undefined */);

bes 16.05.2012 15:51

melky, в ваших примерах демонстрируется вынужденная необходимость проверок для обеспечения работоспособности и безошибочности кода (проверка на существование, выбор используемого объекта через ||), я же пытаюсь выяснить несколько другое.

Попытаюсь сформулировать на другом примере.
Например, есть функция, которая должна присваивать переменной n значение 2.
Обычно её реализуют так.

function f() {
  if (n != 2) n = 2;
}


То есть вставляют проверку и не присваивают переменной n значение 2, если оно там уже хранится, хотя можно было сделать так:

function f() {
  n = 2;
}

То есть присвоить переменной n значение 2 в любом случае (переприсвоить в случае, если там итак было уже значение 2).

А так как обычно используют первый способ, отсюда и вопрос: в чём смысл выполнения таких проверок (стиль, производительность или что-то другое).

nerv_ 16.05.2012 16:16

Цитата:

Сообщение от bes
А так как обычно используют первый способ, отсюда и вопрос: в чём смысл выполнения таких проверок (стиль, производительность или что-то другое).

по примеру - ни в чем. Думаю, данный вопрос следовало задавать в рамках контекста (определенного кода)

bes 16.05.2012 17:10

Цитата:

Сообщение от nerv_
по примеру - ни в чем

У меня складывается подобное мнение, но данные проверки в программировании почему-то всегда используют, например, в set-методах.

Например,
<div id="myDiv"></div>

<script>
function setColor(value) {
 if (myDiv.style.color != value) 
    myDiv.style.color = value;
}
</script>


Цитата:

Сообщение от nerv_
Думаю, данный вопрос следовало задавать в рамках контекста (определенного кода)

Какой тут может быть контекст, факт - используют (привёл пример - в set-методах), зачем используют - пока не понятно.

nerv_ 16.05.2012 17:52

Цитата:

Сообщение от bes
У меня складывается подобное мнение, но данные проверки в программировании почему-то всегда используют, например, в set-методах.

тут вопрос иначе стоит: дрюкать дум лишний раз или нет? Лучше нет)

bes 16.05.2012 18:38

Цитата:

Сообщение от nerv_
тут вопрос иначе стоит: дрюкать дум лишний раз или нет? Лучше нет)

Проверка-то его тоже дрюкнет, поэтому вопрос остаётся.

bes 17.05.2012 09:23

Может быть у кого-нибудь есть ещё какие-нибудь предположения по этой теме??

nerv_ 17.05.2012 09:48

Цитата:

Сообщение от bes
Проверка-то его тоже дрюкнет

да, но по разному (как мне кажется). Одно дело перерисовка документа, другое чтение св-ва. Хотя, вероятно, браузер не станет перерисовывать документ из-за присваивания такого же значения. Я бы понял какой-то пример:
if ( value !== 'чему то там' ) {
	elem.style[ 'property' ] = value;
}

bes 17.05.2012 10:14

Цитата:

Сообщение от nerv_
да, но по разному (как мне кажется). Одно дело перерисовка документа, другое чтение св-ва. Хотя, вероятно, браузер не станет перерисовывать документ из-за присваивания такого же значения.

Вот это уже интереснее.

Для обычных переменных идёт сравнение операций чтения и записи, здесь наверное можно и не проверять.

А для свойств, связанных с прорисовкой, в случае, если после каждого присваивания произойдёт перерисовка, идёт сравнение чтения и записи + перерисовки, здесь наверное имеет смысл осуществить проверку.

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

nerv_ 17.05.2012 10:22

Цитата:

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

Точно утверждать не стану, но браузер производит перерисовку документа с определенным интервалом, а не после каждого изменения. Погугли на эту тему. Было бы здорово, если имелась возможность ее включать/выключать из кода, а ля true/false.

melky 17.05.2012 10:41

Цитата:

Сообщение от nerv_
а не после каждого изменения

опера перерисовывает страницу после изменения ширины <body>
Цитата:

Сообщение от nerv_
Было бы здорово, если имелась возможность ее включать/выключать из кода, а ля true/false.

requestAnimationFrame исполняет код прямо перед перерисовкой. чем он вам не нравится ?)

bes, почитай определение шаблона Особый случай


Часовой пояс GMT +3, время: 13:25.