Javascript Namespaces and undefined function - javascript

Can someone explain how to do this properly
foo(); //outputs 'foo'
function foo(){
console.log('foo');
}
but this gives 'function is undefined' error
MY_NAME_SPACE ={};
MY_NAME_SPACE.foo(); //undefined
MY_NAME_SPACE.foo = function(){
console.log('foo');
}
I can see that in the second example, the call was made before the function was added to the My_NAME_SPACE object, but if this is the case,how would one use this type of "name space" if the ordering is important?

Yes, if you are going to use this namespace pattern, you will need to create and populate the namespace before trying to invoke methods or access property values that have not yet been assigned to the namespace.
Instead of defining the namespace object and then defining each consecutive method in the namespace, eg:
var MY_NAME_SPACE = {};
MY_NAME_SPACE.foo = function() {
console.log('foo');
}
I prefer to use what is referred to as the module pattern, as the methods that I want contained in MY_NAME_SPACE are visually wrapped in the module:
var MY_NAME_SPACE = (function () {
var foo = function () {
console.log('foo');
};
return { foo: foo };
})();
MY_NAME_SPACE.foo()
Also, if the methods you wish to wrap in a namespace or module are independent and reusable, it would makes sense to create a separate file, maybe my_name_space.js, and include this file in projects that need access to the methods in MY_NAME_SPACE (the MY_NAME_SPACE API).

Related

Entire JS inside one global variable?

I've got a school assignment of creating an app and one of the restrictions were that only one global variable was allowed, named "App". So I need to put the whole JS inside this variable.
I thought of doing something like:
App = function() { this.test = () => alert("test"); }
And then calling it with App.test().
But this doesn't work, the error I'm getting is:
Uncaught TypeError: App.test is not a function at HTMLLIElement.onclick (index.html:25)
Am I doing something wrong?
You need to define your app in a variable as an object and then you can use those members of the object such as:
// Object creation
window.App = {};
Then you add more properties like functions or variables and use it later inside of that variable.
window.App.test = function() {
alert('test');
}
window.App.variable = 'my variable';
console.log( App.test() );
console.log( App.variable );
Another thing is you can omit the word window from App.
Keeping most of your approach as it is, you could return an object that has functions as properties.
App = function() {
return {
test: () => alert("test"),
test2: () => alert("test2")
};
}
App().test();
App().test2();
To be able to use your function that contains this.test..., you'll need to use it as a "constructor function" because this in a function declaration means "instance property", meaning you will need to explicitly create an instance of App with the new keyword:
// Declare the global
var App = function() { this.test = () => alert("test"); }
// Make an instance of an object via the constructor function
var myApp = new App();
// Invoke the functionality via the instance
myApp.test()
Or, set up App as an object, connect that object to the Global window object and set test as a property of App all without any instance properties (this references), which avoids having to make the explicit instance:
// Declare the global property as an Object
// and set up a "test" property that stores
// a function in that object:
window.App = { test: function(){alert("test");}}
// Invoke the functionality directly
App.test()
The test function is not defined before executing the App function:
App = () => test = () => alert("test")
<button onclick='App(); test()'>:</button>
App can be defined as object instead:
App = { test: () => alert("test") }
<button onclick='App.test()'>:</button>
Just to piggyback on to what the other answers have suggested, this technique is most commonly used (in browser developement) when you "namespace" some JS code. Namespacing is useful because it helps the developer reduce global variable pollution by adding all their code under one namespace under window.
This also helps the developer modularise the code.
Here's a pattern you might see from time to time that adds code to a single namespace under window.
// This first function is what's known as an Immediately-invoked
// function expression (IIFE). `window` is passed in as an argument
// to the function - all other declared variables are local to the scope
// of the function so you don't get anything leaking to global.
// PS, the semi-colon is there before the opening parenthesis to prevent
// any errors appearing if you minimise your code
;(function (window) {
// Here we declare something new to add to the namespace
// It could be another object, a string, an array, or a constructor
// like Model
function Model() {...}
// If namespace `window.app` doesn't exist instantiate it with
// an empty object. If it _does_ exist it probably means that another
// module like this one has already been added to the namespace.
window.app = window.app || {};
// Then assign your new module as a property under that namespace
window.app.Model = Model;
})(window);
You can then use it later something like this:
var model = new app.Model();
var game = new Game(model);
For further reading: Addy Osmani on namespacing.

How do I get the name of a JavaScript class/instance method from inside the method?

I am trying to get the name of a JavaScript instance or class method (in client-side/browser JS) while using the following OOP style for AMD modules (for usage with RequireJS):
define([...], function(...) {
var FooBar = function() {
//Constructor code...
};
FooBar.foo = function() {
//This is a FooBar class method named "foo". How do I get its name from here?
//...
};
FooBar.prototype.bar = function() {
//This is a FooBar instance method named "bar". How do I get its name from here?
//...
};
});
I have seen various posts explaining how to do it in case of named functions, e.g., function foobar() {...}, but not in case of assigned anonymous functions, e.g., foobar = function() {...}.
The latter is relevant here, unless the above can be rewritten using named functions instead.
I would rather not revert to some naming-scheme convention such as foobar = function foobar_extra_name() {...}, since this involves naming a function twice. Furthermore, even if this were possible, it would still not be possible to do something like FooBar.prototype.bar = function FooBar.prototype.bar() {...} because of the dot notation, so it wouldn't be of much help.
Any thoughts about this? Any help is greatly appreciated.
You can indeed rewrite your code using named functions as it follows:
var FooBar = function FooBar() {
//Constructor code...
};
FooBar.foo = function foo() {
//This is a FooBar class method named "foo". How do I get its name from here?
//...
};
FooBar.prototype.bar = function bar() {
//This is a FooBar instance method named "bar". How do I get its name from here?
//...
};

