Calling an JavaScript Object's methods is not always as
straightforward as you might expect. Not only are there several ways of
doing so, but each may result in the method behaving in different and
even unexpected ways. It's all part of the flexibility that is inherent
in JavaScript. In today's article, we're going to look at various ways
of calling object methods and their ramifications.
Methods vs. Functions
Some times it seems that functions and methods are one and the same.
Technially they are in JavaScript, because all functions belong to some
object. However, methods that can be called without an object-dot prefix
(object.) are considered to be functions. As such, they are part of the
global namespace. In fact, all global functions are owned by the Window
object, but it doesn't require the object-dot prefix. To put it to the
test, take any global function that you can think of, like alert(),
isNaN(), or eval() and prepend the 'window.' object identifier to it:
1
2
3
4
5
6
7
| alert( 'hi there.' ); window.alert( 'hi there.' ); //still works isNaN( 'test' ); //returns true window.isNaN( 'test' ); //still returns true eval( "isNaN('test');" ); //also returns true! window.eval( "window.isNaN('test');" ); //true as well |
Method Piggybacking using Function Call() and Apply()
In JavaScript, the Function is itself an object that has its own
methods! Two of these are call() and apply(). Both serve the same
purpose, which is to allow an object to use another object's method for
its own designs. While the whole thing may sound a little disingenuous,
it does save you from having to duplicate methods across multiple
objects. Both methods accept the this pointer as the first argument, but
call() takes each target function parameter separately, while apply()
expects an array of arguments as the second argument:
1
2
3
| Function.call(thisArg[, arg1[, arg2[, ...]]]) Function.apply(thisArg[, argArray]) |
The call() method signature is best suited for methods whose
arguments you know beforehand. Apply(), on the other hand, is for
methods whose argument list can vary or is unknown.
Some examples will make the distinction clear. In the first one,
Luigi is a leach who has no methods of his own. If he were a Java of C++
class, his life would be barren indeed. However, since he lives in
JavaScript, he can use one of the Function methods to execute Mario's
sayHello() method. Since we know that the sayHello() method only takes a
name argument, we can use call() and pass the name to it:
1
2
3
4
5
6
7
8
9
10
11
12
| var Mario = { name: 'Mario' , sayHello: function (name) { return 'Hi ' +name+ ', I\'m ' + this .name; } }; var Luigi = { name: 'Luigi' }; alert(Mario.sayHello.call(Luigi, name)); //outputs 'Hi Mario, I'm Luigi' |
One good use for the apply() method is in object creation and
constructor chaining. The reason is that every object will have a
different set of constructor arguments. In the following example, our
createObject() method is added to the Function object's prototype so
that we can apply it to any object's constructor function. The person
object's initialization parameters are set via an array of object
literals, each containing the property name and associated value. By
using the apply() method, we can pass the array to the constructor
function. It in turn, parses the property names and values to set them.
Once the object has been created, we can access class members using the
usual object-dot (person.) notation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| Function.prototype.createObject = function (aArgs) { var init = this , fNewConstr = function () { init.apply( this , aArgs); }; fNewConstr.prototype = init.prototype; return new fNewConstr(); }; var args = [{name: "Rob" }, {age: 29}, {liesAboutHisAge: true }]; var person = function () { for ( var i = 0; i < arguments.length; i++) { var propName = function (obj) { for ( var name in obj) { return name; } }(arguments[i]); this [propName] = arguments[i][propName]; } }.createObject(args); alert(person.name); // alerts "Rob" |
Calling an Instance Method without an Instance
Yes, you read that correctly. Not only do the call() and apply()
methods allow an object to hijack another's methods, but you can use
them to call the methods of an object that hasn't been instantiated! The
reason we can do that is because in JavaScript, built-in objects like
Strings and Arrays store all their methods in the prototype property.
So, although Strings and Arrays are technically functions, their
prototypes are objects. Here's some code that calls the String's
substr() method directly instead of accessing it trough our 'str'
instance variable:
1
2
| alert( typeof String); //displays 'function' var str = 'the quick brown fox jumped over the log.' ; alert(String.prototype.substr.call(str, 4, 5)); |
You might be wondering what the advantage of calling a method this
way might be. Sometimes you just don't need to have an instance of a
certain object type, but need to get at some of its functionality. In
our last example of the day, we have an instance of parameter relaying.
Just as we can pass parameters directly to a function or method, they in
turn can pass parameters between each other. A classic example is where
one function uses some parameters and then passes the rest on to the
next function. That is accomplished by calling the Array prototype's
slice() method:
1
2
3
4
5
6
7
8
9
| function function1() { alert(Mario.sayHello(arguments[0])); //passes the last argument on function2.apply(arguments[1], Array.prototype.slice.call(arguments, 2)); } function function2() { //only one argument passed alert(Mario.sayHello.call( this , arguments[0])); } function1( "Luigi" , Luigi, Mario.name); |
Conclusion
There are many ways to call an object's methods in JavaScript, and
just as many ways of passing parameters to a method. By taking advantage
of both, you can save yourself a lot of method duplication as well as
cut down on your object instances. Especially where built-in objects are
concerned, you can often utilize an object method without creating an
instance of that object.
Nice article to read. Surely java got it's various advantage over other language that keep it above other programming language as well and useful for coding mobile apps and web development.
ReplyDeleteThanks for the article,
Think to Share Web Designing Company in Kolkata
Build your career; join new age IT courses online at Kolkata lead by experienced faculties. Affluenz IT Academy is the best IT training Institute for online training at reasonable course fees.
ReplyDeleteJoin
AI training courses in Kolkata
Big data and Hadoop Certification Training Course in Kolkata
Ethical Hacking Certification Training Course in Kolkata
AWS Training Course in Kolkata
MS Azure Certification Training Course in Kolkata