When I was defining a namespace in JavaScript, Netbeans gave a global variable not declared error while I think it shouldn't. Why is this?
Demonstration code:
var MyNamespace = new function () {
var MyClass = function () {};
MyClass.SOME_CONSTANT = 9; // MyClass not defined
this.MyClass = MyClass; // MyClass not defined
};
I checked and this code works in IE (document mode IE 5) and Edge 13. The code is a Module Pattern like syntax like in this answer.
EDIT: first declaring a variable is probably not useful, for a function inside the namespace will sometimes change the local variable instead of that in the public namespace, am I right? Still, I wonder why Netbeans gives me an error.
You can add a comment to the top which will tell Netbeans to ignore the error.
For example when using angular
/* global angular */
Will prevent the error for things like
angular.module('Module', []);
I am using NetBeans IDE 8.2 (Build 201705191307)
If you want to completely ignore this type of error, I would suggest this:
Tools > Options > Editor > Hints > Uncheck "The global variable is not declared"
It worked for me.
Related
When setting a breakpoint on the console.log statement, why would this be undefined in the debugger but the statement print with no issues? Am I missing something in regards to scope here?
export class OptionsSidebarComponent {
...
public filters: Object = new Object();
...
public generateFilters() {
for (let property in this.terms) {
if (this.terms.hasOwnProperty(property) && this.terms[property] !== null) {
if (!this.filters.hasOwnProperty(this.productGroup.id)){
this.filters[this.productGroup.id] = new Filters();
}
this.terms[property].forEach((term) => {
console.log(this.filters);
});
}
}
}
}
With typescript While debugging, keep in mind that transpilers can rename variables. Using the original name in the console without sourcemaps that include renaming will show you undefined even if the original value isn't. Make sure you use the transpiled name in watches or console commands.
When you're referencing this with your console.log statement inside its own class, you're using it in its relevant scope. Depending on the framework you are using, different terms are used to reference your class... AngularJS used $scope- Angular 2+ uses this to reference the current class (or current scope/context).
When you use this in your debugger you're using it outside of its scope. It no longer references the class you intend it to.
Each one of your components in Angular uses this to reference itself. Here's an article to explain in further detail: https://angular-2-training-book.rangle.io/handout/features/refresher_on_this.html
If we simplify it to basic javascript and look at your class as just a function a good example would be this:
function example(){
var anything = 10;
console.log(anything); //output: 10
}
console.log(anything); //undefined! we're out of scope :)
So looking at it from this perspective, this is nothing magical. It's just provided to us by Angular to make our references to other things inside our components easier.
Situation: using functions to declare your Classes
If you are using and declaring classes with some custom (or framework function) as WinJs does (check their open source git directory), you are certainly familiar with this kind of code:
function define(constructor, instanceMembers, staticMembers) { }
function derive(baseClass, constructor, instanceMembers, staticMembers) { }
define(function constructor(){
this.yourProperty = 1;
}, {
// Prototype object
somePrototypeFunction: function(){
// When you type "this." here, it will not show up "yourProperty" declared
// in the constructor, because you have not instanciated the class,
// intellisense does not know that everything is linked
}
}
Common problem on these "custom" functions
Intellisense does not show up the values declared within the constructor when you try to reach them from the prototype functions.
I found something that have helped me: http://social.msdn.microsoft.com/forums/windowsapps/en-US/3eee400a-fefd-4f5e-9109-68df03fef006/javascript-intellisense-with-this-inside-gettersetter
This leaded me to the solution that I share to you below, it was a pain to make it work, and actually I was about to ** AGAIN ** let go with that problem which was something really disapointing especially with big team projects.
I find it weird that there are not many complaints about this on the web, maybe it's a configuration problem? However I had that problem on all VSD installations I saw.
So I hope the following solution will help you too if you run into the same situation.
After a few hours I finally have a solution which is not perfect (I have handled .base like in C# in my javascript library, but with the following code I can't say to intellisense that this ".base(...) " exists in the context of the prototype functions and constructor). If you have any tip on how to do that let me know, I'm interested.
Tested on Visual Studio 2013.
Simply change window.define / window.derive to the namespace and name you actually use (for WinJs it would be WinJS.Class.define and WinJS.Class.derive).
Add in _references.js the relative path of the file where you will put the following code, just after your library
And that's all! You'll have intellisense inside your
(function (window) {
"use strict";
/*
* Goal: make intellisense understand that the constructor of your define/derive functions are linked to the prototype object you have supplied.
* Tested on WinJs library and other custom libraries.
* Save this in a file, and reference it only in _references.js, insert it after your library containing the define/derive functions
*/
function initIntellisenseFor(constructor, baseClass) {
var inst = new constructor();
// Force intellisense to run function
for (var key in inst) {
if (typeof inst[key] == 'function') {
try {
inst[key]();
} catch (e) {
// Silent fail if wrong arguments (not sure if needed)
}
}
}
// Force intellisense to discover constructor
inst.constructor = constructor;
// Missing: .base() implementation for each method with redirection to the appropriate parent class method
}
var oldDefine = window.define;
window.define = function (constructor, instanceMembers, staticMembers) {
var result = oldDefine.call(this, constructor, instanceMembers, staticMembers);
initIntellisenseFor(result);
return result;
};
var oldDerive = window.derive;
window.derive = function (baseClass, constructor, instanceMembers, staticMembers) {
var result = oldDerive.call(this, baseClass, constructor, instanceMembers, staticMembers);
initIntellisenseFor(result, baseClass);
return result;
};
})(this);
I am integrating Emberjs and jquery ui. using the methods mentioned in http://www.lukemelia.com/blog/archives/2012/03/10/using-ember-js-with-jquery-ui/
Everything thing seems to be working ok.
The problem is following:
When I have
JQ = {};
to declare a new namespace I faced with this error (although it works fine on the browser)
JQ is not defined
when I declare the same variable as
var JQ = {};
Grunt shows no errors but it stops working in the browser.
I looked into the combined code in the browsers it is like the following
function(){
var JQ = {};
}
....rest of the code
so I am sure it is declared but the browser don't mange to see it.
So I can't find out the problem? nor the solution
Best,
Mohammad
if you want to make JQ global..declare it as window.JQ = {}
i think issue may be just linting....add JQ to the globals...
In orderto make sure jshint doesnt throw error..add JQ to the global list in .jshintrc file
When you use var JQ = {}; and the result is
function(){
var JQ = {};
}
your variable is defined only in the scope of that function, which means that you can't use it outside of that closure. So, when you use JQ = {}; your compiled file should contain:
function(){
JQ = {};
}
which defines the variable in the global namespace. But you said that you got JQ is not defined, so I could suggest to check if you don't use the variable before its definition.
If the variable foo is undefined, normally I can do things like:
!foo;
foo === undefined;
foo !== 'some value';
However, the code base that I am working on now has something in it that seems to instruct the browser's interpreter to throw an exception for any operation on an undefined variable other than this:
typeof foo !="undefined";
I'm working in the same browsers that I normally work in (Chrome and Firefox). But I'm coming on to this project in the middle this time instead of starting from scratch. It is a dJango project using Backbone.js, underscore, handlebars, jQuery, yepnope.
Could this behavior be due to the instruction "use strict" appearing somewhere in the global namespace? I did a search in the project for the text string "use strict" and found it in some code that seems to come from twitter:
Files: bootstrap.js
script.js
From: http://twitter.github.com/bootstrap/javascript.html#transitions
I also found it in the json2 file. However I'm pretty sure this file didn't cause me problems last time I worked with it:
File: json2.js
From: http://www.JSON.org/json2.js
For all I know, this isn't even caused by the inclusion of "use strict" somewhere...
Any ideas?
Thanks so much!
When a variable is undeclared, you cannot use it in comparisons.
undeclaredvar = 1;
is the only thing that works: undeclaredvar is implicitly declared in the global namespace.
Strict mode declarations inside a function will never "leak" the strictness to the global scope. So, "use strict"; in Twitter bootstrap / JSON2 won't affect the strictness of your script.
There's an important difference between undefined and undeclared.
function test() {
var foo;
if (foo) { /* not executed */ }
}
This is fine because foo is declared, but its value is undefined.
function test() {
if (foo) { /* exception! */ }
}
This will throw an exception (ReferenceError) because foo is not declared. (Unless there is a window.foo.)
Playing a little with coffeescript and Rails 3.1.0.rc4. Have this code:
yourMom = (location) ->
console.log location
yourMom "wuz hur"
When the page loads, this outputs "wuz hur" properly. But when I try to call
yourMom("wuz hur")
from the chrome js console (as I do sometimes to test normal JS functions), I get a "ReferenceError: yourMom is not defined"
Are functions generated by coffeescript available in this way?
an easier way to share global methods/variables is to use # which means this.
#yourMom = (location) ->
console.log location
yourMom "wuz hur"
Nicer syntax and easier to read, but I don't encourage you to create global methods/variables
This happens because coffeescript wraps everything in a closure. The JavaScript output of that code is actually:
(function() {
var yourMom;
yourMom = function(location) {
return console.log(location);
};
yourMom("wuz hur");
}).call(this);
If you want to export it to the global scope, you can either do:
window.yourMom = yourMom = (location) ->
console.log location
or
this.yourMom = yourMom = (location) ->
console.log location
I'm not sure about Rails but the CoffeeScript compiler has an option (--bare) to compile without the function wrapper. Fine for playing but it does pollute the global scope.
this link might solve your problem
Rails - Calling CoffeeScript from JavaScript
Wrap your functions in a unique namespace and then you can acess these functions from wnywhere