How to use Object literal as requirejs module?

I am trying to get my head around the javascript AMD pattern using requireJS. I'm very new to object oriented programming and also new to requireJS. I'd hope some one can help me here.
I defined a test module called 'module3' with object literal:
define([], function () {
var _name = 'this is a test3';
var returnedModule3={
name:'test',
getName:getName
}
function getName() {
return _name;
}
return returnedModule3;
});
However in the main.js file when I call this module after the file is loaded, I get an error in firebug saying "TypeError: module3ref is not a constructor". Below you will see the code in my main file:
// Load modules and use them
require(['myModule/module3'], function(module3ref){
// do something with the loaded modules
var module3 = new module3ref();
console.log("module3.getName:"+module3.getName());
});
Does this mean we cannot use object literal to create module?
Interpreting your question's title literally: RequireJS can turn object literals directly into AMD modules, e.g.:
define({
getName: function() {
return 'this is a test3';
},
name: 'test'
})
However, with this pattern it's not possible for one property to refer to its "neighbours" (but that's a limitation of JS object literal syntax, not RequireJS itself).
I have tried on my side. Try this:
define([], function () {
var _name = 'this is a test3';
var returnedModule3 = function(){
this.name = 'test';
this.getName = getName
}
function getName() {
return _name;
}
return returnedModule3;
});
Note: this should be attached to each property within returnedModule3 so as to be accessed from outside/other JS file otherwise it become private to function and you will get error object has no method getName.
Issue with your code: In your code, you were trying to create an instance of object.
Another Approach (EXPORTING OBJECT) :
If you want to export Object as it is like your returnedModule3 then must define main.js as:
require(['module3'], function(module3ref){
// do something with the loaded modules
console.log("module3.getName:"+module3ref.getName());
});

My own mini-framework is not compatible with some projects

I failed to create a mini-library with some useful functions that I have found over the Internet, and I want to use them easily by just including a file to the HTML (like jQuery).
The problem is that some vars and functions share the same name and they are causing problems.
Is there a better solution to this instead of giving crazy names to the vars/funcs like "bbbb123" so the odds that someone is working with a "bbbb123" var is really low?
I would put all of your functions and variables into a single object for your library.
var MyLibrary = {
myFunc: function() {
//do stuff
},
myVar: "Foo"
}
There are a few different ways of defining 'classes' in JavaScript. Here is a nice page with 3 of them.
You should take one variable name in the global namespace that there are low odds of being used, and put everything else underneath it (in its own namespace).
For example, if I wanted to call my library AzureLib:
AzureLib = {
SortSomething: function(arr) {
// do some sorting
},
DoSomethingCool: function(item) {
// do something cool
}
};
// usage (in another JavaScript file or in an HTML <script> tag):
AzureLib.SortSomething(myArray);
Yes, you can create an object as a namespace. There are several ways to do this, syntax-wise, but the end result is approximately the same. Your object name should be the thing that no one else will have used.
var MyLibrary = {
myFunc: function() { /* stuff */ }
};
Just remember, it's object literal syntax, so you use label : value to put things inside it, and not var label = value;.
If you need to declare things first, use a wrapping function to enclose the environment and protect you from the global scope:
var MyLibrary = (function() {
var foo = 'bar';
return {
myFunc: function() { /* stuff */ }
};
})(); // execute this function right away to return your library object
You could put all of your library's functions inside of a single object. That way, as long as that object's name doesn't conflict, you will be good. Something like:
var yourLib = {};
yourLib.usefulFunction1 = function(){
..
};
yourLib.usefulFunction2 = function(){
..
};

Javascript Prototype not Working

Hi I don't know whether this is my mistake in understanding Javascript prototype object ..
Well to be clear I'm new to the Javascript singleton concept and lack clear cut knowledge in that but going through some referral sites I made a sample code for my system but it's giving out some errors which I couldn't find why so I'm asking for your help. My code is:
referrelSystem = function(){
//Some code here
}();
Prototype function:
referrelSystem.prototype.postToFb = function(){
//Some Code here
};
I get an error saying prototype is undefined!
Excuse me i thought of this right now
EDIT
I have used like this:
referrelSystem = function(){
return{
login:getSignedIn,
initTwitter:initTw
}
};
Is this causing an issue?
A typical way to define a JavaScript class with prototypes would be:
function ReferrelSystem() {
// this is your constructor
// use this.foo = bar to assign properties
}
ReferrelSystem.prototype.postToFb = function () {
// this is a class method
};
You might have been confused with the self-executing function syntax (closures). That is used when you would like to have "private" members in your class. Anything you declare in this closure will only be visible within the closure itself:
var ReferrelSystem = (function () {
function doSomething() {
// this is a "private" function
// make sure you call it with doSomething.call(this)
// to be able to access class members
}
var cnt; // this is a "private" property
function RS() {
// this is your constructor
}
RS.prototype.postToFb = function () {
// this is a class method
};
return RS;
})();
I would recommend that you study common module patterns if you're looking into creating a library.
Update: Seeing your updated code, the return from referrelSystem won't work as expected, since return values are discarded when calling new referrelSystem().
Rather than returning an object, set those properties to this (the instance of referrelSystem that gets constructed):
var referrelSystem = function () {
// I assume you have other code here
this.login = getSignedIn;
this.initTwitter = initTw;
};
I don't think you intend to immediately execute the functions, change them to this:
var referrelSystem = function(){
//Some code here
};
(+var, -())
Same with the prototype function:
referrelSystem.prototype.postToFb = function(){
//Some Code here
};
(Here you don't need the var, because you're assigning to something that already exists.)
A function should return to work as
prototype
property.
Take a look at this example here

Categories