Точечная нотация, объект окна и его свойства
Я пытаюсь изучить некоторые новые понятия о javascript. Вот простой код, который я написал. Внутри функции это ключевое слово относится к глобальному объекту, который является окном, если он не связан с контекстом другого объекта. внутри myobj
У объекта есть два метода, которые имеют одно и то же имя с двумя другими глобально доступными функциями afunc
а также anotherfunc
соответственно. Я хочу получить доступ к этим глобальным функциям в контексте myobj и, конечно же, без привязки глобального объекта к немедленно вызванной функции, которую я использовал для их вызова. Но это бросает ошибку. Мой вопрос: если все в javascript - это объект, а объект window содержит их, то почему я могу получить доступ к этой функции, используя this.afucn
или же window.afunc
?
(function(){
var afunc=function (){
document.write('this is world'+'</br>');
}
var anotherfunc=function (){
document.write('this is another world');
}
var myobj={
afunc:function(){
document.write('afunc');
},
anotherfunc:function(){
document.write('anotherfunc');
},
context:function(){
(function(){
this.afunc();
this.anotherfunc();
})();
}
};
myobj.context();
})();
3 ответа
Это правда, что в вашем случае, this
будет ссылаться на глобальный объект и this.afunc()
и т. д. получит доступ к глобальной переменной afunc
,
Однако, если нет больше кода для отображения, у вас нет глобальной переменной afunc
, Переменные, которые вы определили с
(function(){
var afunc=function (){
document.write('this is world'+'</br>');
}
var anotherfunc=function (){
document.write('this is another world');
}
//...
})();
являются локальными для ограждающей функции ((function(){ ... })();
часть).
Если вы хотите сделать их глобальными, вы можете просто переместить их за пределы функции:
var afunc = function() {
document.write('this is world' + '</br>');
};
var anotherfunc = function() {
document.write('this is another world');
};
(function() {
var myobj = {
afunc: function() {
document.write('afunc');
},
anotherfunc: function() {
document.write('anotherfunc');
},
context: function() {
(function() {
this.afunc();
this.anotherfunc();
})();
}
};
myobj.context();
})();
Однако учтите, что в строгом режиме this
было бы undefined
, не ссылаясь на глобальный объект. Это было сделано, потому что обычно, если кто-то использует this
внутри функции они не ожидают, что она ссылается на глобальный объект. Просто глядя на код, не всегда понятно, хотите ли вы получить доступ к глобальному объекту (через this
) или какой-то другой объект (и, как вы заметили, в вашем намерении была некоторая путаница).
Вот почему, если вы хотите получить доступ к глобальному объекту, вы должны сделать это явно и обратиться к нему через window
,
Перво-наперво, я думаю, что вы немного запутались.
В JavaScript не все является функцией. Вместо этого можно использовать несколько разных примитивов (начиная с ES5):
- строка
- Число
- Boolean,
- Ноль
- Неопределенный
- объект
Рекомендуемое чтение: документация Mozilla по структурам данных JavaScript
Каждый из этих типов имеет специальные методы, связанные с ним - за исключением null
а также undefined
это заполнители с очень специфическим использованием, но они не важны для того, чтобы помочь вам понять, что происходит в JavaScript. Одним из ключей, который поможет, является идея, что JavaScript - это то, что называется функциональным языком. Частично это означает, что функции являются первоклассными объектами. Среди прочего, это означает, что можно использовать функцию в качестве значения.
Другое дело, что возвращаемые функции - это не единственное, что возвращается - то, что происходит, заключается в том, что программирование функций построено на идее замыкания или функции и всех связанных переменных в области видимости, в которой была определена возвращаемая функция. (в конце концов, мы можем ссылаться на переменные в функции, которая возвращает нашу новую функцию!)
function foo() {
var bar = 3;
// Returns a function that when called, returns the Number 5.
return function () {
return 1 + 1 + bar;
}
}
Что касается сужения вашей ошибки, в вашем myObj.context
Я заметил, что вы написали вызывающее выражение...
context: function () {
(function () {
this.afunc();
this.anotherfunc();
})();
},
Это действительно необходимо? Фактически, эта функция действительно необходима вообще? Поскольку теперь мы знаем, что JavaScript обрабатывает функции объекта как значения, вы всегда можете просто myObj.afunc
или же myObj.anotherfunc
работать с кодом, специфичным для myObj
,
Если бы вы намеревались написать метод, который бы вызывал afunc
а также anotherfunc
методы на myObj
лучший набор кода будет:
var myObj = {
afunc: function () {
// Magic!
},
anotherfunc: function () {
// More magic!
},
context: function () {
this.afunc();
this.anotherfunc();
}
};
Если вы намереваетесь позвонить afunc
/anotherfunc
определяется в выражении немедленного вызова, окружающем объявление myObj
Просто удалите this
от звонков в context
,
Если вы намереваетесь позвонить afunc
/anotherfunc
методов в глобальной области видимости, тогда вам не повезло: вы не определили такие функции в данном фрагменте. Однако это можно исправить так:
// Now, afunc exists in the global scope!
function afunc() {
// Magic
}
// Now, anotherfunc exists in the global scope!
function anotherfunc() {
// Magic
}
(function () {
var myObj = {
// Your object...
};
myObj.context();
})();
Однако в целом это считается плохой формой программирования, потому что мы загромождаем глобальную область видимости ненужными функциями, переменными и объектами; Лучше хранить объявления функций внутри объекта, вызывающего немедленный вызов, если только вам не нужно вызывать их в других местах. Если вам нужно вызывать эти функции в других местах, вы можете подумать о том, как это сделать.
Это не работает, потому что this
не относится к тому, что вы думаете, это относится к, это держится за window
, В котором оттуда функции находятся не полностью в глобальной области видимости, потому что они заключены в (function(){ ... })();
, Теперь к вашему context
функция, мы не хотим function()
обертка, потому что ничего не находится в глобальной области видимости:
context:function(){
(function(){ // <-- Here
this.afunc();
this.anotherfunc();
})(); // <--
}
Удалите это (мы все равно не хотим) и this
будет ссылаться на случай myobj
context:function(){
this.afunc();
this.anotherfunc();
}
Если мы хотим, чтобы те были объявлены за пределами myobj
объем, то вы не хотите использовать this
, Потому что это означает, что функции, которые принадлежат экземпляру myobj
, Вы просто хотите сказать:
context:function(){
afunc();
anotherfunc();
}
Так как myobj
не знает о "глобальных" функциях.
(function(){
var afunc=function (){
document.write('this is world'+'</br>');
}
var anotherfunc=function (){
document.write('this is another world');
}
var myobj={
afunc:function(){
document.write('afunc');
},
anotherfunc:function(){
document.write('anotherfunc');
},
context:function(){
afunc();
anotherfunc();
}
};
myobj.context();
})();