I'd like to "use strict"; mode in javascript but have some problems with strict warnings.
I have a "widget", e.g.:
var Widget = function () { /* ... */ }
Before I was using it like this (inside a module):
(function () {
var w1 = new Widget();
}());
when I add "use strict"; to this context I get a warning that "Widget" is not defined:
(function () {
"use strict";
var w1 = new Widget(); // <- warning here
}());
What is the proper way of doing this?
Should I define my "widgets" differently?
In strict mode you can't accidentally create global variables. Trying to do so will throw a reference error, as you've noticed. Hence you need to name an object, which has Widget assigned:
window.Widget = function () { /* ... */ }
(function () {
"use strict";
var w1 = new window.Widget();
}());
More info: MDN , www.nczonline.net
Related
I have a module with a lot of JS code in it. Module is created like so:
(function (root, factory) {
// root === window
root.MyModuleName = factory();
})(this, function () {
'use strict';
var MyModuleName = function() {
// A lot of code here that I don't want to be parsed or evaluated
// until MyModuleName constructor is executed.
//
// For example:
// var a = { d: 123 };
// var b = function() { return 45; };
// this.someMethod = function() { b() + a.d };
// ...
};
return MyModuleName;
});
All methods & properties are inside MyModuleName closure and (I thought) they should be parsed only after MyModuleName() is executed.
After user clicks on some button I create an instance of MyModuleName and execute some method:
someButton.onclick = function() {
// I want compiler to parse and evaluate JS code only here
var myModule = new MyModuleName();
console.log(myModule.someMethod());
};
Even though MyModuleName constructor is executed() only after click, code inside it is evaluated when JS file loads (I can see it in Chrome dev tools timeline).
How to make sure compiler evaluates code only after click, not after JS file loads?
You can't. The JS engine has to evaluate the code to create the function before it can assign the function anywhere.
How can I set and access a global var in a prototype way?
var app;
(function(){
"use strict";
var App = function() {
};
App = App;
}(window));
$(function() {
app = new App();
});
When you're using strict mode, the value of this inside the IIFE isn't window, it's probably undefined, so App isn't really global.
If you explicitly make it global it should work
var app;
(function (w) {
"use strict";
w.App = function () {
};
}(window));
$(function () {
app = new App();
});
FIDDLE
If you weren't using strict mode, you could just remove the var keyword
I am trying to call a function from outside which is defined with in a window object, but it throws an error.
window.vcm = (function() {
"use strict";
function red(){
alert('red');
}
});
vcm.red();//Error at this line...
I am new to OOPS in javascript. Can somebody tell me how to call this function here.
The value that is vcm does not have a red property.
Perhaps you mean this instead, wherein vcm is an object that has a property red that is function you can call:
window.vcm = {
red: function(){
"use strict";
alert('red');
}
};
It's also a possibility (albeit not somewhat you 'd see in practice) for vcm itself to be a function and for it to have a red property that is a function:
window.vcm = (function() {
"use strict";
var vcm = function() { alert("vcm"); }
vcm.red = function() { alert('vcm.red'); };
return vcm;
})();
vcm(); // "vcm"
vcm.red(); // "vcm.red"
There are two approaches.
Approach 1 :
window.vcm = {
red: function (){
"use strict";
alert('red');
}
};
vcm.red();
Approach 2 :
window.vcm = (function() {
"use strict";
this.red = function(){
alert('red');
}
});
var x = new vcm();
x.red();
red only exist inside the function you assigned to window.vcm and also only when the function is executed. Furthermore, functions don't have a property red.
Consider this simpler example:
function foo() {
function bar() {}
}
bar(); // will throw an error
Calling bar will throw an error because bar is not defined in the scope where it is called.
It seems you want to assign an object to window.vcm, which has a property red:
window.vcm = {
red: function (){
"use strict";
alert('red');
}
};
Here I am using an object literal to create an object with the property red.
More information:
MDN - Working with objects
Let's say we have this script.
var apple = {
type: "macintosh",
color: "red",
getInfo: function () {
return this.color + ' ' + this.type + ' apple';
}
///more functions here....
}
How can I let all these functions run in strict mode? I can put "use strict" at the top of the file but JSlint does not approve this. An alternative is to put "use strict" in every function, but is there a better option?
Wrap everything inside an IIFE and JSLint should approve.
(function () {
"use strict";
//all your code here
}());
Note that variables/functions previously declared in the global scope would no longer be accessible in the global scope when moved to inside this immediately-invoked function expression.
You will have to explicitly set these as properties of the global object, e.g. the window object for browser environment:
(function () {
"use strict";
window.someGlobalVariable = "something";
}());
#zzzzBov's solution also works nicely on both browser and back-end environments.
Wrap everything in an IIFE, alias the global reference, and explicitly set global variables on the global object:
(function (root) { //could be window (browser), could be global (node)
"use strict";
...code...
root.apple = apple; //explicitly make apple a global variable
}(this));
If you are using namespaces for your object literals, I like this approach best:
(function (myApp) {
'use strict';
myApp.myObj = {
init: function(){}
}
}(window.myApp = window.myApp || {}));
myApp.myObj.init();
I have the following function
var myInstance = (function() {
var privateVar = 'Test';
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// all private members are accesible here
alert(privateVar);
},
publicMethod2: function () {
}
};
})();
what's the difference if I add a new to the function. From firebug, it seems two objects are the same. And as I understand, both should enforce the singleton pattern.
var myInstance = new (function() {
var privateVar = 'Test';
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// all private members are accesible here
alert(privateVar);
},
publicMethod2: function () {
}
};
})();
While the end result seems identical, how it got there and what it executed in is different.
The first version executes the anonymous function with this being in the context of the window object. The second version executes the anonymous function, but this is in the context of a new empty object.
In the end, they both return another object(your Singleton). It's just a slight difference in execution context.
To test this out, but an alert(this); right before the declaration of the privateVar variable.
#Tom Squires: That's not necessarily true and is poor practice not to declare your variables. A script with the "use strict"; directive does cause the JS engine to complain (assuming that the engine supports "use strict";