Я несколько новичок в JavaScript и задаю несколько вопросов о сфере видимости, о которой, как представляется, явно не задавали раньше. В верхней части функции, над которой я работаю, угловая переменная vm
устанавливается равной this
. Я понимаю, что все, что предваряет vm
будущем, будет в рамках this
но как это отличается от того, чтобы быть в области функций, чтобы начать? Чтобы быть более явным, как vm.foo = "test"
отличается от var foo = "test"
внутри функции с точки зрения ее объема. Любая помощь приветствуется.
Если вы установите vm = this
, то свойства vm
могут сохраняться за пределами текущего вызова функции. Напротив, локальное значение переменной (например, var foo = "test"
) не сохраняется за текущим вызовом функции.
В принципе, this.foo
внутри функции не эквивалентен var foo
внутри этой же функции. Первое на самом деле ссылается на значение свойства для this
объекта, тогда как второе ссылается только на локальную переменную в текущей области вызова функции.
Вот пример, иллюстрирующий эту разницу:
function myFunction(myArg) {
console.log("this.foo = " + this.foo);
console.log("foo = " + foo);
var foo = "test";
console.log("foo' = " + foo);
var vm = this;
console.log("vm.foo = " + this.foo);
vm.foo = myArg;
console.log("vm.foo' = " + this.foo);
}
console.log("window.foo = " + window.foo);
console.log(">>> Test call 1");
myFunction("abc");
console.log("window.foo = " + window.foo);
console.log(">>> Test call 2");
myFunction("xyz");
console.log("window.foo = " + window.foo);
Для удобства, вот консольный вывод:
window.foo = undefined
>>> Test call 1
this.foo = undefined
foo = undefined
foo' = test
vm.foo = undefined
vm.foo' = abc
window.foo = abc
>>> Test call 2
this.foo = abc
foo = undefined
foo' = test
vm.foo = abc
vm.foo' = xyz
window.foo = xyz
Как вы можете видеть, this
внутри функции на самом деле относится к глобальному window
объекту. Это означает, что значение vm.foo
которое вы назначаете внутри функции, фактически доступно в любом месте, где доступно window
(т. vm.foo
в вашем скрипте). Вы можете изменить, какой объект используется как this
если вы вызываете функцию с помощью метода call
и явно передаете другой объект как thisArg
. Вы также можете получить другой объект как this
если вы вызываете функцию как метод для некоторого объекта. Вот пример, иллюстрирующий обе эти возможности:
function myFunction(myArg) {
console.log("this.foo = " + this.foo);
console.log("foo = " + foo);
var foo = "test";
console.log("foo' = " + foo);
var vm = this;
console.log("vm.foo = " + this.foo);
vm.foo = myArg;
console.log("vm.foo' = " + this.foo);
}
var x = { f: myFunction };
var y = { f: myFunction, foo: "YYY" };
var z = { foo: "ZZZ" };
x.f("x"); // "this" is "x"
y.f("y"); // "this" is "y"
myFunction.call(z, "z"); // "this" is "z"
console.log("x.foo = " + x.foo);
console.log("y.foo = " + y.foo);
console.log("z.foo = " + z.foo);
Обратите внимание, как вызовы, которые используют y
и z
для this
имеют начальные значения this.foo
, так как соответствующие объекты инициализируются значением для свойства foo
. Значение this.foo
сохраняется в объекте, на который this
ссылается, а не в самой функции (если, конечно, this
не относится к самой функции).
console.log(this.foo);
в конце кода выше.
this
в вашем примере глобальный объект как функция выполняются без какого - либо контекста исполнения. Если вы делаете new myFunction()
, this
будет ссылаться на новый экземпляр, и свойство не будет присутствовать при следующем вызове. Модули Angularjs имеют собственный контекст выполнения, поэтому this
не будет глобальный объект, поэтому он не сохраняется между экземплярами новых модулей
Внутри функции var foo = 'test'
не обязательно связывает foo
с this
, потому что значение this
зависит от того, как была вызвана функция (см. Раздел "Функциональный контекст").
Скорее независимо от вышесказанного, причиной присвоения this
vm
является сохранение его ссылки, если вы хотите иметь другую функцию внутри этой функции, где вы ссылаетесь на исходный контекст this
. Обычно это делается в функции контроллера, см. Это Руководство по угловому стилю.