ap = Array.prototype,
aps = ap.slice,
apsp = ap.splice,
I often see code like above in different frameworks. What are the benefits of this?
Why not use it directly?
When used exactly as you've shown, the primary reason is to reduce the amount of typing in code that will heavily utilize the referenced method or object. Further, this can have the effect of reducing the overall size of a script. Consider:
Array.prototype.someFunction1 = function () { /*someFunction1 */ };
Array.prototype.someFunction2 = function () { /*someFunction2 */ };
Array.prototype.someFunction3 = function () { /*someFunction3 */ };
Array.prototype.someFunction4 = function () { /*someFunction4 */ };
... (284 characters) versus:
var ap = Array.prototype;
ap.someFunction1 = function () { /*someFunction1 */ };
ap.someFunction2 = function () { /*someFunction2 */ };
ap.someFunction3 = function () { /*someFunction3 */ };
ap.someFunction4 = function () { /*someFunction4 */ };
... which has 261 characters. Trivial, yes, but on a large scale this can make enough of a difference to be worthwhile in distributed code (think Google-hosted jQuery).
Sometimes, however, this is done to preserve scope through a closure:
var self = this;
this.someProperty = 5;
var myDiv = document.createElement('div');
myDiv.addEventListener('mousedown', function(e) { alert(self.someProperty); }, false);
Several benefits:
Faster at run-time (fewer lookups to get the final result)
Smaller code before minification
Easier to reduce even more with minification
Less typing when coding
One should note that I think it makes the code less readable to people not already familiar with the code or its conventions because the code isn't as self documenting. Everyone knows what Array.prototype.splice is but strangers don't know what aps is until they study the code, track down its definition and remember what it is.
I was asked in a comment to explain the fewer lookups issue:
For the interpreter to resolve Array.prototype.splice, it has to do the following:
Look in the local scope for the Array name. It doesn't find it.
Look in any closures (e.g. parent scope) for the Array name. It doesn't find it.
Look in the global scope for the Array name. It finds it.
On the Array object, look for the prototype property.
On the prototype property, look for the splice property and now it finally has the function it needs.
For the interpreter to resolve aps, it has to do this:
Look in the local scope for the aps name. It finds it and not it has the function it needs.
The pre-assignment to aps has essentially pre-done the lookups so that they are already resolved at runtime. This removes some flexibility because if the value of the splice or prototype properties are changed, the variable aps won't reflect that change, but if you know they aren't supposed to change (something the run-time interpreter doesn't know), then you can take advantage of this shortcut.
One functional reason this pattern would exist would be to protect against other javascript code changing the meaning of the particular methods. Essentially protecting from code like the following
Array.prototype.splice = function() {
// This is evil
};
The other more likely though is the developer simply didn't want to type Array.prototype.splice and prefered a shorter version like apsp.
There are two benefits.
a is easier to minify then Array.prototype.slice
a is a single lookup where Array.prototype.slice is multiple look ups
So basically they are both micro optimisations. Which are valuable in libraries because libraries care about being as efficient as possible
Related
Having read this article https://www.toptal.com/javascript/es6-class-chaos-keeps-js-developer-up and subsequently "JavaScript: The Good Parts", I shall henceforth commit to becoming a better JavaScript developer. However, one question remained for me. I usually implemented methods like this:
function MyClass(){
this.myData = 43;
this.getDataFromObject = function(){
return this.myData;
}
}
MyClass.prototype.getDataFromPrototype = function(){
return this.myData;
}
var myObject = new MyClass();
console.log(myObject.getDataFromObject());
console.log(myObject.getDataFromPrototype());
My assumption that underlies this whole post is that getDataFromObject is faster (during call, not during object creation) because it saves an indirection to the prototype but it is also less memory-efficient because every object gets an own instance of the function object. If that is already wrong, please correct me and you can probably stop reading here.
Else: Both article and book recommend a style like this:
function secretFactory() {
const secret = "Favor composition over inheritance [...]!"
const spillTheBeans = () => console.log(secret)
return {
spillTheBeans
}
}
const leaker = secretFactory()
leaker.spillTheBeans()
(quote from the article, the book didn't have ES6 yet but the ideas are similar)
My issue is this:
const leaker1 = secretFactory()
const leaker2 = secretFactory()
console.log(leaker1.spillTheBeans === leaker2.spillTheBeans) // false
Do I not mostly want to avoid that every object gets an own instance of every method? It might be insignificant here but if spillTheBeans is more complicated and I create a bazillion objects, each with twelvetythousand other methods?
If so, what is the "goot parts"-solution? My assumption would be:
const spillStaticBeans = () => console.log("Tabs rule!")
const spillInstanceBeans = (beans) => console.log(beans)
function secretFactory() {
const secret = "Favor composition over inheritance [...]!"
return{
spillStaticBeans,
spillInstanceBeans: () => spillInstanceBeans(secret)
}
}
const leaker1 = secretFactory()
const leaker2 = secretFactory()
leaker1.spillStaticBeans()
leaker2.spillInstanceBeans()
console.log(leaker1.spillStaticBeans === leaker2.spillStaticBeans) // true
console.log(leaker1.spillInstanceBeans === leaker2.spillInstanceBeans) // false
The spillInstanceBeans method is still different because each instance needs its own closure but at least they just wrap a reference to the same function object which contains all the expensiveness.
But now I have to write every method name two to three times. Worse, I clutter the namespace with public spillStaticBeans and spillInstanceBeans functions. In order to mitigate the latter, I could write a meta factory module:
const secretFactory = (function(){
const spillStaticBeans = () => console.log("Tabs rule!")
const spillInstanceBeans = (beans) => console.log(beans)
return function() {
const secret = "Favor composition over inheritance [...]!"
return{
spillStaticBeans,
spillInstanceBeans: () => spillInstanceBeans(secret)
}
}
}())
This can be used the same way as before but now the methods are hidden in a closure. However, it gets a bit confusing. Using ES6 modules, I could also leave them in module scope and just not export them. But is this the way to go?
Or am I mistaken in general and JavaScript's internal function representation takes care of all this and there is not actually a problem?
My assumption that underlies this whole post is that getDataFromObject is faster to call than getDataFromPrototype because it saves an indirection to the prototype
No. Engines are very good at optimising the prototype indirection. The instance.getDataFromPrototype always resolves to the same method for instances of the same class, and engines can take advantage of that. See this article for details.
Do I not mostly want to avoid that every object gets an own instance of every method? It might be insignificant here
Yes. In most of the cases, it actually is insignificant. So write your objects with methods using whatever style you prefer. Only if you actually measure a performance bottleneck, reconsider the cases where you are creating many instances.
Using ES6 modules, I could also leave them in module scope and just not export them. But is this the way to go?
Yes, that's a sensible solution. However, there's no good reason to extract spillInstanceBeans to the static scope, just leave it where it was - you have to create a closure over the secret anyway.
The spillInstanceBeans method is still different because each instance needs its own closure but at least they just wrap a reference to the same function object which contains all the expensiveness.
It should be noted that you're just replicating the way the JavaScript VM works internally: a function like spillTheBeans is compiled only once where it occurs in the source code even if it has free variables like secret. In SpiderMonkey for example, the result is called a »proto-function« (not to be confused with prototype). These are internal to the VM and cannot be accessed from JavaScript.
At runtime, function objects are created by binding the free variables of proto-functions to (a part of) the current scope, pretty much like your spillInstanceBeans example.
Saying that, it's true that using closures instead of prototype methods and this creates more function objects overall – the robustness gained from true privacy and read-only properties might make it worthwhile. The proposed style focuses more on objects rather than classes, so a different design could emerge that cannot be compared directly to a class-based design.
As Bergi says, measure and reconsider if performance is more important in (some part of) your code.
I am new to javascript and I've been wondering about something. Is there an accepted way I should be listing my object properties?
To be specific, I have been writing code where an object is created without any initial properties and adding them on as the code runs.
Example:
Game = {};
Game.x = 0;
...Code code code
Game.thing = function () {
Game.variable = 30;
}
As you can see, my Game object is just slowly gathering properties as my code runs on. Is this acceptable? Or should I be listing out all the properties I will be using at the beginning in my Game object initialization? Thanks.
You can do this:
var Game = { // DON'T FORGET var !!!!!
x: 0,
something: some_value,
thing: function() {
this.variable = 30;
}
};
What you're doing in your code is not really wrong (except don't forget var!!). It's a matter of style and intent. The above code (well the part in the curly braces) is called an "object literal", and it's a way of creating an object as a JavaScript value on the fly. It's very useful, but it's not necessarily better than other ways of building an object.
edit
Note that according to this article when an object (in V8 at least, though I suspect other runtimes are likely to have similar behavior) starts looking like it's being used like a map, then it internally is optimized for that purpose. After that point, for ... in loops over the object will no longer be candidates for optimization. You can (I think) still use Object.keys() to do such iterations, and overall it's probably a net benefit, but it might be the case that objects that experience a lot of property creation fall into that situation.
It really depends on your application. If you have all of the data you want to put in your object when you create it, use an object literal:
var Game = {
x: 0,
thing = function () {
this.variable = 30;
}
}
However, there may be instances where you want to add to your newly created object as you go. This is common when namespacing (which it seems like you're trying to do).
I would start with something like this:
var Game = Game || {};
That way, you make sure you aren't colliding with another object. Then go from there, by adding your properties and methods. A common approach is to create a closure and assign new methods from within that closure.
(function() {
var foo = function () {
... stuff ...
}
Game.foo = foo;
})();
That way, you don't run the risk of accidentally creating any global variables. :)
I'm looking for the standard way to calculate a variable once, then access it within the scope of every execution of a function, without relying on global variables.
This seems like a standard use of prototype properties (variables) - but every example I can find on JS prototypes is based on prototype methods (functions). The only thing I can find about setting properties / variables in a prototype is a question from someone who also couldn't find any information about these, asking if it's good or bad practice (tldr: it's fine, but remember it's rarely worth sacrificing readability for tiny performance gains).
I've got a way to set and get prototype properties that works, but feels clunky as it depends on a reference to the function (essentially var prop = thisfunctionname.prototype.someprop). Since I found it through trial and error, I'd like to ask if there's a cleaner, more standard way to get these prototype properties from within the function, without going back up to the scope around the function and getting the function from there?
Here's a simplified light-hearted example: an imaginary jQuery plugin that adds a number to another number then returns it in a sentence with the user's name. We want to ask the user their name only once, then store that name for re-use within scope:
(function($) {
var sum = function( num1,num2 ) {
var result = num1 + num2;
// This works, but seems clunky since it depends on the variable `sum`
// from the scope around this function - is there a better way?
var name = sum.prototype.name;
$(this).text( num1+' plus '+num2+' is '+result+', '+name+'.');
return $(this);
};
var name = prompt('Please enter your name','');
// Is there a better way to set this default variable to be accessible
// in all calls to this function?
sum.prototype.name = name;
$.fn.basicArithmetic = sum;
})(jQuery);
// end of plugin. Example usage...
$('<p/>').basicArithmetic(1,5).appendTo('body');
$('<p/>').basicArithmetic(2,2).appendTo('body');
$('<p/>').basicArithmetic(25,30).appendTo('body');
$('<p/>').basicArithmetic(92.3,15.17).appendTo('body');
Live jsbin example. More realistic real-life use cases would be when the calculation for the property is expensive in memory usage, or destructive (e.g. requires changing the DOM during calculation).
Two different answers, really:
The usual way is to use a variable within a scoping function (you already have one handy in your example); no prototypes involved at all.
(function($) {
var name;
name = prompt('Please enter your name','');
function sum( num1,num2 ) {
var result = num1 + num2;
$(this).text( num1+' plus '+num2+' is '+result+', '+name+'.');
return $(this);
}
$.fn.basicArithmetic = sum;
})(jQuery);
Updated JSBin Example | Source
(Side note: I also changed your anonymous function expression into a named function declaration, but it doesn't really matter in this case.)
The usual way in a jQuery plug-in is to store the data on the element(s) the plug-in is being applied to. That doesn't work for the example you gave, which requires that the data be global to the plug-in, but normally (not always, just normally) plug-ins keep only instance-specific information, which you'd normally store on elements (probably via the data function).
What object oriented design patterns do you use in your application's javascript, and why?
Feel free to post code, even if there is no formal design pattern attached to it.
I have written plenty of javascript, but I have not applied much object orientated patterns to what I am doing, and I am sure i am missing a lot.
The following are three popular JavaScript patterns. These happen to be easily implementable because of closures:
The Module Pattern - Example (and made popular) by Eric Miraglia
Memoization - Example by Oliver Steele
Currying - Example by Dustin Diaz
You may also want to check out:
Pro JavaScript Design Patterns by Ross Harmes and Dustin Diaz
The following is a Google I/O talk from 2008 presented by Diaz, where he discusses some topics from his book:
Google I/O 2008 - Design Patterns in an Expressive Language
Inheritance
I use a notation for inheritance that is based on ExtJS 3, which I find works pretty close to emulating classical inheritance in Java. It basically runs as follows:
// Create an 'Animal' class by extending
// the 'Object' class with our magic method
var Animal = Object.extend(Object, {
move : function() {alert('moving...');}
});
// Create a 'Dog' class that extends 'Animal'
var Dog = Object.extend(Animal, {
bark : function() {alert('woof');}
});
// Instantiate Lassie
var lassie = new Dog();
// She can move and bark!
lassie.move();
lassie.bark();
Namespaces
I also agree with Eric Miraglia on sticking to namespaces so the code above should be run within its own context outside the window object, this is critical if you intend your code to run as one of many concurrent frameworks / libraries executing in the browser window.
This means that the only way to the window object is via your own namespace / module object:
// Create a namespace / module for your project
window.MyModule = {};
// Commence scope to prevent littering
// the window object with unwanted variables
(function() {
var Animal = window.MyModule.Animal = Object.extend(Object, {
move: function() {alert('moving...');}
});
// .. more code
})();
Interfaces
You can also make use of more advances OOP constructs such as interfaces to enhance your application design. My approach to these is to enhance the Function.prototype in order to get a notation along these lines:
var Dog = Object.extend(Animal, {
bark: function() {
alert('woof');
}
// more methods ..
}).implement(Mammal, Carnivore);
OO Patterns
As for 'Patterns' in the Java sense, I've only found use for the Singleton pattern (great for caching) and the Observer pattern for event-driven functionality such as assigning some actions when a user clicks on a button.
An example of utilising the Observer Pattern would be:
// Instantiate object
var lassie = new Animal('Lassie');
// Register listener
lassie.on('eat', function(food) {
this.food += food;
});
// Feed lassie by triggering listener
$('#feeding-button').click(function() {
var food = prompt('How many food units should we give lassie?');
lassie.trigger('eat', [food]);
alert('Lassie has already eaten ' + lassie.food + ' units');
});
And thats just a couple of tricks in my bag of OO JS, hope they are useful to you.
I recommend if you intend to go down this road that you read Douglas Crockfords Javascript: the Good Parts. Its a brilliant book for this stuff.
I am a fan of the Module Pattern. It's a way of implementing extensible, non-dependent (most of the time) frameworks.
Example:
The framework, Q, is defined like this:
var Q = {};
To add a function:
Q.test = function(){};
These two lines of code are used together to form modules. The idea behind modules is that they all extend some base framework, in this case Q, but are not reliant on each other (if designed correctly) and can be included in any order.
In a module, you first create the framework object if it does not exist (which is an example of the Singleton pattern):
if (!Q)
var Q = {};
Q.myFunction = function(){};
That way, you can have multiple modules (like the one above) in separate files, and include them in any order. Any one of them will create the framework object, and then extend it. No manual need to check if the framework exists. Then, to check if a module/function exists in custom code:
if (Q.myFunction)
Q.myFunction();
else
// Use a different approach/method
The singleton pattern is often very helpful for 'encapsulation' and organization stuff. You can even change accesibility.
var myInstance = {
method1: function () {
// ...
},
method2: function () {
// ...
}
};
cleanest way to implement a singleton in javascript
I really like jquery's method chaining pattern, allowing you to call several methods on one object. It makes it really easy to perform several operations in a single line of code.
Example:
$('#nav').click(function() {
$(this).css('color','#f00').fadeOut();
});
I really like the Decorator pattern with jQuery plugins. Rather than modifying plugins to meet your needs, write a custom plugin that just forwards requests and adds additional parameters and functionality.
For example, if you need to pass a set of default arguments around all the time, and you need slightly-different behavior that ties into business logic, write a plugin that does whatever pre and post work is necessary to suit your needs and passes your default arguments if those particular arguments aren't specified.
The main benefit of this is that you can update your libraries and not worry about porting library changes. Your code might break, but there's at least the chance that it won't.
One of useful patterns in javascript world is chaining pattern which is made popular by LINQ at first place, and also is used in jQuery.
this pattern enables us to call different methods of a class in chaining manner.
the main structure of this pattern would be as
var Calaculator = function (init) {
var result = 0;
this.add = function (x) { result += (init + x); return this; };
this.sub = function (x) { result += (init - x); return this; };
this.mul = function (x) { result += (init * x); return this; };
this.div = function (x) { result += (init / x); return this; };
this.equals = function (callback) {
callback(result);
}
return this;
};
new Calaculator(0)
.add(10)
.mul(2)
.sub(5)
.div(3)
.equals(function (result) {
console.log(result);
});
the key idea of this pattern is this key word, which makes possible accessing to other public member of Calculator fucntion.
I am working on making all of our JS code pass through jslint, sometimes with a lot of tweaking with the options to get legacy code pass for now on with the intention to fix it properly later.
There is one thing that jslint complains about that I do not have a workround for. That is when using constructs like this, we get the error 'Don't make functions within a loop.'
for (prop in newObject) {
// Check if we're overwriting an existing function
if (typeof newObject[prop] === "function" && typeof _super[prop] === "function" &&
fnTest.test(newObject[prop])) {
prototype[prop] = (function(name, func) {
return function() {
var result, old_super;
old_super = this._super;
this._super = _super[name];
result = func.apply(this, arguments);
this._super = old_super;
return result;
};
})(prop, newObject[prop]);
}
}
This loop is part of a JS implementation of classical inheritance where classes that extend existing classes retain the super property of the extended class when invoking a member of the extended class.
Just to clarify, the implementation above is inspired by this blog post by John Resig.
But we also have other instances of functions created within a loop.
The only workaround so far is to exclude these JS files from jslint, but we would like to use jslint for code validation and syntax checking as part of our continuous integration and build workflow.
Is there a better way to implement functionality like this or is there a way to tweak code like this through jslint?
Douglas Crockford has a new idiomatic way of achieving the above - his old technique was to use an inner function to bind the variables, but the new technique uses a function maker. See slide 74 in the slides to his "Function the Ultimate" talk. [This slideshare no longer exists]
For the lazy, here is the code:
function make_handler(div_id) {
return function () {
alert(div_id);
};
}
for (i ...) {
div_id = divs[i].id;
divs[i].onclick = make_handler(div_id);
}
(I just stumbled on this questions many months after it was posted...)
If you make a function in a loop, an instance of a function is created for each iteration of the loop. Unless the function that is being made is in fact different for each iteration, then use the method of putting the function generator outside the loop -- doing so isn't just Crockery, it lets others who read your code know that this was your intent.
If the function is actually the same function being assigned to different values in an iteration (or objects produced in an iteration), then instead you need to assign the function to a named variable, and use that singular instance of the function in assignment within the loop:
handler = function (div_id) {
return function() { alert(div_id); }
}
for (i ...) {
div_id = divs[i].id;
divs[i].onclick = handler(div_id);
}
Greater commentary/discussion about this was made by others smarter than me when I posed a similar question here on Stack Overflow:
JSlint error 'Don't make functions within a loop.' leads to question about Javascript itself
As for JSLint:
Yes, it is dogmatic and idiomatic. That said, it is usually "right" -- I discover that many many people who vocalize negatively about JSLint actually don't understand (the subtleties of) Javascript, which are many and obtuse.
Literally, get around the problem by doing the following:
Create a .jshintrc file
Add the following line to your .jshintrc file
{"loopfunc" : true, // tolerate functions being defined in loops }
JSLint is only a guide, you don't always have to adhere to the rules. The thing is, you're not creating functions in a loop in the sense that it's referring to. You only create your classes once in your application, not over and over again.
If you are using JQuery, you might want to do something like this in a loop:
for (var i = 0; i < 100; i++) {
$("#button").click(function() {
alert(i);
});
}
To satisfy JSLint, one way to work around this is (in JQuery 1.4.3+) to use the additional handler data argument to .click():
function new_function(e) {
var data = e.data; // from handler
alert(data); // do whatever
}
for (var i = 0; i < 100; i++) {
$("#button").click(i, new_function);
}
Just move your:
(function (name, func) {...})()
block out of the loop and assign it to a variable, like:
var makeFn = function(name, func){...};
Then in the loop have:
prototype[prop] = makeFn(...)