How to add Javascript function to every object? - javascript

I'm wondering how can I attach a function to be available for each object on the page. I know that I can do it like this:
mything = {
init: function(SELECTOR){
},
destroy: function(){
}
};
But then it is available to me only this way: mything.init(SELECTOR);
What I want is to be able to do the same thing this way:
$('.mydiv, input, whatever').myFunction({ 'my' : 'arg', 'my2' : 'arg2' });
$('.mydiv').myFunction('destroy');
I know that there are plenty of Javascript tutorials out there but I don't know how to search for this type of functionality. Any help would be appreciated!

In your case, it looks like it is just enough for you to extend the jQuery.prototype.
jQuery.extend( jQuery.fn, mything );
However, it is of course possible, even if not very recommendable, to go that ultimate root and extend the Object.prototype. This really would add those functions to every and each object.

This isn't necessarily a great idea (it's a terrible idea), but you can accomplish this with prototypes:
Object.prototype.myFunction = function() {
console.log('Called myFunction');
};
And you can see what happens for an arbitrary object:
document.myFunction();
Note that adding to the prototypes of classes other than your own (and especially the builtin objects or classes belonging to libraries other than your own) can induce lots of confusion. This is one of the reasons why Google's own style guide recommends against this (despite much temptation to add String.startsWith, String.endsWith, and many other useful operations to builtin types).

The clean way to do what you describe is to wrap your code inside a jQuery plugin.
Here is the official jquery plugin guide. Read through it, it is actually quite simple to understand.
The part about wrapping functions (so that $(selector).myFunction() calls init, $(selector).myFunction('doThis') calls doThis, etc...) is here.

Related

custom methods and the usefulness of constructors and prototype in web-dev

ok so i know that prototype is used for inheritance and when coupled with a constructor function can be used to make custom methods. so my question here is two fold: how do i make methods for pre-built JavaScript objects like integers,strings,arrays,etc...
the other question is besides making my own methods what is the usefulness of constructors/prototype in everyday web development(i.e. creating websites) or is this more so for high-end development like making a web app or developing with new tech(i.e. html5 canvas or three.js) i haven't seen an example anywhere on the web of this being used in an everyday situation.
To create a Javascript method to an already existing object, you can simple add it to its constructor's prototype:
String.prototype.firstLetter = function() { return this.charAt(0); }
var myStr = "Cool str!";
alert(myStr.firstLetter()); // 'C'
As for how useful it will be, depends on what you do with Javascript. If you write client-side code and you need to modify an existing component, monkey-patching a function may be useful there. If you need some structure on your code (and you do), creating an object to represent the interface state may be useful.
Also, knowing how to use a tool usually avoids self-harm. =)
If you are interested, you may want to take a look into Crockford's page or buy his Javascript: The Good Parts book.
There is a lot of confusion you can avoid if you get to know the language, and you may even get to like it and find out you can do a lot of useful stuff in it.
Here's an example that extends Number:
Number.prototype.between = function(a, b) {
return this >= a && this <= b
}
var num = 0;
if (num.between(0,0)) alert('is between')
else alert('not');
Although I often use the prototype, I have not yet run across a good reason to use the constuctor property, which returns the type of an Object. W3schools.com has a good illustration of this property at http://www.w3schools.com/jsref/jsref_constructor_math.asp
You can add functions into a class's prototype:
String.prototype.report_fish = function() { alert("a fish!"); };
"".report_fish();
You can do this with numbers as well, although the syntax to invoke is slightly different:
Number.prototype.report_fish = function() { alert("a fish!"); };
(0).report_fish();
As to why you'd do this, I personally believe that you should avoid doing this to built-in objects where possible. (A persistent problem to work around when building re-usable Javascript libraries used to be and probably still is people's tendency to override and extend the Object prototype.)

Keeping your javascript structured and tidy (as an OO programmer)

