2013-05-29 4 views
4

Я слышал разные мнения по поводу использования var в такой ситуации:, что это правильно: вар заявление, если не определено

function(maybeUndefined) { 
    if(typeof maybeUndefined === 'undefined') 
     var maybeUndefined = 'bob'; 
} 

Нужно ли фиксировать var, или нет, потому что maybeUndefined является argument из function ?

+1

Вы можете использовать 'this' слово; Я не думаю, что это означает, что вы думаете, что это значит. – Mathletics

+1

Да, имя параметра уже делает его локальной переменной. – Bergi

ответ

10

В этом случае вам не нужно var, так как mayBeUndefined уже выделен в рамках функции (подсказка: перечисление переменных аргумента в определении функции заставляет эти переменные объявляться локально). Таким образом, var является полностью необязательным, хотя и совершенно бессмысленным (и утечка на удобочитаемость).

+0

Что вы подразумеваете под словом «определение функции бросает его»? –

+0

@RienNeVaPlus [править]? Вы пишете бумагу? – Mathletics

+1

@ ŠimeVidas: 'function (a, b, c)' подразумевает наличие 'a',' b' и 'c' в качестве локальных переменных внутри функции. –

3

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

Кроме того, вы должны отметить, что это не часть this. this будет использоваться только для объекта функции, если используется ключевое слово new, и поскольку у вас нет именованной функции, в этом случае это маловероятно. Без new this относится к окну (или undefined, если используется use strict;), из которого ваша переменная определенно не является частью результата аргумента, имеющего локальную область.

+0

спасибо за подсказку :) –

+0

'this' не ссылается на _scope_ функции даже с' new'. И без 'new' существует несколько способов вызова функции, так что' this' не будет 'window'. – nnnnnn

+0

В строгом языке (который должен быть подразумеваемым языком, IMO), '' '' 'undefined' для регулярных вызовов функций. Итак, не глобальный объект. –

6

Пример:

function func (arg1, arg2) { 
    var local1, local2; 

    function nested1() {} 
    function nested2() {} 

    // other code 
} 

Здесь мы имеем объявление функции. Когда эта декларация анализируются в функциональном объект, лексическую среду (= объем) создаются для выполнения этой функции со следующими привязками:

  • arg1
  • арг2
  • LOCAL1
  • local2
  • nested1
  • nested2
  • это
  • аргументы

(Обратите внимание, что существуют также два специальных встроенных крепления: this и arguments. Они всегда создаются для всех объектов функций.)

Эти имена определяются как локальные привязки. (Этот процесс указан в "Declaration binding instantiation". Предупреждение: этот алгоритм не предназначен для чтения людьми :-)). Поэтому, когда имя определяется как параметр, нет необходимости объявлять его как локальную переменную. Этот механизм не зависит от того, передано ли значение (аргумент) для этого параметра при вызове функции.

Таким образом, даже если вы вызываете функцию следующим образом:

func(123); 

название arg2 будет по-прежнему определяется (как связывание в среде функция в), хотя его стоимость будет первоначально undefined для этого конкретного вызова ,

Btw, если вы используете строгого язык (рекомендуется!), Функциональные средами являются статическими, что означает, что вышеуказанные переплеты быть гарантированы только переплетами в среде функции. С другой стороны, по умолчанию предоставляет определенные механизмы, динамически, добавлять/удалять привязки из среды функции. Пример:

(function() { 

    // the name "temp" does not exist as a binding in the function's environment 

    eval('var temp'); 

    // now it does 

    delete temp; 

    // and it's gone again 

}()); 
+0

+1, блестящий ответ! –

1

Сопряжение

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

arguments объект

Аргументы могут по-прежнему передаются функции без параметров, и по-прежнему будут доступны в «скрытой» arguments объект - который является своего рода «псевдо-массив» (если вы будет), в том, что это функционально массив, но не оснащен тем же API, JavaScript вооружает Array (псевдо-типа) с:

// The following functions do the same thing, but one is "more readable" 

function foo() { 
    return arguments; 
} 

function bar(baz, qux) { 
    return arguments; 
} 

оценки (интерфейс) против выполнения (реализации)

Когда обе функции оценивали (в файле «нагрузки»), то arguments объект находится в каждом определении функции undefined; объект не становится «определенным», пока функция не выполняет код; чтобы визуализировать, что с помощью псевдо-код, он бы выглядеть примерно так:

// Function bodies (as objects) 
foo : { 
    arguments : new Array // [undefined] 
    __proto__ : Empty() // the super-object that allows this object to inherit "functionality" 
} 

bar : { 
    arguments : new Array(baz, qux) // [undefined, undefined] 
    __proto__ : Empty() 
} 

Функция вызова

Итак, когда вы вызываете функцию, она «реализует» или «исполняет» его тело (его «объект»). Когда это произойдет, если объекты, которые были введены в объект , определены, то функция может ссылаться на них. Если нет, будет выбрана эталонная ошибка, занесенная в журнал, что переменные undefined в этой области.

Короче:

Это не нужно взаимодействовать переменные функции-сфера уровня (так называемые «частные члены») с использованием var, потому что язык уже придает arguments объект для всех объектов function тела ,

Больше чтения:

JavaScript запоминание: "Функция-кэширование" несколько аргументов для повышения производительности: http://decodize.com/javascript/javascript-memoization-caching-results-for-better-performance/

+0

Обратите внимание, что 'arguments' is * not * на самом деле типа JavaScript« Array »- я использовал его для иллюстративных целей, потому что они настолько похожи (один расширяет другой). Но 'arguments' является абстрактным массивом типов данных (структурно) тем, что это * вектор *, который несет« последовательность »элементов; функция «Пусто», установленная на «прототипе» объекта, так что JavaScript может * обязательно * реализовать «конструктор» этого объекта (или «выполнить его {тело)»). В StackOverflow много хороших чтений об объектах, прототипах и конструкторах; и их влияние на/влияет на контрольный объем. – Benny

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