Setting up standard JavaScript prototypal inheritance within a namespace? - javascript

The standard prototypal inheritance in JavaScript is as follows:
function Animal() {
this.legs = 0;
}
Animal.prototype.move = function () {
alert("I'm moving!");
}
Bird.prototype = new Animal();
Bird.prototype.constructor = Bird;
function Bird() {
this.legs = 2;
this.wings = 2;
}
Bird.prototype.move = function () {
alert("I'm flying!");
}
Does the function definition for Bird have to come after the assignment of Bird's prototype and constructor. I ask this because I'm trying to do this from within a namespace, and variable hoisting is causing my code to fail. As an example:
var namespace = {};
namespace.Animal = function () {
this.legs = 0;
};
namespace.Animal.prototype.move = function () {
alert("I'm moving!");
};
namespace.Bird.prototype = new namespace.Animal();
namespace.Bird.prototype.constructor = namespace.Bird;
namespace.Bird = function () {
this.legs = 2;
this.wings = 2;
};
namespace.Bird.prototype.move = function () {
alert("I'm flying!");
};
Thanks to hoisting the namespace.Bird.prototype assignment statement and the namespace.Bird.prototype.constructor assignment statement fail. If I move the namespace.Bird function assignment above those two lines as shown in the following code block, however, the code seems to work.
namespace.Bird = function () {
this.legs = 2;
this.wings = 2;
};
namespace.Bird.prototype = new namespace.Animal();
namespace.Bird.prototype.constructor = namespace.Bird;
However, I don't know if there's a specific reason why most resources show the original order rather than having the function assignment come first.
Can someone please clarify?
Thanks!

The reason has to do with parse-time availability of functions and runtime availability of functions.
For example:
var afunc = asdf;
function asdf(){}
is the same as
function asdf(){}
var afunc = asdf;
But,
var afunc = asdf;
var asdf = function(){};
is not the same as
var asdf = function(){};
var afunc = asdf;
Does that make sense why?
Also, the answers to this question would probably help you
var functionName = function() {} vs function functionName() {}

Related

Is there a problem with my implementation of the module pattern?

I've written the following as an implementation of the module pattern:
let myClass = function (publicName, privateName)
{
this.publicVar = publicName;
let privateVar = privateName;
this.publicMethod = function ()
{
return this.publicVar;
}
this.getPublic = function ()
{
return this.publicMethod();
}
this.setPublic = function (newPublicName)
{
this.publicVar = newPublicName;
}
this.getPrivate = function ()
{
return privateVar;
}
this.setPrivate = function (newPrivateName)
{
privateMethod(newPrivateName);
}
let privateMethod = function (newPrivateName)
{
privateVar = newPrivateName;
}
return this;
}
let a = new myClass('public A', 'private A');
let b = new myClass('public B', 'private B');
// A
console.log(a.publicVar);
console.log(a.publicMethod());
console.log(a.getPrivate());
a.setPrivate('private A-2');
console.log(a.getPrivate());
console.log(a.getPublic());
a.setPublic('public A-2');
console.log(a.getPublic());
// B
console.log(b.publicVar);
console.log(b.publicMethod());
console.log(b.getPrivate());
b.setPrivate('private B-2');
console.log(b.getPrivate());
console.log(b.getPublic());
b.setPublic('public B-2');
console.log(b.getPublic());
It differs from examples I can generally find on the web though, as it doesn't use an IIFE, and doesn't use a constructor as such...
Is there a problem with what I've done?
I can't see anything wrong with it personally... It seems to encapsulate the methods and variables as it should.
NOTE: I also realise that a lot of the methods are unnecessary, I just wanted to test a few things to see if I could break it.

Make object variables be accesible within all "deeper" scope

I'm currently coding a kind of plugin in JS. I've just learnt about objects, and I'm kind of annoyed by the fact that I can't access variables set within the constructor, two or more levels up. Here's what I mean:
var myConstructor = function()
{
this.one = "one";
this.two = "two";
this.publicMethod = function()
{
console.log("I can access: ", this.one);
var privateMethod = function()
{
console.log("I cannot access var two like this: ", this.two);
};
privateMethod();
};
};
var myObject = new myConstructor();
myObject.one = 1;
myObject.two = 2;
myObject.publicMethod();
So, how could I make privateMethod access the variables that are set within the constructor? In the same manner that publicMethod uses this to do so. Is this possible? Thank you very much.
Try this.
var myConstructor = function()
{
this.one = "one";
this.two = "two";
this.publicMethod = function()
{
// new variable
_two = this.two;
console.log("I can access: ", this.one);
var privateMethod = function()
{
console.log("I cannot access var two like this: ", _two);
};
privateMethod();
};
};

Error for JS OOP beginner training

