Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Properties of Javascript function objects

I have a JavaScript function object as;

var addNum = function(num1, num2) {         return num1 + num2; } 

Now if I try to access

addNum.divide() 

I wanted to understand the prototype chain for the above code. I read that in the above example, addNum would be searched for divide(), followed by Function.prototype and finally Object.prototype.

But my question is in the above example, how can addNum would be searched for divide()

Does it refer to something like ;

var addNum = function(num1, num2) {  this.divide = function(){}              return num1 + num2;     } 

I could not understand the line where it says addNum would be searched for divide()

Please help me understand the same.

like image 927
copenndthagen Avatar asked Mar 02 '13 11:03

copenndthagen


People also ask

What is JS function object?

JavaScript functions are a special type of objects, called function objects. A function object includes a string which holds the actual code -- the function body -- of the function. The code is literally just a string.

What are the properties of an object?

The basic properties of an object are those items identified by its four-part name (name, type, instance, and version) and also include owner, status, platform, and release.

What is objects properties and methods in JavaScript?

Object MethodsMethods are actions that can be performed on objects. Object properties can be both primitive values, other objects, and functions. An object method is an object property containing a function definition. JavaScript objects are containers for named values, called properties and methods.

How many properties can a JavaScript object have?

JavaScript objects have two types of properties: data properties and accessor properties.


2 Answers

I'm not sure this will answer your question but may give you some insight. Consider the following example:

var Person = (function () {     var Person = function (name) {         this.name = name;     }      Person.greet = function () {         console.log("Hello!");     }      Person.prototype = {         greet: function () {             console.log('Hello, my name is ' + this.name);         }     };     return Person; })();  var bob = new Person("Bob");  Person.greet(); // logs "Hello!" bob.greet(); // logs "Hello, my name is Bob 

The function object "Person" has a direct 'greet' property that is a Function. OOP-wise, you can almost think of that as a static method that can be called directly from the Person Function (Person.greet()). Once you "instantiate" a person object from the Person constructor, that new object "bob" now references it's methods from the Person.prototype object. Now when you call bob.greet(), it uses the greet function in the prototype object.

Hope that helps.

like image 58
Keith Morris Avatar answered Oct 10 '22 11:10

Keith Morris


As you say so yourself: you have a function object. Functions are objects in JS, just like Object literals, arrays, or anything else: a function can be assigned properties and methods at will:

var someAnonFunction = function(foo) {     console.log(this);     console.log(this === someAnonFunction);//will be false most of the time }; someAnonFunction.x = 123;//assign property someAnonFunction.y = 312; someAnonFunction.divide = function() {     console.log(this === someAnonFunction);//will be true most of the time     return this.x/this.y;//divide properties x & y }; someAnonFunction.divide(); 

In this case, the function object, referenced by someAnonFunction has been assigned a reference to the anonymous function, called divide (well, the reference to an anonymous function was dubbed divide anyway). So there is no prototype involvement at all here. Mind you, as you say so yourself: all objects can be traced back to Object.prototype, just try this:

console.log(someAnonFunction.toString === Function.prototype.toString);//functions are stringified differently than object literals console.log(someAnonFunction.hasOwnProperty === Object.prototype.hasOwnProperty);//true 

Or, perhaps this is more clear: a simple scheme of how a method/property call is resolved to a value in JS:

[      F.divide      ]<=========================================================\ \ F[divide] ===> JS checks instance for property divide                           | |  /\ ||                                                                          | |  || || --> property found @instance, return value-------------------------------| |  || ||                                                                          | |  || ===========> Function.prototype.divide could not be found, check prototype  | |  ||      ||                                                                     | |  ||      ||--> property found @Function.prototype, return-----------------------| |  ||      ||                                                                     | |  ||      ==========> Object.prototype.divide: not found check prototype?        | |  ||          ||                                                                 | |  ||          ||--> property found @Object.prototype, return---------------------|_|  ||          ||                                                                 |=|  ||          =======>prototype is null, return "undefined.divide"~~~~~~~~~~~~~~~|X|  ||                                                                             \ /  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< TypeError can't read property 'x' of undefined 

It therefore follows, that if you want the code above to work using prototypes, you'll have to augment a prototype of sorts (in this case, the Function.prototype). Do know that this isn't to be recommended, in fact changing "native" prototypes is often frowned upon. Still:

Function.prototype.divide = function (a, b) {     a = +(a || 0);//coerce to number, use default value     b = +(b || 1) || 1;//division by zeroe is not allowed, default to 1     return a/b; }; function someFunction () {     return 'someString'; }; var another = function(a, b) {     return a + b; }; someFunction.divide(12, 6);//will return 2 another.divide(12, 4);//3 

In both cases, the function object, referenced by the name (someFunction or another) will be scanned for a property called divide, which isn't found. Then however it'll scan the Function.prototype, where such a property is found.
If that weren't the case, JS would also check the Object.prototype, if that failed, it will eventually throw an error.

I've posted quite lengthy answers on SO on this subject a while back:

What makes my.class.js so fast? (deals with prototype chains)
Objects and functions in javascript (recap of functions <=> objects <=> constructors)
What are the differences between these three patterns of "class" definitions in JavaScript? (some more info, still)
Javascript - Dynamically change the contents of a function (vaguely touches on the anonymous functions, assigned to variables and properties and changing their context)

like image 34
Elias Van Ootegem Avatar answered Oct 10 '22 09:10

Elias Van Ootegem