Getter functions - javascript

I've peeked into many plugins' code (for educational purposes) and basically every one of them (which deals with prototypes), has bunch of functions like this:
myMarker.prototype.getPosition = function() {
return this.latlng;
};
//OR
myMarker.prototype.getObject = function() {
return this;
};
What's the reason behind this?
Why not just to use someObject.latlng instead of someObject.getPosition()?

One common reason for doing this is to avoid coupling the object's internal data storage to the API; in this example you could change the way the position is stored internally, and then add some processing to getPosition() to return a backwards compatible result.
For example, version 1.1 of this library might look like this, and calling code wouldn't need to be changed:
myMarker.prototype.getPosition = function() {
return this.latitude + this.longitude;
};
It is possible to accomplish this using computed properties with ES5 get and set, but only if the code doesn't need to run on Internet Explorer 8 and below.

When you say like this.
myMarker.prototype.getPosition = function() {
return this.latlng;
};
You are defining function getPosition which available to all instance to class myMarker.
So,all object of this class share this method without replication.
For someObject.latlng,there is nothing wrong.
But assume, this object is accessible to all which are in the current scope.So,it can be modified/accessible to anyone.
When you go through prototype you are trying to define some pattern,which gives restriction for access and modification of property

Related

Can I call behaviors methods directly without eventproxy?

I'm searching for alternative ways to call a method defined in Marionette's behaviors from inside a view.
For sure there is the eventproxy but maybe it's more intuitive to call the method directly like:
view.behaviorsMethod();
I could assign it like:
view.method = behavior.method;
I could check for reassignment because it'll maybe lead to unexpected results for others:
view.method = (view.method !== undefined ? view.method : behavior.method);
But this doesn't seem to be an elegant way.
The answer to your question is you can not directly do so, but there is always a way.
you can do it using _.invoke(this._behaviors, 'yourMethodName') but I will discourage using it
since
_behaviors is a private variable of the Marionette.View class and it's name can be changed or it can be dropped in upcoming versions
You will have to set context for the method as _.invoke will not set
the context of the method to proper this.
if you can set the context properly then this will work for you.
as suggested by #ThePaxBisonica in comment
I will suggest you to go with a mixin pattern from which you can extend both your behavior and view and you will not have to set any context and do not have to worry about the _behavior private variable
as
var mixin = {
behaviorMethodWhichYouWantToCallFromView: function(){
alert("mixin method");
}
}
var behavior = mn.behavior.extend(_.extend(mixin, {
//actual behavior code remove the method as behavior will get it from mixin
}))
var view = mn.view.extend(_.extend(mixin, {
//actual view code remove the method as behavior will get it from mixin
}))
Hope it helps.
I know this is bit long approach.

Protecting a Global Javascript "API" Object

