2013-03-14 3 views
4

I'v пытались найти причину использования этой строки кодаЧто такое «var cc = cc = cc || {};» line делать в Cocos2D?

var cc = cc = cc || {}; 

в библиотеке Cocos2D JavaScript, например, в this месте, но я не мог найти никаких разумных оснований. Единственное задание с точки зрения настроек по умолчанию было бы неплохо, но двойное назначение? Кто-нибудь знает причину этого?

+6

выглядит ошибкой для меня – musefan

+0

Да, это определенно ошибка. –

+1

Возможно, он оценивается как 'var cc = (cc = cc || {});', поэтому он просто устанавливает локальные и глобальные переменные 'cc'? – VisioN

ответ

1

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

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

Обратите внимание, что, например, я буду использовать фактические значения, а не пустые объекты.

Обычно, можно было бы ожидать, чтобы увидеть следующий пример использования:

var cc = cc || 1; 

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

Это можно проверить, используя различные имена переменных, например:

var aa; 
alert(aa); 
var cc = aa || 1; 
alert(aa); 
alert(cc); 

(Example) Здесь вы можете увидеть, что aa никогда не меняется.

Далее мы рассмотрим код в вопросе:

var cc = cc = cc || 1; 

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

var aa; 
alert(aa); 
var cc = aa = aa || 1; 
alert(aa); 
alert(cc); 

(Example) На этот раз мы можем видеть, что aa действительно переодеться.

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

+0

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

2

код эквивалентен следующему:

var cc; 
cc = cc || {}; 
cc = cc; 

, который, очевидно, является ошибкой.

ОБНОВЛЕНИЕ. я сделал больше исследований по этой теме, и вот интересная вещь:

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

var cc = 1; 
function test() { 
    var cc = cc || {}; 
    return cc; 
} 
test(); 

всегда будет производить {}, независимо от того, что начальное значение cc (в глобальном масштабе) есть. В частности, этот код:

var cc = [expression]; 

эквивалентно:

var cc; 
cc = [expression]; 

хотя var cc; создает новую переменную только еслиcc не существует в текущей области.

ОБНОВЛЕНИЕ 2. Какая операция имеет приоритет, запутанная, поскольку в коде OP оба знака = фактически не совпадают. Первый обозначает объявление переменной, потому что перед ним есть ключевое слово var. Второй - назначение. Вот почему

var x = y = z; 

эквивалентно

var x; 
y = z; 
x = z; 

(обратите внимание, что var ключевое слово относится только к x), а

x = y = z; 

эквивалентно

y = z; 
x = z; 

(обратите внимание, что операция y=z возвращает z, который не имеет никакого значения (это может быть y очевидно), но стоит отметить)

ВЫВОД: Объявления переменного на левой стороне всегда приходит перед оценкой из правая сторона и назначение правой стороны влево.

+0

. Разве это не было бы эквивалентно 'cc = cc || {}; var cc = cc; ' – musefan

+0

@musefan Я не уверен на 100%, как он работает под капотом, но кажется, что объявление переменной имеет приоритет перед другими операциями. Это также доказывает, что таких конструкций следует избегать. – freakish

+0

@musefan Я обновил свой ответ. – freakish

0

Этот код является ошибкой. То, что автор имел в виду, вероятно, заключалось в том, чтобы установить как глобальные, так и внутренние переменные области видимости на одно значение, но это выражение всегда терпит неудачу. Мало того, что это не позволяет установить внешнюю переменную, он всегда обращается к {}.

Причина, по которой это выражение терпит неудачу, состоит в том, что объявленные переменные установлены на undefined перед назначением. Так как эта строка кода пытается назначить переменную с тем же именем, что и сама, и поскольку JavaScript сначала оценивает внутренние переменные области видимости, то cc всегда будет определять свое внутреннее ядро ​​ во время присвоения, что отрицает логическую оценку и возвращает {} ,

Другой способ увидеть это в коде:

var cc;     //cc is set to 'undefined' 

cc = cc || {};   //which becomes equivalent to: 

cc = undefined || {}; //which finally evaluates to: 

cc = {}