I'm new in programming and I'm learning JavaScript OOP, trying to make a game with tanks. I have some code but it doesn't work properly and I need some help to understand how it works. Please check it and tell me how to solve the problem because I want to add a few more kinds of tanks but before that I need to fix the code.
var Tank = (function () {
function Tank(name) {
this._name = name;
}
Tank.prototype.getWeight = function () { return this._weight; }
Tank.prototype.getName = function () { return this._name; }
return Tank;
}());
var SmallTank = (function () {
this.prototype = Object.create(Tank.prototype);
function SmallTank(name) {
Tank.apply(this._name);
}
SmallTank.prototype._weight = 2;
return SmallTank;
}());
var myTank = new SmallTank("Aleks Tank");
console.log(myTank.getWeight());
It seems that you're just trying to do some kind of inheritance; typically you do this by assigning a parent instance to the prototype of the child.
I think you will want something like this:
var SmallTank = (function () {
function SmallTank(name) {
Tank.call(this, name);
this._weight = 2;
}
SmallTank.prototype = new Tank();
return SmallTank;
}());
Alternatively you can assign Object.create(Tank.prototype).
Here is another way of doing what it looks like you are attempting to do, following the Mozilla guide:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
var Tank = function (name) {
this.name = name;
};
Tank.prototype.getName = function () { return this.name; };
var SmallTank = function (name) {
Tank.call(this, name);
this.weight = 2;
};
SmallTank.prototype = Object.create(Tank.prototype);
SmallTank.prototype.constructor = SmallTank;
SmallTank.prototype.getWeight = function () { return this.weight; };
var myTank = new SmallTank("Aleks Tank");
console.log(myTank.getName());
console.log(myTank.getWeight());

Class inheritance with method in javascript

I am new to javascript app development.When i came with functions and all i have found a code like
function Parenizor(value) {
console.log(this.setValue());
}
Parenizor.method('setValue', function () {
console.log('am called');
});
Parenizor.method('getValue', function () {
return 1;
});
Parenizor.method('toString', function () {
return 2;
});
And when i called the function like
var a = new Parenizor(1)
a.setValue()
It throws me error like Undefined not a function..Why is it like this ??..Hope anyone here can find my mistake ..Thanz ..:)
It seems your code comes from Classical Inheritance in JavaScript, by Douglas Crockford.
I guess you didn't read this part:
To make the examples above work, I wrote four sugar methods. First,
the method method, which adds an instance method to a class.
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
That's not how you define a method. Do it like this:
function K() {}
K.prototype.setValue = function () {};
K.prototype.getValue = function () {};
Javascript is OO, not with classes, but with prototypes.
First when you declare Parenizor, you're declaring a 'constructor'.
You probaly want this:
function Parenizor(){
var value = null;
this.setValue = function(val){
value = val;
};
this.getValue = function(){
return value;
};
this.toString = function(){
return String(value);
};
}
Or also, setting into the object prototype:
function Parenizor(){}
Parenizor.prototype._value = null;
Parenizor.prototype.setValue = function(){...};
Parenizor.prototype.getValue = function(){...};
Parenizor.prototype.toString = function(){...};

Javascript module pattern, nested functions, and sub modules

I am trying to wrap my head around javascript modules, but I'm unsure how to split up a module into further sub modules. I have read that nested functions are not really a great idea, due to performance, so how do I break up a function in a module? For example, lets say I have the following module:
var Editor = {};
Editor.build = (function () {
var x = 100;
return {
bigFunction: function () {
// This is where I need to define a couple smaller functions
// should I create a new module for bigFunction? If so, should it be nested in Editor.build somehow?
}
};
})();
bigFunction is only related to Editor.build. Should I attach the smaller functions that make up bigFunction to the prototype bigFunction object? I'm not even sure if that would make sense.
var Editor = {};
Editor.build = (function () {
var x = 100;
return {
bigFunction: function () {
bigFunction.smallFunction();
bigFunction.prototype.smallFunction = function(){ /*do something */ };
// not sure if this even makes sense
}
};
})();
Can someone please throw me in the right direction here? There is so much misleading information online, and would just like a definite guide on how to deal with this sort of modularization.
Thank you.
Here is a snippet I use to make names for an input:
var dynamicCounter = 0;
//custom dropdown names
var createContainerNames = function () {
function Names() {
this.id = "Tasks_" + dynamicCounter + "__ContainerId";
this.name = "Tasks[" + dynamicCounter + "].ContainerId";
this.parent = "task" + dynamicCounter + "Container";
}
Names.prototype = { constructor: Names };
return function () { return new Names(); };
} ();
And then I use it:
var createdNames = createContainerNames();
var createdId = createdNames.id;
dynamicCounter++;
var differentNames = createContainerNames();
var differentId = differentNames.id;
Another approach would be to do this:
var NameModule = function(){
//"private" namemodule variables
var priv1 = "Hello";
//"private namemodule methods
function privMethod1(){
//TODO: implement
}
//"public namemodule variables
var pub1 = "Welcome";
//"public" namemodule methods
function PubMethod(){
//TODO: pub
}
return {
pub1 : pub1,
PubMethod: PubMethod
};
and then to use it
var myPubMethod = new NameModule();
myPubMethod.PubMethod();
var pubVar = myPubMethod.pub1;
EDIT
You could also take this approach:
var mod = function(){
this.modArray = [];
};
mod.prototype = {
//private variables
modId: null,
//public method
AddToArray: function (obj) {
this.modArray.push(obj);
}
}

Categories

Resources