0

I am getting "weekday is not defined" error output, not sure why. Any help is greatly appreciated!

(function(exports) {

  var days = ["monday", "tuesday", "wednesday", "thursday"];

  exports.name = function(number) {
    return days[number];

  };
  exports.day = function(name) {

    return days.indexOf(name);

  };

})(this.weekday = {});

console.log(weekday.name(1));
RobG
  • 124,520
  • 28
  • 153
  • 188
evanr123
  • 43
  • 1
  • 5
  • 2
    Where are you getting the "not defined" message? – Jose Nuno Oct 04 '19 at 22:21
  • the console where the output is displayed, in netbeans. – evanr123 Oct 04 '19 at 22:22
  • 5
    haha. excellent response. They wanted to know where in your code – baao Oct 04 '19 at 22:22
  • What isn't defined? What have you tried so far to fix this? What are you wanting to do with this? The little bit of code you shared seems to be from a bigger block just based on your use of `this` and the fact that `weekday` or `exports` are not defined anywhere. Could you possible share more code? – Jesse Oct 04 '19 at 22:22
  • sorry, I revised the question, it says "weekday is not defined". I thought this was the only code needed, maybe that is the problem, the book dose have code before this that defines a weekday function/module but it has the same functionality as the module above, so I thought the purpose was to choose one or the other. – evanr123 Oct 04 '19 at 22:25
  • @J.Murray—the outer brackets make the statement a function expression, so it can be called immediately (and doesn't need a name). – RobG Oct 04 '19 at 22:27
  • try calling `console.log(this.weekday.name(1));` in the last line. – Taha Paksu Oct 04 '19 at 22:27
  • The code as posted works (it can be reduced to `(function() {})(this.weekday = {}); console.log(weekday)` as an example), so voting to close as OT as the posted code doesn't illustrate the issue. – RobG Oct 04 '19 at 22:35
  • @RobG that seems very unhelpful. Can you explain *why* the code reduces to this? – Jochem Kuijpers Oct 04 '19 at 22:37
  • 2
    It's all about variable scopes in javascript. I suggest you read more about it, it' interesting and many times helps you to debug your code faster. – Mohammad Mahmoudi Oct 04 '19 at 22:37
  • Your result is that *weekday* is not defined, but `(function() {})(this.weekday = {})` creates a global property/variable named *weekday* that references an "empty" object. – RobG Oct 04 '19 at 22:38
  • @RobG Then it seems like that is the explanation OP was looking for, Along with the current helpful answer, I see no reason to close this.. – Jochem Kuijpers Oct 04 '19 at 22:39
  • @JochemKuijpers—the OP reports an issue that *weekday* is undefined, but has yet to post code that reproduces the error, hence it's off topic. The OP's code works, it doesn't create an error. It's a fairly common pattern that must be in thousands of script files. – RobG Oct 04 '19 at 22:43
  • @RobG Yet the answer likely solves the problem that SO users were able to deduce from a common error made with this pattern, and offers an explanation to learn from. Isn't that the point of asking questions? (further discussion should probably not take place here) – Jochem Kuijpers Oct 04 '19 at 22:47
  • @JochemKuijpers—there is no problem in the posted code. Until the OP posts code that illustrates the issue, there can't be a useful answer because we can only guess at why they are getting the message (as Taha Paksu has done). It may be a problem with the NetBeans IDE, it might be they've identified the wrong section of code, it might be any one of a dozen issues, but whatever it is it's not in the OP. – RobG Oct 04 '19 at 22:50
  • 1
    @RobG, the OP is filling `this.weekday` object member methods with the above code. `weekday` (if set before) won't produce the `weekday is not defined` exception, it will tell that the object doesn't have a `name` method. – Taha Paksu Oct 04 '19 at 22:54
  • 1
    Correct, the problem isn't in the code; it's described in the title and the text. – Jochem Kuijpers Oct 04 '19 at 22:54
  • Good grief, **the code works and does not produce an error**. I've converted the code exactly as posted to a runnable snippet (which the OP should have done). The reasons for off topic posts include "*Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself.*" When the OP has done that, the question can be answered. Until then, you can only guess (which is decidedly unhelpful). – RobG Oct 04 '19 at 22:58
  • @RobG yes you are absolutely right, this.weekday sets window.weekday and the latter will work because it's set, you never will get an undefined error, but the OP is having one and we know the reason. It's 100% caused by a different scope of variables. Shouldn't we help anyone with incomplete but clearly understandable questions? – Taha Paksu Oct 04 '19 at 23:00

2 Answers2

3

Your code is probably something like:

var scopeMaster = function() {};

scopeMaster.prototype.testMethod = function() {

  (function(exports) {

    var days = ["monday", "tuesday", "wednesday", "thursday"];

    exports.name = function(number) {
      return days[number];

    };
    exports.day = function(name) {

      return days.indexOf(name);

    };

  })(this.weekday = {});

  console.log(weekday.name(1));

};

scopeMaster.prototype.testMethod();

it says "weekday isn't defined" because weekday searches for a local variable, or a variable in the parent scopes. Not searching a member in the current scope object, and thus it won't match this.weekday.

You can do it in two ways:

1) By declaring a local or parent scope variable:

