简体   繁体   中英

dot notation , window object and its properties

I am trying to learn some new concepts about javascript.Here is a simple code I wrote. Inside a function THIS keyword refers to global object which is window unless it's bind with the context of another object. Inside myobj object there are two methods which shares a same name with another two globally accessible function called afunc and anotherfunc respectively. I want to access those global function within myobj context and of course without using binding global object to a immediately invoked function which I used to call them. But it is throwing an error. My question is if everything in javascript is an object and window object holds them ,then why can i access those function using this.afucn or 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(); })(); 

It is true that in your case, this will refer to the global object and this.afunc() , etc will access the global variable afunc .

However, unless there is more code to show, you don't have a global variable afunc . The variables you defined with

(function(){
var afunc=function (){
    document.write('this is world'+'</br>');
}
var anotherfunc=function (){
   document.write('this is another world');
}
//...
})();

are local to the enclosing function (the (function(){ ... })(); part).

If you want to make them global, you can just move them outside the 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(); })(); 


However , note that in strict mode , this would be undefined , not referring to the global object. This was done because usually if someone uses this inside a function, they don't expect it to refer to the global object. By just looking at the code, it's not always clear whether you want to access the global object (via this ) or some other object (and as you noticed, there was some confusion about your intend).

That's why, if you want to access the global object, you should do so explicitly and refer to it via window .

First things first, I think you have some things a little bit confused.

In JavaScript, not everything is a function. Instead, there are a few different primitives one can use (as of ES5):

  1. String
  2. Number
  3. Boolean,
  4. Null
  5. Undefined
  6. Object

Recommended Reading: Mozilla Documentation on JavaScript Data Structures

Each of these types has special methods associated with it - except for null and undefined , those are placeholders with very specific usages - but those aren't important for helping to fix your understanding of what's going on in JavaScript. One of the keys that will help, is the idea that JavaScript is what's called a functional language . In part, this means that functions are first-class objects. Among other things, this means that it is possible to use a function as a value.

Another thing, is that said returned functions aren't the only thing that gets returned - what happens is that function programming is built around the idea of a closure , or a function and all the relating variables in the scope that the returned function was defined (after all, we could be referencing variables in the function that's returning our new function!)

function foo() {
    var bar = 3;

    // Returns a function that when called, returns the Number 5.
    return function () {
        return 1 + 1 + bar;
    }
}

As far as narrowing down your error is concerned, in your myObj.context function, I notice you've written an immediately-invoking expression...

context: function () {
    (function () {
        this.afunc();
        this.anotherfunc();
    })();
},

Is that really necessary? In fact, is that function really necessary at all? Since we now know that JavaScript treats functions on an object as values, you can always just do myObj.afunc or myObj.anotherfunc to work with the code specific to myObj .

If your intent was to write a method that would call the afunc and anotherfunc methods on myObj , a better set of code would be:

var myObj = {
    afunc: function () {
        // Magic!
    },
    anotherfunc: function () {
        // More magic!
    },
    context: function () {
        this.afunc();
        this.anotherfunc();
    }
};

If your intent is to call the afunc / anotherfunc defined in the immediately-invoking expression surrounding the declaration of myObj , simply remove the this from the calls in context .

If your intent is to call the afunc / anotherfunc methods on the global scope, then you are plumb out of luck: you have not defined such functions in the given snippet. However, this could be fixed like so:

// 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();
})();

Generally, though, this is considered bad programming form, because we're cluttering the global scope with unnecessary functions, variables, and objects; it's a better idea to keep your function declarations inside of the immediately-invoking object, unless you need to call them in other places. If you need to call these functions in other places, you might consider researching the ways you would do that.

It's not working because this is not referring to what you think it's referring to, it's holding on to the window . In which from there, the functions are outside are not entirely in the global scope because they are wrapped within (function(){ ... })(); . Now to your context function, we don't want the function() wrapper because nothing is in global scope:

   context:function(){
       (function(){ // <-- Here
           this.afunc();
           this.anotherfunc();
       })(); //        <--
   }

Remove that (we don't want it anyways) and this will refer to an instance of myobj

   context:function(){
       this.afunc();
       this.anotherfunc();
   }

If we want to get the ones declared outside of myobj scope, then you don't want to use this . Because that means the functions that belong to the instance of myobj . You just want to say:

   context:function(){
       afunc();
       anotherfunc();
   }

Because myobj does not know about the "global" functions.

 (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(); })(); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM