2015-04-25 1 views
1

Вопрос (Eloquent JS 2nd Ed, Глава 4, упражнение 4):Почему код JavaScript выполняется во время условия false? (Eloquent JavaScript - Deep сравнение)

Написать функцию, deepEqual, которая принимает два значения и возвращает истину только если они имеют одинаковое значение или являются объектами с теми же свойствами , значения которых также равны по сравнению с рекурсивным вызовом deepEqual для .

Test Cases:

var obj = {here: {is: "an"}, object: 2}; 
var obj1 = {here: {is: "an"}, object: 2}; 
console.log(deepEqual(obj,obj1)); 

Код:

var deepEqual = function (x, y) { 
    if ((typeof x == "object" && x != null) && (typeof y == "object" && y != null)) { 
     if (Object.keys(x).length != Object.keys(y).length) 
      return false; 

     for (var prop in x) { 
      if (y.hasOwnProperty(prop)){ 
      if (! deepEqual(x[prop], y[prop])) //should not enter!! 
       return false; 
       alert('test'); 
      }else return false; // What does this section do? 
     } 
     return true; 
    } 
    else if (x !== y) 
     return false; 
    else 
     return true; 
}; 

изначально выполняются Paul Roub

Главный вопрос: Я просто добавил предупреждение к блоку кода после if (! deepEqual(x[prop], y[prop])) заявление вроде отладки, и теперь я понятия не имею, почему код внутри все еще выполняется, а сам оператор должен возвращать true и ! превращает его false ..?
Что такое }else return false;? (Это же утверждение) Функция, кажется, работает нормально без этого раздела ..

+1

Именно поэтому вы никогда не должны опускать выражения «{}» in if ... –

ответ

6

Вы добавили alert() таким образом, что он работает только тогда, когда тест if терпит неудачу, потому что вы не добавили { }, чтобы соответствовать намерение указанный вашим отступом. Если тест if преуспевает, следующая инструкция return выйдет из функции, и alert() не произойдет.

Любой код, который включает в себя блок if или else if, который всегда возвращается, но, тем не менее, следует за предложением else - это запах кода. Либо else, либо return является избыточным; это вопрос стиля, который вы идете.

Этот код также недостатки в том, что он испытывает ряд свойств с Object.keys() — который неявно только смотрит на «собственные» свойства — но затем использует for ... in цикл по xбез.hasOwnProperty() проверки. (Если наследуемые свойства должны влиять на понятие «равенство» является субъективным, но это, вероятно, следует быть симметричными по крайней мере.)

О, и что первый else return false пункт после проверки, чтобы увидеть, если y имеет одно из свойств в x это просто быстрый выход. Если y не имеет имени свойства, которое находится в x, то они не могут быть равны.

Наконец, обратите внимание, что любой тип «глубокого» тестера равенства, который намеревается быть общим, действительно должен иметь дело с циклами графиков объектов и другими даже более странными вещами. (Что-то в объектном графе x относится к части y и наоборот?) Сравнение глубоких объектов не является тривиальной вещью.

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