简体   繁体   中英

JavaScript Function Hoisting in my Object

I have created an object and am attaching a bunch of functions to the object. I am concerned about how the ordering of the functions effects when I can call my functions. In my example below, I must define my functions first before I can use them. My problem with this is that I cannot call init() immediately until I have defined it. Init() will contain a bunch of other functions that it will need to call, which will have to be placed above init(). So in the end, init() will have to be the very last function defined in my object. I believe this is related to Hoisting.

My question is if there is a way for me to call a function before defining it? Is there some sort of way to create a 'placeholder' function like in C?

https://jsfiddle.net/13hdbysh/1/

(function() {

  foo = window.foo || {};

  //this will not error
  foo.helloWorld = function() {
    console.log('helloWorld()');
  };
  foo.helloWorld();

  //this will error
  foo.init();
  foo.init = function() {
    console.log('init()');
  };

})();

Try using similar IIFE pattern

(function() {

    foo = window.foo || {};

  //this will not error
  foo.helloWorld = function() {
    console.log('helloWorld()');
  };
  foo.helloWorld();

  //this will error
  // foo.init();
  foo.init = (function _foo() {
    console.log('init()');
    this.init = _foo;
    return this.init
  }).call(foo);

  foo.init()

})();

jsfiddle https://jsfiddle.net/13hdbysh/2/

What you're asking deals with how objects store member data. This can be seen in a weird light because of prototypal inheritance. Javascript by default will parse naked functions before they execute.

Example:

(function() {
  init();
  function init()
  {
        console.log("Init");
  }
)}; 

This gets muddied when storing behavior as a member to an object. Because prototypal inheritances dynamic functionality you need to declare your members before accessing them. This is Javascript's main difference from traditional OOP languages.

You mentioned, "is there a way to create a 'placeholder' function like in C." You can , but not in the same way. You can assign it to a naked function and assign that to your object. Look in my example, the hello function.

Alternatively you can store the behavior on the prototype of your object and override it when necessary.

Example:

function hello() 
{
  console.log("Hello my name is "+this.name);
}

(function() {  
  var something = function(name) {
        this.name = name;
    };

  something.prototype.initTwo = function() {
    console.log("My Name is: "+this.name);
  };

    var thingOne = new something("Thing One");
  thingOne.init = "SomeThing";

  var thingTwo = new something("Thing Two"); 
  thingTwo.init = function() {
     console.log(this.name);
  };

  thingTwo.initTwo = function() {
    console.log("SomethingTwo is Named: "+this.name);
  };

  thingTwo.hello = hello;

  console.log(thingOne.init);
  thingTwo.init();

  thingOne.initTwo();
  thingTwo.initTwo();
  thingTwo.hello();
}) ();

Demo: Fiddle

Documentation on objects in javascript.

我不确定为什么要在定义它之前先调用它,但是这里是如何做的:

foo = window.foo || { init: function() { } };

How about declaring it as a local variable first.

(function() {

  foo = window.foo || {};

  //this will not error
  foo.helloWorld = function() {
    console.log('helloWorld()');
  };
  foo.helloWorld();

  var initFunction = function() {
     console.log('init()');
  };
  //this will no longer error
  initFunction();

  foo.init = initFunction;

})();

Init() will contain a bunch of other functions that it will need to call, which will have to be placed above init().

You are operating under a misapprehension.

A function must be defined before you call it, not before you define another function which will call it later.

Just define all your functions and then start calling them.

(function() {

  foo = window.foo || {};

  foo.helloWorld = function() {
    console.log('helloWorld()');
  };

  foo.init = function() {
    console.log('init()');
  };

  foo.init();
  foo.helloWorld();

})();

As far as hoisting is concerned, function declarations (you only have function expressions) are hoisted, but they create locally scoped variables, not object properties. You would have to assign them to object properties before you could call them as such, and that assignment wouldn't be hoisted.

It's throwing an error because you're calling the method init() before it's declared.

This way will works

foo.init = function() {
   console.log('init()');
 };
 foo.init();

Since foo is an object, you can put those functions into an object so that will be assigned to foo once window.foo is null

 (function() { foo = window.foo || { helloWorld: function() { console.log('helloWorld()'); }, init: function() { console.log('init()'); } }; //this will not error foo.helloWorld(); foo.init() })(); 

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