Declaring a member function in JS - javascript

I've tried two ways to declare a member function in JS:
function init() {
var name = "Mozilla";
function displayName() {
alert(name);
}
}
a = new init();
a.displayName()
And
function init() {
var name = "Mozilla";
displayName = function() {
alert(name);
}
}
a = new init();
a.displayName()
The first method told me that displayName() is undefined. The way I see it a variable of type Function with name displayName is created, and thus it should work.
Any one care to explain why it didn't work?

It doesn't work because that's now how JavaScript works. Just declaring a function within a constructor function doesn't set it up on the object created by the constructor function, you have to make the link between the object and the function explicitly (directly by assigning it to the object, or more often indirectly via a prototype).
The typical way you do that is via prototypical inheritance, although you can also just assign functions directly to individual objects (more below — but you talked about "member functions," and the typical way you do things like that in JavaScript is via prototypes).
There are a couple of ways to set up prototypical inheritance. The classic way, which is compatible with a broad range of JavaScript engines even in legacy browsers, is via the prototype property on constructor functions, which refers to an object. That object becomes the prototype of instances created via new FunctionName. You add properties to that object to share them amongst the instances created by that function.
So, using prototypical inheritance:
function Init(name) {
this.name = name;
}
Init.prototype.displayName = function() {
alert(this.name);
};
var i = new Init("Mozilla");
i.displayName();
Notes on the above:
In JavaScript, the overwhelming convention is that constructor functions start with an upper case letter. So I called it Init rather than init.
All functions automatically have a prototype property on them, which is a blank object.
I add a property to that object called displayName which refers to a function.
Rather than hard-coding the name, I pass it into Init as an argument.
Note that I store the name on a property on the newly-constructed instance; within the call to Init, that instance is available as this.
Similarly, because displayName is called as part of an expression retrieving the function reference from the object, this is the object within the call to displayName, and so this.name has the name.
To keep things simple in the above, I assigned an anonymous function to displayName. (The property has a name, the function does not.) I tend not to do that in real code.
All instances constructed via new Init will share the same copy of the displayName function, via the prototype.
More to explore (on my blog):
Mythical methods
You must remember this
Anonymouses anonymous
You might also be interested in my Lineage toolkit, if you're interested in building classes of objects in JavaScript (and hierarchies).
As of ES5, there's another option: Object.create. This allows you to create objects and assign them prototypes directly, without using constructor functions. But as you used new, which means you're using constructor functions, I won't go into detail on that.
Now, you don't have to use the prototype features of JavaScript if you don't want to. You can, for instance, do this:
function Init(name) {
var name = name;
this.displayName = function() {
alert(name);
};
}
var i = new Init("Mozilla");
i.displayName();
That doesn't use the prototype features of JavaScript, instead it just creates a new displayName function every time you call Init and assigns it directly to the object. (Any reasonable quality JavaScript engine will be smart enough to reuse the code of the function, but there will be distinct function objects for each instance). The above also makes the name property completely private, because the function we create on each call is a closure over the local variable name. (More: Closures are not complicated)

To create something like a member function you need to add it to the protoype of the constructor function:
function init() {
this.name = 'Mozilla';
}
init.prototype.displayName = function() {
alert(this.name);
}
I also highly recommend you to read something about how the object system in JavaScript works. There's a pretty good article about it on MDN: https://developer.mozilla.org/en-US/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript

The following should work:
function Init() {
var name = "Mozilla";
this.displayName = function() {
alert(name);
}
}
a = new Init();
a.displayName()

One of the standards you can use is
var init = (function() {
var name = "Mozilla"; // Shared by all instances
function init() {
this.name = "IE"; // Spesific to the created instance
}
init.prototype = {
displayName: function() {
alert(name);
alert(this.name);
}
}
return init;
})();
var a = new init();
a.displayName();​

In your first method:
function init() {
var name = "Mozilla";
function displayName() {
alert(name);
} } a = new init(); a.displayName()
function displayName(){} only can be called in init(), it's like private function, so can not be used as a public function of the object(init())

Related

Using this or new in JS?