var scopeMaster = function() {};

var weekday = null; // here's the global one

scopeMaster.prototype.testMethod = function() {

  // var weekday = null; // if you want a private local one
  
  (function(exports) {

    var days = ["monday", "tuesday", "wednesday", "thursday"];

    exports.name = function(number) {
      return days[number];

    };
    exports.day = function(name) {

      return days.indexOf(name);

    };

  })(weekday = {});

  console.log(weekday.name(1));

};

scopeMaster.prototype.testMethod();

2) By using the current scope member variable:

var scopeMaster = function() {};

scopeMaster.prototype.testMethod = function() {
 
  (function(exports) {

    var days = ["monday", "tuesday", "wednesday", "thursday"];

    exports.name = function(number) {
      return days[number];

    };
    exports.day = function(name) {

      return days.indexOf(name);

    };

  })(this.weekday = {});

  console.log(this.weekday.name(1));

};

scopeMaster.prototype.testMethod();
Taha Paksu
  • 14,293
  • 1
  • 39
  • 67
  • The posted code doesn't display the reported issue, it works fine. It doesn't make a lot of sense to refactor the code just to generate the issue, then propose a response for a guess at the problem. It may be an issue with the NetBeans IDE. – RobG Oct 04 '19 at 22:48
  • @RobG the posted code even isn't complete, how do you tell that it's working fine? – Taha Paksu Oct 04 '19 at 22:49
  • By running it (surely you tried it?). I've converted the code in the OP to a runnable snippet exactly as originally posted. It works. – RobG Oct 04 '19 at 22:54
  • Yes, because the scope's are the same, they both are owned by the `window` object. So the exception should be related with different scopes, right? – Taha Paksu Oct 04 '19 at 22:57
  • Who knows? Certainly no one here because the OP hasn't posted code that produces the error. `this.weekday = {}` creates a global *weekday*, how can it be a scope issue? You can also produce the error by moving `console.log(weekday.name(1));` to above the IIFE. – RobG Oct 04 '19 at 23:01
  • if `this == window` yes it'll always work. Otherwise you'll get an undefined variable exception. – Taha Paksu Oct 04 '19 at 23:02
  • It's global code, *this* is the global object (which might also be *window*, but not necessarily). – RobG Oct 04 '19 at 23:03
0

The code behaves as reported if the this value in the this.weekday.name(1) parameter is an object data type (and not just undefined) but does not have the global object as its value.

A weekday property with name and day methods will then be created on the this object without error, but attempts to access it as a global property variable will fail saying weekday is not defined.

If the code is in a required node module, this answer explains that this is set to module.exports. If this is not the case you will need to investigate how this gets its value further.

traktor
  • 12,838
  • 3
  • 23
  • 44