Javascript namespacing/prototype issue - javascript

I've been trying to further my understanding of javascript namespacing and prototype inheritance but i am running into an issue.
An example of what i'm dealing with code wise:
var namespace = {
ex1: function () { },
ex2: function () {
this.exvar1 = 0,
this.exvar2 = 0;
}
}
namespace.ex1.prototype = {
method1: function () {
},
method2: function () {
}
};
namespace.ex2.prototype = {
method1: function () {
alert("ex2.method1" + typeof this.method1);
},
method2: function () {
alert("ex2.method2" + typeof this.method2);
}
};
if i then try and call a method by doing:
namespace.ex2.method1();
i find that namespace.ex2.method1 is not a function.
What am i missing?

i find that namespace.ex2.method1 is not a function.
Correct. In JavaScript, you don't directly assign prototypes to objects (although that's becoming possible as the new 5th edition gets adopted; see below). Instead, you set up prototypes on constructor functions which are then assigned to objects constructed by those functions. So if you had done
var obj = new namespace.ex2();
obj.method1();
...you would have found the method. (Although there's no reason you can't call namespace.ex2.prototype.method1(); if you want to.)
This indirect approach is somewhat unusual for a prototypical language. ECMAscript 5th edition does introduce a means of creating an object and setting its prototype directly (Object.create), but that's a fairly new addition to the language.
For more about prototypes, "methods," setting up prototype chains, etc., you might find this article by Crockford and this rather lesser (but perhaps more familiar-sounding, and certainly pragmatic) one by yours truly interesting reading.

create instance before
var instance = new namespace.ex1;
try here http://jsfiddle.net/quWPC/

Prototypes apply to instances of objects:
var foo = function() {};
foo.prototype = {
a: function() {}
}
var instance = new foo;
instance.a();
To put a function directly inside an object (instead of in its prototype), do this:
var foo = function() {};
foo.a = function() {};
foo.a();

Related

Constructor function - in simple namespace - Javascript