I've got 3 codes :
var control = new Control();
function Control() {
this.doSomethingElse = function() {...}
this.doSomething = function () {
control.doSomethingElse();
}
}
Or
var control = new Control();
function Control() {
var self = this;
this.doSomethingElse = function() {...}
this.doSomething = function () {
self.doSomethingElse();
}
}
Or
var control = Control();
function Control() {
var self = this;
this.doSomethingElse = function() {...}
this.doSomething = function () {
self.doSomethingElse();
}
return self;
}
Important : The function is a controller, and just declared once. Then I'm using "control" everywhere in my code...
I was wondering if the control.doSomethingElse() was slow ?
In the end, what is the right thing to do and/or the fastest code in those exemple ?
Thanks !
The first is wrong - an object should never internally use the variable name by which it is known outside. Other code could change that variable to point to something else, breaking this code.
The third is also wrong - when calling Control() without new the assignments to this.foo inside will end up getting attached to the global object (except in strict mode, where there's no implicit this on bare function calls, so the assignment to this.doSomethingElse tries to attach to undefined, causing a runtime error).
That only leaves the second as appropriate, but ultimately it's a question of correctness, not performance.
Do not define methods in constructor - that means defining them every time an instance is created. Use Control.prototype.foo = function() {} instead. Also you do not need to return this if you're using new operator - that's the whole point of new operator.
The recommended approach is this:
function MyClass(param1) {
// Here we're changing the specific instance of an object
this.property1 = param1;
}
// Prototype will be shared with all instances of the object
// any modifications to prototype WILL be shared by all instances
MyClass.prototype.printProperty1 = function() {
console.log(this.property1);
}
var instance = new MyClass("Hello world!");
instance.printProperty1(); // Prints hello world
To understand this code, you need to understand javascript's prototype-based inheritance model. When you create instance of MyClass, you get a new object that inherits any properties present in MyClass.prototype. Read more about it.
Also I wonder:
The function is a controller, and just declared once.
If you're not using this multiple times, you don't need to create something like class. You can do this instead:
var control = {doSomething:function() { ... }};
I assume you are used to Java, where everything must be a class, whether it makes sense or not. Javascript is different, you can also make single objects or functions as you need.

How can I create encapsulated 'classes' in JavaScript?

In JavaScript, classes are usually emulated through constructors. However, I'm curious as to how one can create an encapsulated class, i.e. a class that keeps some of it's members private.
The commonly seen way of creating a 'class' is as follows:
function MyClass(parameter) {
this.value = parameter;
}
MyClass.prototype.myPublicFunction = function() {
console.log("About to run private function.");
myPrivateFunction();
};
MyClass.prototype.myPrivateFunction = function() {
...
};
As you can see, in this example myPrivateFunction is actually public. One approach I've seen to solve this problem is the following:
function MyClass(parameter) {
this.value = parameter;
this.myPublicFunction = function() {
console.log("About to run private function.");
myPrivateFunction.call(this);
}
function myPrivateFunction() {
...
}
}
This works; myPrivateFunction is inaccessible from the outside. But this approach has a problem - all functions in this 'class' are going to be copied across instances, instead of shared through the prototype. Also using privateFunction.call(this) everywhere isn't awesome.
Same goes for non-function members. How can I define a private instance-member in a class? What is the best and what is the most common approach? Is it acceptable to simply rely on a naming convention (such as beginning private function names with a _)?
You could create a scope to hide you private functions with an auto executing function.
Like:
(function(){
function myPrivateFunction(arg_a, arg_b) {
/* ... */
console.log("From priv. function " + this.value);
}
window.MyClass = function(parameter) {
this.value = parameter;
this.myPublicFunction = function() {
console.log("About to run private function.");
myPrivateFunction.call(this, 'arg_a', 'arg_b');
}
}
})();
But then you need to use MyClass only after it is declared since now it is an function expression and not a function statement, but all instances of MyClass will share the same instance of myPrivateFunction. but you will need to use Function.prototype.call (as in myPrivateFunction.call(this, 'arg_a', 'arg_b'); to get the value of this keyword to match your instance.
If you do just myPrivateFunction('arg_a, 'arg_b'); the keyword this will point to the global object (window on browsers) or null if 'strict mode' is enabled.
Just a note: In my own code I don't do this but rely on naming conventions like MyClass.prototype._myPrivateFunction = function(){}; when not using some framework.

function declaration within function declaration with same name javascript

I've just seen this pattern in javascript:
var test = function () {
function test(args) {
this.properties = args || {}; //etc
}
}
test.prototype.methodName = function (){} //...etc
What is going on with the function definition; declared once outside and once inside. What is the value of this approach?
It is strange. The "outer" function acts as a constructor, you can use var myTest = new test(); to create a new test.
The inner function, because of JS function-scoping, would only be available within the constructor method. You could call the inner test(...) from within the constructor, but it seems pointless as presumably args should be passed in to the constructor.
What might have been intended is:
var test = function(args) {
this.properties = args || {}; // you may want to actually parse each arg here
}
test.prototype.someOtherMethod = function() {}
The first thing to understand here is that functions in JavaScript create new scopes – there is no block scope (yet). So every variable or function declared inside another function is not visible to the outside.
With that in mind: when you define the inner function with the same name of the outer, you lose the ability to call the outer function recursively from itself, by name, because the inner function will "take over" (or "shadow") that name. Inside both functions, test will refer to the inner function, and outside the outer function test always refer to the outer function.
Since after the function definition you're modifying test.prototype, we can assume test (the outer one) will be used as a constructor. In this case, the inner test can be seen as a "private" method of the constructor, callable only from within the constructor. For detailed examples of this object-oriented use of functions within functions, see James T's answer.
This is scope.
When you define a variable as a function, it creates function scope.
Inside that function you can declare the same name, because that function is declared within that scope... Take an easier to follow example:
var User = function()
{
function PrivateToScope()
{
// A Function Only Accessible Inside This Function
alert( "private" );
}
return
{
PublicToScope: function()
{
// A Function Accessible From Outside This Function
alert( "public" );
}
}
}
var James = new User();
James.PublicToScope(); // Will alert "public"
James.PrivateToScope(); // Will fail to do anything
So to explain the answer, the User sets scope, and because you declare the function as above wit the same name, it does not matter.
People do not like me saying this but you can think of this approach as if it were a class in other languages.
var User = function()
{
}
is like
class User
{
}
var User = function()
{
function Something()
{
}
}
is like
class User
{
private function Something()
{
}
}
and finally
var User = function()
{
this.Something = function()
{
}
// or
return {
Something: function(){}
}
}
is like
class User
{
public function Something()
{
}
}
It's alllll about scope. maybe you have a user variable declared as a function and you wish to allow people to get his first name and last name, you would declare these variables or functions as "public"... but what if you wanted to know his diet was good or bad, you may have some complex functions to work it out, but you want to know one thing, good or bad.. you could make all these functions that do ugly stuff private, and then just display the result with a public function...
var User = function()
{
function CalculateDiet()
{
// Lots of scary diet calculating stuff comes out with the result
return result;
}
return
{
FirstName: "James",
LastName: "Poop",
StandardOfDiet: function()
{
return CalculateDiet();
}
}
}
var MyUser = new User();
alert( MyUser.FirstName );
alert( MyUser.StandardOfDiet() );
Why do you care?
Quantifying it is both easy and hard but here are some good ones...
It's neat
If you place a pile of chocolates on a table, they'll all get eaten.. but one of them was for you, people are greedy... Only layout on the table what you want them to eat, they can't be greedy then an accidently eat your chocolate
It sets you up for class oriented programming
It's clear what the programmer meant to do with the code
Memory usage (I'm sure there are overheads to declaring more functions public without need to
Finally, and on a very different note, you have a prototype attached to test, so let's go do this for our user example. Imagine we had an array of users:
var users = [
new User(),
new User()
];
we can iterate over these and get all their usual properties and methods:
for( a in users )
{
alert( users[ a ].FirstName );
}
But let's say something happens in our application... a user clicks on a button that asks each user if they like fish and chips or not, we now need a new method for the user... We can prototype a new method to all iterations of that variable "user" we created... We could declare it before hand, but then we'd waste memory and maybe confuse future programmers with its presence that is based off of something very specific:
// user clicks button and runs this code
User.protoype.DoesUserLikeChips = function(){
// put some code in here that somehow makes this example make sense :)
}
now on every user in your array, you can call this new method... New functionality babehhh!
You may be thinking, why do you not just go users[ a ].DoesUserLikeChips = function(){}... The answer is that it is applied to only that one instance...
Inner test function is a private function of outer test function. And then a methodName function has been set as public function of outer test function. There are no special thing about naming inner function as outer one.

javascript: constructor function vs revealing module pattern for single use

I have come to understand that constructor functions can be instantiated to create new objects in javascript which has its own _proto_ property and also giving the property 'prototype' to the constructor function.
function MyController() {
var controllerName = 'initialcontroller';
function init() {
console.log(controllerName);
}
this.init = init;
}
Here, init can be called like this:
var mycontroller = new MyController();
mycontroller.init();
Supposing I am only instantiating only once and never again, isn't this an overkill if I don't intend to use all the prototype properties being provided by the MyController.prototype ?
Question: Instead, can i not code like this using the revealing module pattern?
var myController = function() {
var controllerName = 'initialcontroller';
function init() {
console.log(controllerName);
}
return {
init : init
}
}();
Here, init can be called like this:
myController.init();
In this case, if I try to access any property inside myController that is not present, the javascript engine won't try to find whether the property exists anywhere in the prototype chain, thus saving my time.
Or is there any other advantages of instantiating a function that i am overlooking?
If you simply want a "singleton"-like object with some methods and other properties, you could just use an object literal to simplify things even more:
var myController = {
init: function (foo) {
// do something with foo or whatever
}
}
myController.init("bar");
Or - if you need some "private" internal state, use the regular revealing module pattern:
var myController = (function () {
var internal = "i am private";
return {
init: function () {
// blah blah
}
};
}());
myController.init();
About the prototype lookup time: Yeah, theoretically, the lookup traverses up the prototype chain when you're trying to access a non-existing property. Theoretically, this might be a tiny bit faster for plain ol' Object instances that have "no" specific constructor. In reality, this performance impact should be quite negligible. Don't attempt to optimize here unless you REALLY need it. :)

Recommend way of scoping private members in javascript module

Conside the following JavaScript code. The function definitions all seem to achieve the same thing. Is there any recommended convention for defining the functions which are then 'revealed' in the return dictionary object?
var testModule = (function(){
var counter = 0;
var localFunc1 = function() {
return "local 1";
}
function localFunc2() {
return "local 2";
}
this.localFunc3 = function() {
return "local 3";
}
localFunc4 = function() {
return "local 4";
}
return {
proxy1: localFunc1,
proxy2: localFunc2,
proxy3: localFunc3,
proxy4: localFunc4
};
})();
I don't think that there is any real preferred method. The most common setup I've seen involves creating all of your methods as local (using var) then returning an object that exposes the public methods.
A couple of things to note:
this.localFunc3 will only work if your object is instantiated with the 'new' keyword
when returning your object, remove the () from each function so that you are returning a reference to the function and not the function's returned value
localFunc4 will be global since it has no 'var' keyword in front of it
When working with a module pattern like this, I tend to go for something along the lines of:
var Obj = ( function () {
var private_static = 'this value is static';
return function () {
//-- create return object
var _self = {};
//-- create private variables
var private_variable = 'this value is private';
var func1 = function () {
return 'value 1';
};
//-- attach public methods
_self.func1 = func1;
//-- return the object
return _self;
};
} )();
Some notes about this method:
allows for private static variables (if you don't need private static variables, you can remove the closure)
by creating the _self reference first, you can pass a self reference to any objects instantiated from within that need a reference to their parent
I like that I can reference all internal functions without _self.whatever or this.whatever, ignoring whether or not they are private or public
The definitions do not achieve the exact same thing.
var localFunc1 and function localFunc2 do the same thing, they create functions only available inside your outer function.
this.localFunc3 and localFunc4 are not really local functions: they both belong to the window object (this in that context is window, and localFunc4 is declared without the var statement).
So, the latter two don't even need to be exposed on your returned object, since they're already global. And, actually, you are not exposing any functions on your return object, you are exposing their return values, since you invoke each of them. Were you trying to do this?
return {
proxy1: localFunc1,
proxy2: localFunc2,
proxy3: localFunc3,
proxy4: localFunc4
};
Note: I recommend you watch this video where Douglas Crockford explains the multiple ways to deal with inheritance in JavaScript. I believe you are looking for what he calls "parasitic inheritance".

Categories

Resources