I've recently been playing with javascript, HTML5, chrome extensions, jQuery, and all that good stuff. I'm pretty impressed so far with the possibilities of javascript, the only thing I struggle with is structuring my code and keeping it tidy. Before I know it, functions are scattered all over the place. I've always done my programming in an object oriented manner (C++ and C#), and I find myself not being able to keep things tidy. It feels like I always end up with a bunch of static util functions, were I to 'think' in C#.
I've been looking for some information on objects in javascript, but it seems to come down to wrapping functions in functions. Is this a good way of structuring your codebase? On the surface it seems a bit hackish. Or are there other ways of keeping things tidy for an OO mindset?
One important aspect to remember about Javascript is that it is a prototypical language. Functions can be objects, and anything can be put on the object, often affecting related objects in the process. There's no official way to 'extend' an object because of this. It's a concept that I still have a hard time understanding.
Javascript 'acts' like any other OOP language for the most part, with some exceptions, namely extending objects (http://jsweeneydev.net84.net/blog/Javascript_Prototype.html).
After extensive research, I did find a very, very light-weight way to simulate expanding objects (I'm using using it in my GameAPI). The first field is the parent object, the second is the object that expands.
extend : function(SuperFunction, SubFunction) {
//'Extends' an object
SubFunction.prototype = new SuperFunction();
SubFunction.prototype.constructor = SubFunction;
},
This link might clear up some problems and misconceptions:
http://www.coolpage.com/developer/javascript/Correct%20OOP%20for%20Javascript.html
Personally, I tend to be anti-framework, and I haven't seen a framework yet that doesn't force the programmer to significantly change their programming style in this regard anyway. More power to you if you find one, but chances are you won't really need one.
My best advise is to try to adapt to Javascript's prototypical style, rather than force old methodologies on it. I know it's tricky; I'm still trying to myself.
Best of luck diggingforfire.
I generally follow the make-an-anonymous-function-then-call-it pattern. Basically, you create an inner scope and return a single object containing your interface. Nothing else escapes, because it's all trapped within the function scope. Here's an example using jQuery:
var FancyWidget = (function($) {
// jQuery is passed as an argument, not referred to directly
// So it can work with other frameworks that also use $
// Utility functions, constants etc can be written here
// they won't escape the enclosing scope unless you say so
function message(thing) {
alert("Fancy widget says: " + thing);
}
// Make a simple class encapsulating your widget
function FancyWidget(container) {
container = $(container); // Wrap the container in a jQuery object
this.container = container; // Store it as an attribute
var thisObj = this;
container.find("#clickme").click(function() {
// Inside the event handler, "this" refers to the element
// being clicked, not your FancyWidget -- so we need to
// refer to thisObj instead
thisObj.handleClick();
});
}
// Add methods to your widget
FancyWidget.prototype.handleClick = function() {
this.container.find("#textbox").text("You clicked me!");
message("Hello!");
};
return FancyWidget; // Return your widget class
// Note that this is the only thing that escapes;
// Everything else is inaccessible
})(jQuery);
Now, after all this code executes, you end up with one class, FancyWidget, which you can then instantiate.
You can define multiple classes this way too; instead of using return FancyWidget, you can return an object literal instead:
return {
FancyWidget: FancyWidget,
Frobnicator: Frobnicator,
// Nested namespaces!
extra: {
thing: thing,
blah: blah
}
};
One of the best OOP javascript libraries out there is Google's Closure library http://closure-library.googlecode.com/svn/docs/index.html
It's structured in a way that OOP programmers will be familiar with especially if you come from a java/C# background. Have a look at the source code of any file and it should feel right at home as an OOP programmer. http://closure-library.googlecode.com/svn/docs/closure_goog_graphics_canvasgraphics.js.source.html
I have never used this personally, but have seen backbone.js referenced many times to this question. See at: http://documentcloud.github.com/backbone/
Using some framework designed to meet similar requirements may be a good idea.
But there are some things you should really follow to be efficient:
remember about closures in JavaScript and do not forget about var keyword,
use callbacks where possible and reasonable, JavaScript is asynchronous by nature,

jQuery like custom functions

I have been wondering how I can create functions like jQuery. For example: $(ID).function()
Where ID is the id of an HTML element, $ is a function that return the document.getElementById reference of the element "ID" and function is a custom javascript function.
I'm creating a little library which implements some functions. And I want to use that sintax without using jQuery.
Now, my questions are: how I can implement that? What is the name of the tecnique that allow that?
Edit:
What I want to do is this:
HTMLElement.prototype.alertMe = function() {alert(this.value);}
Then, when I call document.getElementById('html_input_id').alertMe(), it must show an alertbox with the input value. But HTMLElement.prototype doesn't work in IE.
$ = function(id) {
return document.getElementById(id);
}
Okay, look, what you're asking has a lot of details and implications. The code for jQuery is open source, you can read it for the details; you'd do well to find a good Javascript book as well, the the O'Reilly Definitive Guide.
$ is just a character for names in JS, so as some of the other answers have shown, there's no reason you can't just write a function with that name:
var $ = function(args){...}
Since everyone and his brother uses that trick, you want to have a longer name as well, so you can mix things.
var EstebansLibrary = function(args){...}
var $ = EstebansLibrary; // make an alias
Since you end up doing different things with the entry point function, you need to know how JS uses arguments -- look up the arguments object.
You'll want to package this so that your internals don't pollute the namespace; you'll want some variant of the module pattern, which will make it something like
var EstebansLibrary = (function(){
// process the arguments object
// do stuff
return {
opname : implementation,...
}
})();
And you'll eventually want to be prepared for inheritance and that means putting those functions into the prototype object.
You can use prototype to assign a new function to the Element prototype.
Element.prototype.testFunction=function(str){alert(str)};
This would provide the function 'testFunction' to all HTML elements.
You can extend any base Object this way, i.e. Array, String etc.
This will work without any plugin at all - although that said I don't think it will work in IE. I believe libraries such as MooTools and jQquery create their own inheritance with DOM elements to ensure cross-browser compatibility, although don't quote me on that.

Javascript Object Prototype

I was reading Prototypes in javascript and I have written 2 small js codes which are outputting exactly same. I just want to know what is the difference between them:
Code 1:
String.sam = function() { alert('fine') };
'ok'.sam();
Code 2 with prototype:
String.prototype.sam = function() { alert('fine') };
'ok'.sam();
Please clarify the difference and the better way to use the code.
Thanks
Your first example doesn't work. What you are doing is creating a static method on the string object so you would have to call it statically
//OK
String.sam();
//not OK, raises error
'hello'.sam();
In your second example the keyword this will refer to the instance of the string you call it on. So you can do something like
String.prototype.sam = function() {
console.log( this.toUpperCase() );
}
'hello'.sam(); // HELLO
This technique, although powerful is frowned upon in certain quarters. It is known as Guerrilla patching, Monkey punching or similar things.
There are a few reasons it is considered bad:
Hard to debug (you've changed the language)
Easy to break other code on the page that is not aware you've altered a prototype
Possible clashes with future enhancements of the core.
Probably lots more
I think, your first method adds only for this special property the alert() method. If you want create another instance, you have to do the same thing again. With protoype you define it more generally so you don't have to do the same thing again for another instance.
Perhaps http://www.javascriptkit.com/javatutors/proto.shtml will help you to understand it better.

Adding methods to native JavaScript objects

Adding methods to native JavaScript objects like Object, Function, Array, String, etc considered as bad practice.
But I could not understand why?
Can some body shed light on this?
Thanks in advance.
Because you might happen to use a library that defined a function with the same name, but working another way.
By overriding it, you break the other's library's behaviour, and then you scratch your head in debug mode.
Edit
If you really want to add a method with a very unpleasant name like prependMyCompanyName(...) to the String prototype, I think it's pretty much risk-free from an overriding point of view. But I hope for you that you won't have to type it too often...
Best way to do it is still, in my humble opinion, to define for example, a MyCompanyUtils object (you can find a shortcut like $Utils), and make it have a prepend(str,...) method.
The two big reasons in my opinion are that:
It makes your code harder to read. You write code once and read it many number of times more. If your code eventually falls into the hands of another person he may not immediately know that all of your Objects have a .to_whatever method.
It causes the possibility of namespace conflicts. If you try to put your library which overrides Object.prototype into another library, it may cause issues with other people doing the same thing.
There is also the effect that augmenting the Object prototype has on for...in loops to consider:
Object.prototype.foo = 1;
var obj = {
bar: 2
};
for (var i in obj) {
window.alert(i);
}
// Alerts both "foo" and "bar"

Categories

Resources