In want to define a function-constructor inside a namespace. The way in which I defined the constructor till now was a simple constructor function without NS, combined with prototypal inheritance.
The code looked kind of like:
function mySuperObject() {
var self = this;
self.p1 = "";
self.p2 = "jkejie";
// and others
}
mySuperObject.prototype.func1 = function(){...}
// and others
Introducing namespace:
After reading many articles I decided to start up with a very simple way to define a namespace, maybe the most simplest.
Basically it is just about defining a variable which points to an object-literal and the content is the object (the "mySuperObject" in the code-snippet above). The constructor function is following: mySuperObjectInNS.
The code of the object:
var MYNAMESPACE = {
//some variable outside the object
file : "ConstructorInNamespace_obj.js: ",
//Defining contructor function inside a namespace
mySuperObjectInNS : function(propOne, propTwo){
var self = this;
self.objectName = "mySuperObject";
self.propertyOne = propOne;
self.propertyTwo = propTwo;
self.doSomething = function(){
console.log(file + " doSomething called - function of object");
};
///many more functions and attributes
}
}
MYNAMESPACE.mySuperObjectInNS.prototype.specialFunction = function(){
console.log(file + " specialFunction called - prototypical inheritance defined in file of object, outside of namespace");
};
///many more functions and attributes
In another file it is possible to intantiate the object, as follows:
...
var objOne = new MYNAMESPACE.mySuperObjectInNS("param11", "40");
//following line works just fine
objOne.doSomething();
....
Questions:
It seems to me that this all is about defining an Object-Literal and
I will come into trouble the latest I am trying to define "private"
properties of that object. Is this correct?
Is that mySuperObjectInNS still a constructor function? (For me it
seems it is something else,even if I can intantiate objects from it.
Is is a very bad very bad way of namespacing or is kind of ok?
It seems to me that this all is about defining an Object-Literal and I will come into trouble the latest I am trying to define "private" properties of that object. Is this correct?
"Private properties" have nothing to do with using an object for namespacing. In fact, originally when answering this question, I read that as "private functions" because that would be relevant.
There are lots of ways to do private and semi-private properties in JavaScript, but they relate to how you create the constructor function and the methods it gives the object, not how you expose the constructor function. "Namespace" objects are about how you expose the constructor.
One common pattern for creating "private" properties is to define methods that need to access them within the constructor, and make the "properties" local variables within the constructor (so they aren't really properties at all), like this:
function SuperObject() {
var privateInformation;
this.method = function() {
// This can access `privateInformation`, which is completely
// hidden from outside the constructor
};
}
It doesn't matter at all if you do that within a "namespacing" pattern or on its own.
Private functions, on the other hand, affect the pattern. I'll show both below.
A fairly common variant that provides for private functions is to use a function to create the object, which also gives you the opportunity to create private functions:
var TheNamespace = function() {
function privateFunction() {
}
function SuperObject() {
var privateInformation;
this.method = function() {
// This can access `privateInformation`, which is completely
// hidden from outside the constructor
};
}
SuperObject.prototype.otherMethod = function() {
// Can't access `privateInformation`, but has the advantage
// that the function is shared between instances
};
return {
SuperObject: SuperObject
};
}();
// usage
var s = new TheNamespace.SuperObject();
Is that mySuperObjectInNS still a constructor function? (For me it seems it is something else,even if I can intantiate objects from it.
Yes. A constructor function is any function that expect you to use new with it.
Is is a very bad very bad way of namespacing or is kind of ok?
Using objects as pseudo-namespaces is common practice. You might also consider various asynchronous module definition (AMD) technologies, which largely make "namespace" objects largely unnecessary.
Re your comment:
You defined a self-invoking function....which returns an an object?
It's not a self-invoking function, it's an inline-invoked function, but yes, it's a function that returns an object.
(if so I think parantheses are missing)
No, we don't need any parens that aren't there because the only reason for the outer parens other places you've seen this are to tell the parser that the word function starts an expression rather than declaration; we don't need that in the above because we're already on the right-hand side of an assignment, so there's no ambiguity when function is encountered.
Due to you proposed this way, is it a better way to define the ns?
"Better" is a subjective term. It gives you a scope in which you can define private functions, which you'd asked about.
Whereas I often also saw the option: var = {} | someNSName; What is this all about?
If you have several files that will add things to the "namespace" (as is common), then you frequently see this in each of them:
var TheNamespace = TheNamespace || {};
What that does is declare the variable if it hasn't been declared before, and assign an empty object to it if it doesn't already have one. In the first file that gets loaded, this happens:
The var is processed and creates a new variable, TheNamespace, with the value undefined.
The TheNameSpace = TheNameSpace || {} assignment is processed: Since undefined is falsey, the curiously-powerful || operator results in the new {}, which gets assigned to TheNamespace.
When the next file loads, this happens:
The var is a no-op, because the variable already exists.
The TheNameSpace = TheNameSpace || {} assignment is processed: Since TheNamespace has a non-null object reference, it's truthy, and the curiously-powerful || operator results in a reference to the object TheNamespace refers to.
That is, it has no effect at all.
This is used so you can load the files in any order, or load just one file in isolation.
Here's an example:
thingy.js:
var TheNamespace = TheNamespace || {};
TheNamespace.Nifty = function() {
function privateFunction() {
}
function Nifty() {
var privateInformation;
this.method = function() {
// Can access `privateInformation` here
};
}
Nifty.prototype.otherMethod = function() {
// ...
};
return Nifty;
}();
thingy.js:
var TheNamespace = TheNamespace || {};
TheNamespace.Thingy = function() {
function privateFunction() {
}
function Thingy() {
var privateInformation;
this.method = function() {
// Can access `privateInformation` here
};
}
Thingy.prototype.otherMethod = function() {
// ...
};
return Thingy;
}();
There are lots of variations on that basic pattern, particularly if one file may add multiple things to TheNamespace. Here's one that supports doing so fairly concisely:
var TheNamespace = function(exports) {
function privateFunction() {
}
function Nifty() {
var privateInformation;
this.method = function() {
// Can access `privateInformation` here
};
}
Nifty.prototype.otherMethod = function() {
// ...
};
exports.Nifty = Nifty;
function Thingy() {
var privateInformation;
this.method = function() {
// Can access `privateInformation` here
};
}
Thingy.prototype.otherMethod = function() {
// ...
};
exports.Thingy = Thingy;
}(TheNamespace || {});

JavaScript new Function confusion

While reading Learning JavaScript 2nd edition, I see a block of code in Chapter 13: Creating Custom JavaScript Objects.
var oneOff = new Function () {
this.variablea = "variablea";
this.method = function () {
return xxx;
}
}
It is said that it is the same as:
var oneOff = new Object();
oneOff.variablea = "variablea";
oneOff.method = function () {...};
But I don't know what new Function () {..} is. Any help is appreciated. Thanks.
When using new function() { /* */ }, you are not creating a new function, but rather an object.
It is just a standard use of new with a constructor function, like in :
var oneInstance = new ConstructorFunction();
function ConstructorFunction() {
this.var1 = 'val1';
this.method1 = function() { } ;
}
The difference is that the constructor is defined right at the time of instantiation, and we omit to call the function, which is legal (although confusing i think).
I find it somehow clearer with some brackets, and making explicit the call to the constructor :
var oneOff = new ( function () {
this.variablea = "variablea";
this.method = function () {
return xxx;
};
} ) () ;
but for creating just one single object, one would rather use the simple object notation :
var oneOff = {
variablea : 'valuea',
method : function () { return xxx; }
}
How do they compare in performances ?
For the new function() {} method, creating the object will require to first create a function, then execute that function within a 'new' context.
On the other hand, object litteral just create ...one object, so it's less time and less garbage created.
On use performances of the two types of objects (time to read/write a property /use a method) it's very hard to say since all javascript interpreters are very complex and very different. When and how do they decide to optimize a part of the code is something you can't really know before benchmarking. - And benchmarking is not an easy task also because of those 'random' optimisations. My bet is that they should be very close in use performance, let us know if you take the time to do some measures.
new function (notice F is lowercase) is one of the many ways of creating an object in Javascript. After the code is interpreted an object will be assigned to oneOff with variablea and method properties.
Another way to achieve this is to use the object literal notation:
var oneOff = {
variablea:"variablea",
method:function () {
return xxx; //this will be undefined
}
}
This works fine if you only need one instance of oneOff however if you need multiple instances of oneOff you can use the function constructor as follows:
function OneOff(){
this.variablea = "variablea";
}
OneOff.prototype.method = function(){
return xxx; //one again undefined
}
var firstOneOff = new OneOff();
var secondOneOff = new OneOff();

Can you create functions with custom prototypes in JavaScript?

First of all, I don't want to add methods to Function.prototype. Doing that would make them available for all functions and that's not what I'm looking for.
In JavaScript you can create objects with custom prototypes like this:
function CustomObj() {}
CustomObj.prototype = {};
CustomObj.prototype.sayFoo = function () { return 'foo' };
var myCustomObj = new CustomObj(); //=> returns an object: {}
myCusomObj.sayFoo(); //=> 'foo'
You can also create array-like objects with custom prototypes like this:
function CustomArr() {}
CustomArr.prototype = [];
CustomObj.prototype.sayFoo = function () { return 'foo' };
var myCustomArr = new CustomArr(); //=> returns an ordered object: []
myCustomArr.sayFoo(); //=> 'foo'
What I'd like to do is use some kind of constructor to create a function with its own custom prototype in the same way. However, the following does not work:
function CustomFn() {}
CustomFn.prototype = function () {};
CustomFn.prototype.sayFoo = function () { return 'foo' };
var myCustomFn = new CustomFn(); //=> PROBLEM! returns an object: {}
myCustomFn.sayFoo(); //=> 'foo'
// ^^ Here, the prototype was applied but the output was not a function.
myCustomFn(); //=> TypeError: object is not a function
So is there any way to accomplish what I'm trying to do?
UPDATE
Maybe there's another way I could be asking this question that would make it a little clearer.
There's a problem with the idea of a closure:
function makeFn() {
var output = function () { /* do some stuff */ };
output.foo = function () { /* do some stuff */ };
return output;
}
var specialFn = makeFn();
Essentially, this technique gives me what I want. However, the problem is that every time I call makeFn, output.foo has to be created as a totally independent function that takes up its own memory. Gross. So I could move that method out of the closure:
var protoMethods = {
"foo" : function () { /* do some stuff */ }
};
function makeFn() {
var output = function () { /* do some stuff */ };
for (var i in protoMethods) {
Object.prototype.hasOwnProperty.call(protoMethods, i) &&
(output[i] = protoMethods[i]);
}
return output;
}
var specialFn = makeFn();
But now I have to manually do an iteration every time I call makeFn which would be less efficient than if I could just assign protoMethods to be the prototype of output. So, with this new update, any ideas?
It is a tricky thing indeed, more complicated than it should be if the language was designed well...
Basically, you just can't do it cleanly in current versions. Objects other than functions can not be callable.
In future Javascript versions, you can do it with a "proxy" object that can define a "call" handler. But it is still way too complicated and contrived in my opinion.
Another way to go about it is to make your object a real function, not a custom object. Then try to set its __proto__, which is non-standard yet but works in most modern browsers, except Opera and IE 8 or less. Also maybe set its constructor property for faking instanceof checks... such hacks are quite tricky though and results will vary a lot with environments.
The following example works fine on my Firefox:
http://jsfiddle.net/Q3422/2/
function MyFun() {
if (!this || this==window) {
return new MyFun();
}
var f = function() {
return "thanks for calling!";
}
f.__proto__ = MyFun.prototype;
f.constructor = MyFun;
return f;
}
MyFun.prototype = {
foo: function() {
return "foo:" + this();
},
__proto__: Function.prototype
};
var f = new MyFun();
alert("proto method:"+f.foo()); // try our prototype methods
alert("function method:"+f.call()); // try standard function methods
alert("function call:"+f()); // try use as a function
alert('typeof:' + typeof f); // "function", not "object". No way around it in current js versions
alert('is MyFun:' + (f instanceof MyFun)); // true
alert('is Function:' + (f instanceof Function)); // true
Just wanted to add that you should not be worried about "copying" functions to each instance of your objects. The function itself is an object, so is never really copied, nor is it recompiled or anything. It does not waste memory, except for the function object reference itself and any closure variables.
Iterating over the prototype to copy it should not concern you as well, I guess you will not have a gazillion methods.
So your own last solution is probably the best if you need to support environments where proto is not settable, and you are not worried that your prototype might get extended after some objects already got created and they may not pick up the changes.
You're at the heart of what inheritance in JavaScript is all about. Yes, since prototypes are objects, you'll want to set the prototype of CustomFn to an object instead of a function.
But that object can come from another function:
function ParentFn() {}
function CustomFn() {}
CustomFn.prototype = Object.create(ParentFn.prototype);
CustomFn.prototype.sayFoo = fun ...
If you don't have ES5 or a polyfill:
CustomFn.prototype = (function() {
function F(){}
F.prototype = ParentFn.prototype;
return new F();
}());
Some may tell you just to do the following but the above way is better:
CustomFn.prototype = new ParentFn();
I tried that too, when working on V library. I wanted to override the Function constructor to enforce a restricted syntax of constructor functions, that I'm calling "class functions" (and I'm confident to do so).
Answer is no, using the new operator you can only create new "object"s, but not new "function object"s.
However you can use a constructor function both as a constructor and as a function!
var CustomFn = function () {
if (this instanceof CustomFn) {
// here we are 'new CustomFn()'
}
else {
// here we are 'CustomFn()' or 'CustomFn.call()'
}
};
Or as I believe is the better concept, to do the function in first place and then let the constructor go:
var CustomFn = function () {
if (!(this instanceof CustomFn)) { // functioning
// here we are 'CustomFn()' or 'CustomFn.call()'
return new CustomFn(); // or return undefined or throw
}
// constructing
// here we are 'new CustomFn()'
// BaseCustomFn.call(this);
};

How to change function inside constructor in JavaScript?

I need to edit the function which locates inside of the constructor.
Example:
some.thing = function() {
this.somefn = function() { // this is the function that I need to fix
...
}
}
But function should be edited not just only for a single object (new obj = some.thing();) but also for any created objects by this constructor.
So is there any way to edit such inner-functions?
Here is a solution based on prototype:
var Something = function () {
this.f = function () {
console.log("Something");
};
};
var Old = Something;
var Something = function () {
Old.apply(this);
this.f = function () {
console.log("New");
};
};
Something.prototype = new Old();
var s = new Something();
s.f(); // prints "New"
The solutions seem just a little too obvious, so I'm wondering if the trouble is that you don't have access to the original code, and you need a more dynamic solution.
If so, one option may be to override the constructor with your own constructor, and have it call the original, and then update the object.
Original code:
some.thing = function() {
this.somefn = function() { // this is the function that I need to fix
...
}
}
Your code:
// cache a reference to the original constructor
var _thing = some.thing;
// your constructor
some.thing = function() {
// invoke the original constructor on the new object.
_thing.apply(this, arguments);
this.somefn = function() { /*your updated function*/ };
};
// maintain inheritance
some.thing.prototype = Object.create(some.thing.prototype);
// make an instance
var theThing = new some.thing();
Now you're getting the benefit of the original constructor and prototype chain, but you're injecting your own function on to the objects being created.
Only trouble may be that the original function you replaced could make special use of the original constructor's variable scope. If that's the case, there would be an issue to resolve.
It would be possible to retain and invoke the original method that you overwrote before invoking yours. Not sure if this situation calls for that or not.
I exactly know your need cause last week I passed through it. I just implemented a complete inheritance model in javascript and as far as I remember, I had a problem with overriding constructors and calling the parent class's ctor when child class is initializing.
So I just solved the problem with modifing some points in my design and it's now working like a charm! (something like C# but in Javascript)
By the way, I don't suggest you to change a method contents this way, but here is a way to do that (I myself did not do that this way and AGIAIN I DO NOT RECOMMEND IT. THERE ARE MANY OTHER WAYS, BUT THIS IS THE EASIEST):
var test = function() { /*InjectionPlace*/ };
eval("var newTest = " + test.toString().replace(
"/*InjectionPlace*/",
"var i = 10; alert(i);"
));
test();
newTest();
Cheers

Confusing JavaScript statement: "var x = new this();"

I thought I understood the concept of the JavaScript prototype object, as well as [[proto]] until I saw a few posts regarding class inheritance.
Firstly, "JavaScript OOP - the smart way" at http://amix.dk/blog/viewEntry/19038
See the implementation section:
var parent = new this('no_init');
And also "Simple JavaScript Inheritance" on John Resig's great blog.
var prototype = new this();
What does new this(); actually mean?
This statement makes no sense to me because my understand has been that this points to an object and not a constructor function. I've also tried testing statements in Firebug to figure this one out and all I receive is syntax errors.
My head has gone off into a complete spin.
Could someone please explain this in detail?
In a javascript static function, you can call new this() like so,
var Class = function(){}; // constructor
Class.foo = function(){return this;} // will return the Class function which is also an object
Therefore,
Class.foo = function(){ return new this();} // Will invoke the global Class func as a constructor
This way you get a static factory method. The moral of the story is, not to forget functions are just like any other objects when you are not calling them.
What is confusing you, I think, is just where "this" is really coming from. So bear with me-- here is a very brief explanation that I hope will make it quite clear.
In JavaScript, what "this" refers to within a function is always determined at the time the function is called. When you do:
jimmy.nap();
The nap function (method) runs and receives jimmy as "this".
What objects have references to nap is irrelevant. For example:
var jimmy = {}, billy = {};
jimmy.nap = function(){ alert("zzz"); };
var jimmy_nap = jimmy.nap;
jimmy_nap(); // during this function's execution, this is *NOT* jimmy!
// it is the global object ("window" in browsers), which is given as the
// context ("this") to all functions which are not given another context.
billy.sleep = jimmy.nap;
billy.sleep(); // during this function's excution, this is billy, *NOT* jimmy
jimmy.nap(); //okay, this time, this is jimmy!
In other words, whenever you have:
var some_func = function(arg1, arg2){ /*....*/ };
// let's say obj and other_obj are some objects that came from somewhere or another
obj.some_meth = some_func;
other_obj.some_meth = some_func;
obj.some_meth(2, 3);
other_obj.some_meth(2, 3);
What it's getting "translated" into (not literally-- this is pedagogical, not about how javascript interpreters actually work at all) is something like:
var some_func = function(this, arg1, arg2){ /* ...*/ };
// let's say obj and other_obj are some objects that came from somewhere or another
obj.some_meth = some_func;
other_obj.some_meth = some_func;
obj.some_meth(obj, 2, 3);
other_obj.some_meth(other_obj, 2, 3);
So, notice how extend is used in the example on that page:
UniversityPerson = Person.extend({ /* ... */ });
Pop quiz: When extend runs, what does it think "this" refers to?
Answer: That's right. "Person".
So the puzzling code above really is the same as (in that particular case):
var prototype = new Person('no_init');
Not so mysterious anymore, eh? This is possible because unlike in some languages,
a JavaScript variable-- including "this"-- can hold any value, including a function such as Person.
(There is nothing that makes Person specifically a constructor. Any function can be invoked with the new keyword. If I recall the exact semantics, I think they are that when a function is called with the new keyword, it is automatically given an empty object ({}) as its context ("this") and when the function returns, the return value is that same object unless (maybe?) the function returns something else)
This is a cool question because it speaks to a pretty essential part of JavaScript's neatness or oddness (depending on how you see it).
Does that answer your question? I can clarify if necessary.
AJS.Class effectively* translates this:
var Person = new AJS.Class({
init: function(name) {
this.name = name;
Person.count++;
},
getName: function() {
return this.name;
}
});
Person.count = 0;
into this:
var Person = function (name) {
this.name = name;
Person.count++;
};
Person.prototype = {
getName: function() {
return this.name;
}
};
Person.extend = AJS.Class.prototype.extend;
Person.implement = AJS.Class.prototype.implement;
Person.count = 0;
Therefore, in this case, this in AJS.Class.prototype.extend refers to Person, because:
Person.extend(...);
// is the same as
Person.extend.call(Person, ...);
// is the same as
AJS.Class.prototype.extend.call(Person, ...);
* There are a lot of cases I don't go over; this rewrite is for simplicity in understanding the problem.
Imagine the following situation :
var inner = function () {
var obj = new this;
console.log(obj.myProperty);
};
var f1 = function () {
this.myProperty = "my Property"
}
f1.f2 = inner;
f1.f2();
Here the calling object is itself a function, so this will return a function, and we can instantiate it.
In order to use this()(not this) the outer function(the context) must itself return smth that can be instantiated(another function):
var inner = function () {
var obj = new this();
console.log(obj.myProperty);
};
var f1 = function () {
var func = function () {};
func.myProperty = 'my property';
return func;
};
f1.f2 = inner;
f1.f2();
A simpler code explaination:
class User {
constructor() {
this.name = '';
this.age = '';
}
static getInfo() {
let user = new this();
console.log(user);
}
}
User.getInfo()
Output:
Object {
age: "",
name: ""
}
see this link http://www.quirksmode.org/js/this.html It will tell you about the this keyword, but I am not sure what this() is, may be its some kind of user defined function...... that you are not aware of...
"this" means the context of the function currently running.
The code you are posting surely appears in a function that act as a method for an object.
So the object is the context of the function.
"new this()" will return a clone of the current object after running its constructor function with the passed arguments.
this() refers to the the function that the code is in, but this() would have to be within that function. Calling new this(); within a function would create a never ending loop. Calling it outside of a function would be redundant because there is no function/class set as this().

Categories