I currently have a Web Application that runs off a global Javascript-based API, and it is initialized like this:
var Api = {
someVar: "test",
someFunction: function() {
return "foo";
}
}
This API is shared across many "Widgets" that live in the Web Application, and they should all run off this single Api instance so they can pass data to each other.
AJAX is currently used to load these Widgets, for example in widgets/mywidget.html, and it's placed in, say, <div id='widget_<random number>'>...</div>
Certain other parts of the code may choose to add more functionality to Api, and it's currently done like this:
Api.myExtension = {
myNewFunction: function() {
return "bar";
}
}
However, some issues arise from this kind of usage:
Problem One: What if one Widget (these may be provided by third-parties) decides to hide some code within, and does something similar to Api = {}, destroying the global Api var everything lives on, and breaking the whole Application? Is it possible to protect this Api variable from being overwritten from outside? Only "extending" is allowed (adding new things), but "removing/changing" is not allowed. i.e.:
Api.foo = { test: "bar" } // allowed
Api.someVar = "changing the existing someVar"; // not allowed
The following code is located "inside" Api, for example:
var Api = {
Debug: {
Messages = new Array,
Write: function() {
Api.Debug.Messages.push("test"); // allowed
}
}
}
Api.Debug.Messages.push("test 2"); // not allowed
Probable Solutions I've Thought Of:
Suppose we simply use frames to resolve this issue. The Apis provided are now separate from each other. However, there's additional overhead when loading Api again and again if I have many Widgets running, and they can no longer communicate with the "Host" of the widgets (the page where frames reside in), for example, I may want to tell the host to show a notification: Api.Notify.Show("Test"), but it cannot do so because this Api is completely independent from other instances, and it cannot communicate with the "Host"
Using something like a "getter" and "setter" function for the Api to be read and written. I'm unsure on how to implement this, so any help on directions on how to implement this is welcome!
A mixture of 1/2?
There's no good way to prevent having a "third party" widget overwrite the a global variable. Generally it is the responsibility of whoever is putting together the final application to ensure that whatever JavaScripts they are using aren't littering the global namespace and conflicting. The best thing you can do in that direction is give your "Api" a nice, unique name.
What I think can help you a lot is something like the "revealing pattern", which would be a way of doing the "getters and setters" you mentioned, plus more if you needed it.
A simple, useless example would be like the following:
var Api = (function () {
// private variable
var myArray = [];
return {
addItem: function (newItem) {
myArray.push(newItem);
},
printItems: function () {
console.log("lots if items");
}
};
})();
Api.addItem("Hello, world");
Api.extensionValue = 5;
I think you should make a clear delineation of what is shared, or "singleton" data, and keep those items private, as with myArray in my example.
Make it a constant:
const Api = "hi";
Api = 0;
alert(Api); //"hi"
Take a look at
Object.freeze
More info here
Here is a code example from Mozilla's page:
var obj = {
prop: function (){},
foo: "bar"
};
// New properties may be added, existing properties may be changed or removed
obj.foo = "baz";
obj.lumpy = "woof";
delete obj.prop;
var o = Object.freeze(obj);
assert(Object.isFrozen(obj) === true);
// Now any changes will fail
obj.foo = "quux"; // silently does nothing
obj.quaxxor = "the friendly duck"; // silently doesn't add the property
// ...and in strict mode such attempts will throw TypeErrors
function fail(){
"use strict";
obj.foo = "sparky"; // throws a TypeError
delete obj.quaxxor; // throws a TypeError
obj.sparky = "arf"; // throws a TypeError
}
fail();
// Attempted changes through Object.defineProperty will also throw
Object.defineProperty(obj, "ohai", { value: 17 }); // throws a TypeError
Object.defineProperty(obj, "foo", { value: "eit" }); // throws a TypeError
However browser support is still partial
EDIT: see Kernel James's answer, it's more relevant to your question (freeze will protect the object, but not protect reassigning it. however const will) same issue with limited browser support though.
The only way (at least that I can think of) to protect your global variable is to prevent the Widgets from having a direct access to it. This can be achieved by using frames functions, as you suggested. You should create an object that contains all the functions that the Widgets should be able to use, and pass such to each Widget. For example:
var Api = {
widgetApi = {
someFunction: function(){
// ...
}
},
addWidget:function(){
var temp = this.widgetApi.constructor();
for(var key in this.widgetApi)
temp[key] = clone(this.widgetApi[key]);
return temp;
}
// Include other variables that Widgets can't use
}
This way, the Widgets could execute functions and communicate with the host or global variable Api. To set variables, the Widget would be editing its private object, rather than the global one. For every frame (that represents a Widget), you must initialize or create a copy of the widgetApi object, and probably store it inside an array, in such a way that an instance of a Widget is stored in the main Api object.
For example, given <iframe id="widget"></iframe>
You would do the following:
var widget = document.getElementById("widget");
widget.contentWindow.Api = Api.addWidget();
widget.contentWindow.parent = null;
widget.contentWindow.top = null;
Additionally, in every frame you would need to set the parent and top variables to null so that the Widgets wouldn't be able to access the data of the main frame. I haven't tested this method in a while, so there might be ways to get around setting those variables to null.

Overriding methods using Javascript module pattern

