Javascript: Creating global scope functions from inside an class - javascript

I am creating a "class" in Javascript that will handle several HTML5 features (such as video playback).
This Javascript class also generates a Flash fallback in case those HTML5 features arent present in the browser.
The Flash fall back files communicate with the Javascript by calling global functions.
My question is:
How can I get the Javascript class to generate the necessary functions?
To my knowledge using a variable without defining it first using var will make that variable global - but this feels hacky and will certainly fail on strict mode.
The class itself could be bound to any variable, so trying to access functions inside the class without first knowing those variable is going to be problematic. Also I want this code to be as portable as possible.

EDIT: as mentionned by mccainz in the comments it's usually a better idea to use a namespace
You can use window to define global functions without bothering strict mode:
function MyClass() {
// your constructor
window.globalFunctions = window.globalFunctions || {};
}
MyClass.prototype.createGlobalFunctionFoo = function () {
window.globalFunctions.foo = function () {
// your code
};
};
var myInstance = new MyClass();
myInstance.createGlobalFunctionFoo();
console.log(globalFunctions.foo); // your function
Of course you would need to do some checking to make sure you are not rewriting an existing function or some other edge cases, I just gave a straight answer.

Related

Does declaring methods like alert() override the built-in alert() method in Javascript?

I was experimenting to define the built-in method alert() to see what kind of error the console will throw, but instead the built-in alert() got overridden.
This is the code -
function alert(some_string) {
console.log(some_string+some_string);
}
function say() {
alert("Hello");
}
say();
The output is : HelloHello
Coming from a Java background, it would throw a compile error as :
error: method alert() is already defined
So what happened here? Did I actually override the method?
Overriding is a classical OO term which means that a child class has method with the same name as one of the classes it inherits from which is used instead of that method on the child class.
In this case, you are straight up taking the alert variable (which by default has a value of a function provided by the browser) and assigning it a new value (the function you just declared).
(That assumes you are working in the global scope. If you were in a local scope you would just be masking the variable so you would only be making alert inaccessible to other code in the same scope … and since you were writing that code too, it wouldn't be a problem because you would know if you needed the global alert and could avoid reusing its name.)
There might be hundreds of built-in functions and I might accidentally define a function with a same name as one of them, how can I check if such accidents don't happen?
There are two basic techniques for this.
Avoid creating globals
When you create a new variable, do it in as narrow a scope as possible. A common pattern is to use an IIFE to create a new scope for all the variables related to a given piece of code.
(function () {
"use strict";
function alert() {
// Locally scoped alert that doesn't get in the way
// of any variable called `alert` from the browser
// or another library
}
})();
Use namespaces
This is just a term for having a single global as the entry point to a bunch of related code. It is usually given an ALL_CAPS name that is unlikely to conflict with other code.
This allows the functions to be accessed from anywhere, like globals, without creating lots of global variables.
var MYLIBRARY;
(function () {
"use strict";
MYLIBRARY = {
alert: alert
};
function alert() { /* etc */ }
})();

What is difference between function FunctionName(){} and object.FunctionName = function(){}

Today while working my mind was stack at some point in javascript.
I want to know that what is basic difference between
function FunctionName(){
//Code goes here;
}
And
var MyFuncCollection = new Object();
MyFuncCollection.FunctionName = function(){
//Code goes here;
}
Both are working same. Then what is difference between then. Is there any advantage to use function with object name?
I have read Question. But it uses variable and assign function specific variable. I want to create object and assign multiple function in single object.
The first one defines a global function name. If you load two libraries, and they both try to define FunctionName, they'll conflict with each other. You'll only get the one that was defined last.
The second one just has a single global variable, MyFuncCollection. All the functions are defined as properties within that variable. So if you have two collections that try to define the same function name, one will be FuncCollection1.FunctionName, the other will be FuncCollection2.FunctionName, and there won't be any conflict.
The only conflict would be if two collections both tried to use the same name for the collection itself, which is less likely. But this isn't totally unheard of: there are a few libraries that try to use $ as their main identifier. jQuery is the most prominent, and it provides jQuery.noConflict() to remove its $ binding and revert to the previous binding.
The short answer is, the method in object context uses the Parent Objects Context, while the "global" function has its own object context.
The long answer involves the general object-oriented approach of JavaScript, though everything in JavaScript is an object you may also create arrays with this Method.
I can't really tell you why, but in my experience the best function definition is neither of the top mentioned, but:
var myFunction = function(){};
It is possible to assign function to variables, and you may even write a definition like this:
MyObject.myMethod = function(){};
For further reading there are various online Textbooks which can give you more and deeper Information about this topic.
One main advantage I always find is cleaner code with less chance of overwriting functions. However it is much more than that.
Your scope changes completely inside the object. Consider the following code ::
Function:
function FunctionName(){
return this;
}
FunctionName()
Returns:
Window {top: Window, location: Location, document: document, window: Window, external: Object…}
Object:
var MyFuncCollection = new Object();
MyFuncCollection.FunctionName = function(){
return this;
}
MyFuncCollection.FunctionName()
Returns:
Object {}
This leads to some nice ability to daisy chain functions, amongst other things.
The first:
function functionName (){
//Code goes here;
}
Is a function declaration. It defines a function object in the context it's written in.
Notice: this doesn't have to be the global context and it doesn't say anything about the value of this inside it when it's invoked. More about scopes in JavaScript.
Second note: in most style guides functions are declared with a capitalized name only if it's a constructor.
The second:
var myFuncCollection = {};
myFuncCollection.functionName = function () {
//Code goes here;
};
notice: don't use the new Object() syntax, it's considered bad practice to use new with anything other then function constructors. Use the literal form instead (as above).
Is a simple assignment of a function expression to a property of an Object.
Again the same notice should be stated: this says nothing about the value of this when it's invoked.
this in JavaScript is given a value when the function object is invoked, see here for details.
Of course, placing a function on an Object help avoiding naming collisions with other variables/function declarations in the same context, but this could be a local context of a function, and not necessarily the global context.
Other then these differences, from the language point of view, there's no difference whatsoever about using a bunch of function declarations or an Object with bunch of methods on it.
From a design point of view, putting methods on an Object allows you to group and/or encapsulate logic to a specific object that should contain it. This is the part of the meaning of the Object Oriented Programming paradigm.
It's also good to do that when you wish to export or simply pass all these functions to another separate module.
And that's about it (:

Better way to access variables across prototype methods in JavaScript?

I often use the pattern of a main JavaScript constructor function and adding methods to its prototype object so they can be called intuitively by the user, for example:
function Slideshow(options) {
this.options = options
this.slideshow = $('#slideshow')
//more variables here
}
Slideshow.method1 = function () {
this.slideshow.addClass('test') // do something with slideshow variable
};
Slideshow.method2 = function () {
// another method
};
The one thing that really bugs me about this pattern is how in order to make variables accessible across all prototype methods, I have to add "this" in front of each variable inside the constructor function. It's a major pain, and I can't help but think there's a more elegant way to do this.
If I forgo using the prototype object and just add the methods as instance methods, I know I can't get around this problem, but I like the efficiency? and self encapsulating nature of this pattern. Any other suggestions for a better pattern? Thanks!
It's a major pain
No, it's really not. Every single JavaScript developer uses this syntax. If you were in Ruby or Python, you'd use self., in PHP you'd use $this->. Some languages like C++ don't require any special decorator, but JavaScript does.
and I can't help but think there's a more elegant way to do this.
No, there isn't.
This is JavaScript's syntax, you cannot change it, and you cannot work around it. If you want to access a property of this, you need this. before the property name. Otherwise, you're talking about global variables.
If you want a different syntax, consider a different language like CoffeeScript, which compiles to JavaScript.
meager has pretty much summed things up if you're talking about accessing public instance properties or methods. You have to use this in front of it as that's just how the language works.
But, if you have private instance properties or methods, you can define those as local variables inside the constructor and you can access them without this.
function slideshow(options) {
// no need to resave the options arguments as they can be used
// directly from the argument variable
// define a per-instance private variable that other methods defined
// within the constructor can use directly without the use of `this`
var theShow = $(options.selector || '#slideshow');
// define public methods
this.method1 = function() {
// can access private instance variable here without this in front of it
theShow.addClass('test');
}
this.method2 = function() {
theShow.addClass(options.decoaration);
}
}
This general design pattern is described here: http://javascript.crockford.com/private.html
Practically speaking, this works because the constructor function with the public methods declared inside it creates a closure that lasts for the duration of the object lifetime so the local variables in the constructor become per-instance variables accessible only from the functions declared within the constructor.

Expose an object's member functions as global functions

For example I have:
var n = {
abc: function() { print("abc"); },
def: function() { print("def"); },
};
Is there a way to export abc and def as global functions, so that I can call abc() directly rather than n.abc()?
My context for this is using Rhino/Nashorn script engine, and I'd like to inject a "global" object that provides global functions.
The answers for Rhino and Nashorn would be different.
For Rhino, when you create the global object using Context.initStandardObjects, you can then add your properties on the Java side by calling ScriptableObject.defineProperty (see Rhino API) and then the properties will be added to that global scope. If you need a property of type function as your example shows, create it using the FunctionObject API.
For Nashorn, you can use the interfaces mostly based on the standard javax.script APIs, with a couple of Nashorn-specific extensions. When evaluating your script, first use ScriptEngine.createBindings() to create a Bindings object, then use Bindings.put to use eval(String/Reader,Bindings)
If you need a function property, then on the Java side call ScriptUtils.wrap to create a ScriptObjectMirror (make sure to cast it to that; return type of the method is Object), then call get([function name]) to get an executable function property, then put that in the global scope.
All of that said, it seems to me that this is more easily handled on the script side using:
var abc = function() { return n.abc.apply(n,arguments); };
That's portable across Rhino/Nashorn and is one line, which is a lot less work than what you're going to do if you want to avoid writing that one line.
If you execute that in the global scope, you don't need a qualifier; it'll be added to the top-level object as a property. If you want to be more explicit you can do something like this:
(function() {
var global = this; // inner functions called without target default to global as 'this'
this.abc = function() { return n.abc.apply(n,arguments); };
})();
... which will work unless you start doing stuff that's a lot fancier (like messing around with 'this' values when loading scripts).
Why don't you just use JavaScript's bind, call and apply methods to call the object's member functions when you need to invoke them? Making them global indicates code smell.

JavaScript: global scope

Nowdays, i create a .js file with a lot of functions and then I link it to my html pages. That's working but I want to know what's the best way (good practices) to insert js in my pages and avoid conflicts with scope...
Thank you.
You could wrap them in an anonymous function like:
(function(){ /* */ })();
However, if you need to re-use all of the javascript functions you've written elsewhere (in other scripts), you're better off creating a single global object on which they can be accessed. Either like:
var mySingleGlobalObject={};
mySingleGlobalObject.someVariable='a string value';
mySingleGlobalObject.someMethod=function(par1, par2){ /* */ };
or the alternative, shorter syntax (which does the same thing):
var mySingleGlobalObject={
someVariable:'a string value',
someMethod:function(par1, par2){ /* */ }
};
This can then be accessed later from other scripts like:
mySingleGlobalObject.someMethod('jack', 'jill');
A simple idea is to use one object that represents your namespace:
var NameSpace = {
Person : function(name, age) {
}
};
var jim= new NameSpace.Person("Jim", 30);
The best way is to create a new scope and execute your code there.
(function(){
//code here
})();
This is best used when the global scope is accessed at a minimum.
Basically, this defines an anonymous function, gives it a new scope, and calls it.
It's perhaps not the BEST way, but a lot of PHP systems (I'm looking at you, Drupal) take the name of their particular plugin and prepend it to all their function names. You could do something similar, adding the name of your capability to your function names - "mything_do_action()"
Alternately, you could take a more "OO" approach, and create an object that encapsulates your capability, and add all your functions as member functions on IT. That way, there's only one thing in global scope to worry about.

Categories