Попытка выяснить, как работает сфера - PullRequest
3 голосов
/ 14 декабря 2011

Я пытаюсь выучить JS на Codeacademy, и я не могу понять / пройти через это. Может кто-нибудь дать ответ, а также объяснить, почему это так? Был бы глубоко признателен.

// This function tries to set foo to be the
// value specified.

function setFoo(val) {
  // foo is declared in a function. It is not
  // accessible outside of the function.
  var foo = val;
}

setFoo(10);

// Now that we are outside the function, foo is
// not defined and the program will crash! Fix this
// by moving the declaration of foo outside of the
// function. Make sure that setFoo will still update
// the value of foo.
alert(foo);

Ответы [ 8 ]

3 голосов
/ 14 декабря 2011

Вы можете видеть область действия как термин, обозначающий, какие переменные вы можете достичь на определенном «уровне» в коде.В JavaScript эти «уровни» определяются функциями.Каждая функция вводит новый уровень.

Например, возьмите этот пример кода:

var a;
// you can access a at this level

function function1() {
  var b;
  // you can access a, b at this level

  function function2() {
    var c;
    // you can access a, b, c at this level
  }
}

Так что в вашем случае вы должны объявить var foo; вне функции, предпочтительно над ней.Затем вы можете установить его внутри setFoo с помощью foo = val;.foo затем относится к тому, который вы объявили на уровне выше setFoo.

foo, доступен как в setFoo, так и в вызове alert таким образом;сравните его с приведенным выше примером кода (function1 равно setFoo, a равно foo, а вызов alert находится на самом верхнем уровне. function2, b и c неиспользуется в вашем случае.).

2 голосов
/ 14 декабря 2011

Каждая функция в Javascript имеет свою область видимости. Это означает, что каждая переменная, которую вы определяете с помощью ключевого слова var, будет доступна только внутри этой функции. Это означает, что когда вы вызываете setFoo(10), вы создаете переменную foo, присваиваете ей значение пять, после чего она немедленно уничтожается, потому что выходит из области видимости.

Существует несколько способов решения этой проблемы. Первым будет удалить ключевое слово var. Это поместило бы foo в глобальную область, что означает, что это доступно везде. Тем не менее, это не рекомендуется, вы хотите сохранить глобальную область как можно более загроможденной, чтобы при наличии кода JavaScript, предоставленного несколькими людьми на одной странице, они не могли перезаписывать переменные других людей. Еще один способ сделать это будет так:

function setFoo(val){
    var foo = val;
    alertfoo = function(){
        alert(foo)
    } 
}

В этом примере единственное, что вы помещаете в глобальную область видимости, - это функция alertfoo, потому что вы хотите, чтобы она была доступна везде. Функция alertfoo определена внутри функции setFoo, это означает, что, хотя foo должен был выйти из области видимости после выполнения setfoo, он сохраняется в памяти, потому что alertfoo имеет к нему доступ.

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

(function(){
    //set variables you want to be global in your own code
    var mainpage = document.getElementById('main');

   //define functions you want to make available to other people in a way that puts them in the global scope
   setMainElement = function(newmain){mainpage = newmain;}
})();

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

(function(){
    var privatevar = 10,otherprivate=20;

     publicInterface = {
        'addToPrivate': function(x){privatevar+=x;},
        'getPrivate': function(){return private}
     };
})();
2 голосов
/ 14 декабря 2011

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

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

var foo;
function setFoo(val) {   
  foo = val; 
}
setFoo(10); 
alert(foo); // No longer crashes
2 голосов
/ 14 декабря 2011

Просто объявите foo вне любой функции, тогда она будет глобальной:

var foo = null;

function setFoo(val) {
  foo = val;
}

setFoo(10);

alert(foo);

Попробуй!

2 голосов
/ 14 декабря 2011
// Create globale variable
// (You should not use globale variables!)
var foo;

// set value
function setFoo(val) {
  foo = val;
}
setFoo(10);

// show value
alert(foo);
1 голос
/ 14 декабря 2011

Оригинальный код:

function setFoo(val) {
  var foo = val;
}

setFoo(10);

alert(foo); // Crash!

Их советы по устранению сбоя:

Исправьте это, переместив объявление foo за пределы функции

Полагаю, вы не понимаете, что они имеют в виду "вне функции".

Попробуйте этот отредактированный код:

var foo = 5; // "var" declares the variable to be in this outer scope

function setFoo(val) {
  foo = val; // but we can still access it in this inner scope...
}

setFoo(10);

alert(foo); // Displays a dialog box that says "10"
0 голосов
/ 14 декабря 2011

В JavaScript новые области создаются только функциями

0 голосов
/ 14 декабря 2011

Переменные, определенные в функции, действительны только в функции

function setFoo(val) {
    foo = val;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...