I've got a browser addon I've been maintaining for 5 years, and I'd like to share some common code between the Firefox and Chrome versions.
I decided to go with the Javascript Module Pattern, and I'm running into a problem with, for example, loading browser-specific preferences, saving data, and other browser-dependent stuff.
What I'd like to do is have the shared code reference virtual, overrideable methods that could be implemented in the derived, browser-specific submodules.
Here's a quick example of what I've got so far, that I've tried in the Firebug console, using the Tight Augmentation method from the article I referenced:
var core = (function(core)
{
// PRIVATE METHODS
var over = function(){ return "core"; };
var foo = function() {
console.log(over());
};
// PUBLIC METHODS
core.over = over;
core.foo = foo;
return core;
}(core = core || {}));
var ff_specific = (function(base)
{
var old_over = base.over;
base.over = function() { return "ff_specific"; };
return base;
}(core));
core.foo();
ff_specific.foo();
Unfortunately, both calls to foo() seem to print "core", so I think I've got a fundamental misunderstanding of something.
Essentially, I'm wanting to be able to call:
get_preference(key)
set_preference(key, value)
load_data(key)
save_data(key, value)
and have each browser do their own thing. Is this possible? Is there a better way to do it?
In javascript functions have "lexical scope". This means that functions create their environment - scope when they are defined, not when they are executed. That's why you can't substitute "over" function later:
var over = function(){ return "core"; };
var foo = function() {
console.log(over());
};
//this closure over "over" function cannot be changed later
Furthermore you are "saying" that "over" should be private method of "core" and "ff_specific" should somehow extend "core" and change it (in this case the private method which is not intended to be overridden by design)
you never override your call to foo in the ff_specific code, and it refers directly to the private function over() (which never gets overridden), not to the function core.over() (which does).
The way to solve it based on your use case is to change the call to over() to be a call to core.over().
That said, you're really confusing yourself by reusing the names of things so much, imo. Maybe that's just for the example code. I'm also not convinced that you need to pass in core to the base function (just to the children).
Thanks for your help. I'd forgotten I couldn't reassign closures after they were defined. I did figure out a solution.
Part of the problem was just blindly following the example code from the article, which meant that the anonymous function to build the module was being called immediately (the reusing of names Paul mentioned). Not being able to reassign closures, even ones that I specifically made public, meant I couldn't even later pass it an object that would have its own methods, then check for them.
Here's what I wound up doing, and appears to work very well:
var ff_prefs = (function(ff_prefs)
{
ff_prefs.foo = function() { return "ff_prefs browser specific"; };
return ff_prefs;
}({}));
var chrome_prefs = (function(chrome_prefs)
{
chrome_prefs.foo = function() { return "chrome_prefs browser specific"; };
return chrome_prefs;
}({}));
var test_module = function(extern)
{
var test_module = {};
var talk = function() {
if(extern.foo)
{
console.log(extern.foo());
}
else
{
console.log("No external function!");
}
};
test_module.talk = talk;
return test_module;
};
var test_module_ff = new test_module(ff_prefs);
var test_module_chrome = new test_module(chrome_prefs);
var test_module_none = new test_module({});
test_module_ff.talk();
test_module_chrome.talk();
test_module_none.talk();
Before, it was running itself, then when the extension started, it would call an init() function, which it can still do. It's just no longer an anonymous function.

How can I create a selector like how jQuery has jQuery() or $()?

I have been creating my own library for a custom layout script. For ease of use, I am trying to emulate how jQuery exposes its library through the jQuery() which makes the code very easy to read and straightforward. I have come up with something that works but I am not sure if this is the correct way to do this. Rather than keep the functions internal all the functions are "appended" to the library. Anyways, the code which works for me so far is as follows:
slateUI = (function(slateID){
slateUI.ID = slateID;
return slateUI;
});
and a related function looks something like this:
slateUI.doSomething = function(content)
{
//DID SOMETHING USING slateUI.ID
}
I am fairly new to OOP like features of the language. I am sure there is a better way to approach this. The issue that I have is handing down the Element to an appened function call so for instance:
slateUI("#someSlate").doSomething(...)
Obtains its element from the slateUI.ID
Is this the correct way to approach this? Or is this a hacked way that I came up with and there is some straight forward way to do this?
// function which returns a new SlateUI object (so we dont have to use the "new" keyword)
slateUI = function ( slateID ) {
return new SlateUI( slateID );
};
// class definition
function SlateUI ( slateId ) {
this.id = slateId;
}
// methods added to the class prototype (allows for prototypical inheritance)
SlateUI.prototype.someFunction = function() {
alert( this.id );
return this; // adding this line to the end of each method allows for method chaining
};
// usage
slateUI( 'someid' ).someFunction();
The short version of your question is that you're looking for the ability to chain your functions.
This is achieved simply by returning the relevant object from each function. If the function has no other return value, then just return the this variable, to pass control back to the caller.

