Точечная нотация, объект окна и его свойства

Я пытаюсь изучить некоторые новые понятия о 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):

  1. строка
  2. Число
  3. Boolean,
  4. Ноль
  5. Неопределенный
  6. объект

Рекомендуемое чтение: документация 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();
})();

Другие вопросы по тегам