2015-06-19 4 views
1

Я только пройдя через код метода inArray и наткнулся на следующем ::понимания комплекса inArray тройной оператор

inArray: function (elem, arr, i) { 
    var len; 

    if (arr) { 
     if (indexOf) { 
      return indexOf.call(arr, elem, i); 
     } 

     len = arr.length; 
     i = i ? i < 0 ? Math.max(0, len + i) : i : 0; 

     for (; i < len; i++) { 
      // Skip accessing in sparse arrays 
      if (i in arr && arr[i] === elem) { 
       return i; 
      } 
     } 
    } 

    return -1; 
}, 

теперь я понимаю, как tenary операторов работают, но может кто-нибудь сказать мне, как ниже линии код действительно работает? это даже троичный оператор?

i = i ? i < 0 ? Math.max(0, len + i) : i : 0; 

или это какая-то новая конструкция в JS?

Спасибо.

Alex-z.

+0

Самое смешное, оно может быть еще короче: 'i = i <0? Math.max (0, len + i): i || 0; ' –

ответ

4

Оригинальное заявление:

i = i ? i < 0 ? Math.max(0, len + i) : i : 0; 

Чтобы понять это лучше,

i = i ? (i < 0 ? Math.max(0, len + i) : i) : 0; 
// ^       ^

Да, это вложеннаяternary operator? :.

Ниже приведено представление if else вышеприведенного отчета, представленного в if..else шаг за шагом.

if (i) { 
    i = i < 0 ? Math.max(0, len + i) : i; 
} else { 
    i = 0; 
} 

Он работает следующим образом:

if (i) { 
    if (i < 0) { 
     i = Math.max(0, len + i); 
    } else { 
     i = i; 
    } 
} else { 
    i = 0; 
} 
+1

Чтобы быть педантичным, в выражениях if нет присвоения' i'. Указанные тройники свободны от побочных эффектов, тогда как они сочетают назначение левой с оценкой права. В этом примере это на 100% хорошо, но немного неискренне, когда вы учите троицу как концепцию. – Norguard

+0

@ Norguard Право! Спасибо за информацию – Tushar

1

Это 2 тройные операторы, вложенное. Вы можете прочитать это следующим образом:

i = i ? (i < 0 ? Math.max(0, len + i) : i) : 0; 

Или, полностью преобразуется в if/else:

if(i) 
    if (i < 0) 
     i = Math.max(0, len + i); 
    else 
     i = i; 
else 
    i = 0; 

Вы можете сократить if/else структурировать немного:

if(i) { 
    if (i < 0) 
     i = Math.max(0, len + i); 
} else 
    i = 0; 

Или:

if(i && i < 0) 
    i = Math.max(0, len + i); 
if(!i) 
    i = 0; 

Удаляет избыточное else i = i. В тройных высказываниях требуется else, но здесь его можно опустить.


Имейте в виду, что все i = задания вы видели в этих if/else заявления основаны на одной i = уступки перед тройном оператора. Тернарные операторы самостоятельно (a ? b : c) не присваивают значения переменным.

+0

'i = i?' В начале, это даже проверка? или это просто инициализация i со значением? Мне трудно понять, что 'i = i' оценивает' if (i) {} '! , но если так оно и есть, я думаю, что так работает js! –

+0

'i = i' из последнего': i', в тройном выражении. При использовании структуры 'if/else' это' else' не требуется. – Cerbrus

+0

else 'if (i) ... else i = 0;' (3-й серый ящик) присваивается 'if (i <0)', а не внешнему if. –

0

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

Это то, во что я верю, является намерением линии в упрощенной логике. Это то, что происходит в моем сознании, когда я кодирую такие строки.

function calculatewhat(i) { 
    if(i != 0) {/*i = i;*/ // i gets assigned and then evaluated. 
          //If its anything but zero it's true, if its zero its false. 
     if(i < 0) { // Test if its smaller than zero 
      return Math.max(0, len + i) ; 
     } 
     else { // its bigger than 0 
      return i 
     } 
    else { // if its 0... but you could just as wel return i 
      // instead of creating a new variable for the return since i is zero. 
     return 0; 
    } 
} 

Я бы закодирован его вместо вложенного следующего

i = i < 0 ? Math.max(0, len + i) : i 

И чтобы удовлетворить Cerbrus это, как это действительно работает.

function calculatewhat(i) { 
    if(i) { //check if its a true value. This will evaluate true also on "1", "blah",true, etc... 
      //To be typesafe you should make it an integer test. if(typeof i === 'number' && i !== 0); 
     if(i < 0) { // Test if its smaller than zero This will also return true on "-20" and -20.555 
      return Math.max(0, len + i) ; 
     } 
     else { // its bigger than 0 return i. but its type can be anything but an integer, so beware. 
      return i 
     } 
    else { //it's not a number or its 0. 
      //We can't be sure about type so lets return 0 to i making it a valid integer. 
     return 0; 
    } 
} 
+0

Нет, это не так, нет никакого выражения 'return' в тройном коде OP. – Cerbrus

+0

Тернарный оператор возвращает значение smartass. 'var x = true? «hello»: «world»; 'делает x true. его возвращение. он хотел знать, что он сделал. Это в основном то, что он делает. Он возвращает истинное значение правопреемнику. – Tschallacka

+0

Если бы OP слепо заменил тройное заявление вашим кодом, он бы вернулся к своей функции преждевременно. Существует разница ___big___ между присваиванием переменной и возвратом значения. – Cerbrus

0

Это два тройных гнезда.

Развернув наружный слой даст нам:

var x; 
if (i) { 
    x = i < 0 ? Math.max(0, len + i) : i; 
} else { 
    x = 0; 
} 
i = x; 

Развернув внутреннюю ветвь, то дает нам:

var x; 
if (i) { 
    if (i < 0) { 
    x = Math.max(0, len + i); 
    } else { 
    x = i; 
    } 
} else { 
    x = 0; 
} 

i = x; 

В х представляющую временное значение, которое получает переназначен на I.

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

i = i ? (i < 0 ? Math.max(0, len + i) : i) : 0; 

Теперь вы можете увидеть Подвыражение скрывается в середине истинной ветви , внешнего тройника.

+0

Я не вижу, где мой код достаточно некорректен, чтобы оправдать нисходящее. Особенно там, где я явно определил новую переменную для представления значения подвыражений, так как в представленном тройнике имеется ровно 0 побочных эффектов (присваивание 'i'). С удовольствием исправить любую ошибку/надзор, иначе. – Norguard

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