Hidden Features of MooTools

What are the hidden or obscure features of MooTools that every MooTools developer should be aware of?
One feature per answer, please.
Class Mutators
MooTools has a wonderful feature that allows you to create your own Class mutators. Eg, to add a logger for particular class methods being referenced, you can do:
// define the mutator as 'Monitor', use as Mointor: ['methodname', 'method2'...]
Class.Mutators.Monitor = function(methods){
if (!this.prototype.initialize) this.implement('initialize', function(){});
return Array.from(methods).concat(this.prototype.Monitor || []);
};
Class.Mutators.initialize = function(initialize){
return function(){
Array.from(this.Monitor).each(function(name){
var original = this[name];
if (original) this[name] = function() {
console.log("[LOG] " + name, "[SCOPE]:", this, "[ARGS]", arguments);
original.apply(this, arguments);
}
}, this);
return initialize.apply(this, arguments);
};
};
and then in the Class:
var foo = new Class({
Monitor: 'bar',
initialize: function() {
this.bar("mootools");
},
bar: function(what) {
alert(what);
}
});
var f = new foo();
f.bar.call({hi:"there from a custom scope"}, "scope 2");
Try the jsfiddle: http://jsfiddle.net/BMsZ7/2/
This little gem has been instrumental to me catching nested bugfoot race condition issues inside a HUUUGE async webapp that would have been so difficult to trace otherwise.
Function.prototype.protect is maybe a lesser known nice one.
Is used to have protected methods in classes:
var Foo = new Class({
fooify: function(){
console.log('can\'t touch me');
}.protect(),
barify: function(){
this.fooify();
}
});
var foo = new Foo();
foo.fooify(); // throws error
foo.barify(); // logs "can't touch me"
Personally I don't use it very often, but it might be useful in some cases.
Function.prototype.overloadGetter and Function.prototype.overloadSetter
See this post: What does MooTools' Function.prototype.overloadSetter() do?
There are many features that one can use if you read the source code, although the official line is: if it's not in the documentation, it is not in the api and it's not supported so do not base your code around it as it may change
That being said, there are a few things that really can be quite useful. One of my favourites undocumented features is this:
Referenced Elements have a uid
Any element that has either being created or is passed on through a selector, gets assigned a property uid, which is incremental and unique. Since MooTools 1.4.2, this is only readable via Slick.uidOf(node) and not via the old element attr .uid. You can now use the new uniqueNumber property of any MooTools Element object.
How is that being used? For starters, Element Storage. It relies on the uid as the key in the Storage object inside a closure, which will have anything you have .store'd for that element.
element.store('foo', 'bar');
translates to:
Storage[Slick.uidOf(element)].foo = 'bar';
and
element.retrieve('foo'); // getter of the storage key
element.eliminate('foo'); // delete Storage[Slick.uidOf(element)].foo
Initializing storage for an element you have created externally, eg, via var foo = document.createElement('div') and not Element constructor
Slick.uidOf(foo); // makes it compatible with Storage
// same as:
document.id(foo);
Things that are stored by the framework into Storage also include all events callbacks, validators instances, Fx instances (tween, morph etc) and so forth.
What can you do knowing the UIDs of elements? Well, cloning an element does NOT get the element's storage or events. You can actually write a new Element.cloneWithStorage prototype that will also copy all of the stored values you may have, which is useful upto a point - instances that reference a particular element (such as, Fx.Tween) will continue referencing the old element, so it may have unexpected results. This can be useful in moving your own storage, though, all you need is a similar method that will record what you have stored and allow you to clone it.
Example Storage puncture of another Element's data:
var foo = new Element('div'),
uid = foo.uniqueNumber;
foo.store('foo', 'foo only');
var bar = new Element('div');
console.log(bar.retrieve('foo')); // null
bar.uniqueNumber = uid; // force overwrite of uid to the other el
console.log(bar.retrieve('foo')); // foo only - OH NOES
console.log(Object.keys(foo)); // ["uniqueNumber"] - oh dear. enumerable!
One of my favorite features that I learned later but wished I knew from the beginning - event pseudos, especially :once.
See http://mootools.net/docs/more/Class/Events.Pseudos#Pseudos:once
I'd recommend reading the excellent Up the Moo Herd series by Mark Obcena, author of Pro Javascript With MooTools :)

Categories