What is the use of declaring variable inside constructor - javascript

I was studying class based structure in Javascript
To say the least, I created a simple class
class something {
constructor() {
var name = "somexyz"
this.age = 13
}
somefunc () {
console.log(this.name)//Undefined
console.log(name) //blank space
console.log(this.age) //13
}
}
And then call it using
let foo = new something()
foo.somefunc()
Which consoles.log (mentioned in comments of above code)
1. undefined
2. empty space
3. 13
or take a constructor function
function something () {
this.age = 11
let age = 13
this.getAge = function () {
return this.age
}
}
Here,
let somethingNew = new something()
Will return age as 11
Now, my question is what exactly is the purpose of having variable in constructors then?

The emphasis should be on "simple class" - the notion of a local variable seems pointless but it's actually very useful.
Simple example - when you reuse a variable repeatedly
class transport
{
constructor ()
{
const someString = "IUseThisAgainAndAgain";
this.type = 'someType';
this.name = 'someName';
this.serial = someString + "SOMETHING";
this.model = someString + "something thing";
this.example = someString + "another string concat";
}
}
As you can see we use someString alot. And you will see constructor method that are huge and having a variable for a repeated instance will allow better readability of code and allow you to easily modify the instance in one place.

You can use variables to set a default value also for checking purposes or mathematical calculations.
For example:
class something {
constructor(age) {
var default_age = "13";
if(age > 13){
this.age = age;
}else{
this.age = default_age;
}
}
myage() {
console.log("I am "+this.age+" years old.")
}
}
var newobj = new something(15);
newobj.myage();
var newobj2 = new something(8);
newobj2.myage();

vars in constructor are only defined in the scope of the constructor
In this case "" is a string that is present in the global scope. Not finding name in the current scope of the method execution, it is finded moved up to the window.name. Try to change name with something else (ex: name2) and You'll get an error.
For logging "somexyz" see the snippet below
Of course, the local variables in the constructor should be useful for the logic of the constructor itself
class something {
constructor() {
var name = "somexyz"
var name2 = "somexyz"
this.age = 13
}
somefunc () {
console.log(this.name)//undefined
console.log(name) //window.name
console.log(window.name) //window.name
console.log(this.__proto__.constructor.name) //"something"
console.log(this.age) //13
}
}
let foo = new something()
foo.somefunc()

Related

Adding a method to an object that is inside of a function in js

Hi this is from a challenge I was working on. Is there any way i can add the introduce method to the personStore object without using the keyword this. Any insight is greatly appreciated.
Using Object.create
Challenge 1/3
Inside personStore object, create a property greet where the value is a function that logs "hello".
Challenge 2/3
Create a function personFromPersonStore that takes as input a name and an age. > When called, the function will create person objects using the Object.create method on the personStore object.
Challenge 3/3
Without editing the code you've already written, add an introduce method to the personStore object that logs "Hi, my name is [name]".
Side Curiosity
As a side note, was curious if there was a way to add the introduce method to the person object that sits inside of the personFromPersonStore function.
my solution:
var personStore = {
// add code here
greet: function (){
console.log('Hello');
}
};
function personFromPersonStore(name, age) {
var person = Object.create(personStore);
person.name = name;
person.age = age;
person.greet = personStore.greet;
return person;
};
personStore.introduce = function () {
console.log('Hi, my name is ' + this.name)
}
//Challenge 3 Tester
sandra.introduce(); // -> Logs 'Hi, my name is Sandra
You can, but using this is a lot simpler.
This code passes the name property as an argument, but as the property is already accessible to the introduce function as an internal property via this, it is a bit wasteful.
var personStore = {
// add code here
greet: function (){
console.log('Hello');
}
};
function personFromPersonStore(name, age) {
var person = Object.create(personStore);
person.name = name;
person.age = age;
person.greet = personStore.greet;
return person;
};
personStore.introduce = function (nm) {
console.log('Hi, my name is ' + nm)
}
person1=personFromPersonStore('Fred',21);
person1.introduce(person1.name);
You can write it like this:
personFromPersonStore("whatevername","whateverage").name
instead of this.

Setters in Javascript

I want to block the assignment of properties only by the set name function because I want to do some formatting or validation before, look the example:
class Animal {
construct(name){
this.name = name;
return this;
}
setName(name){
this.name = name;
}
getName(){
return this.name;
}
}
class Dog extends Animal {
constructor(name){
super(name);
return this;
}
setName(name){
this.name = name.charAt(0).toUpperCase() + name.slice(1);
}
}
const dog = new Dog();
dog.setName('joe');
console.log(dog.getName()); //Joe
dog.name = 'Bill'; // I wish this type of assignment would not work
console.log(dog.getName()); //Bill
It is possible to do this or something similar ?
You can't lock it down 100%, but there is the setter syntax:
class Foo {
constructor(x) {
this.x = x;
}
set x(newX) {
this._x = newX.charAt(0).toUpperCase() + newX.slice(1);
}
get x() {
return this._x;
}
}
const foo = new Foo('hello');
console.log(foo.x); // Hello
foo.x = 'goodbye';
console.log(foo.x); // Goodbye
To be fair, though, I'd have this logic on the getter, rather than the setter. You generally do these cosmetic things on output, not on input.
Note that this still doesn't prevent your consumer from editing foo._x, there are no private variables in JavaScript.
It is possible indeed!
If you look at the mdn page for set, you'll get some nice clues to how to solve your problem.
The general gist is that you can define set propName as a function to which the new value is set, and within that function you can apply any transformation!
You can define accessors but you can not have them together with values. Mozilla documentation:
It is not possible to simultaneously have a getter bound to a property and have that property actually hold a value
I answered this already with an example for arrays.

JS using class variable [duplicate]

Can JavaScript classes/objects have constructors? How are they created?
Using prototypes:
function Box(color) // Constructor
{
this.color = color;
}
Box.prototype.getColor = function()
{
return this.color;
};
Hiding "color" (somewhat resembles a private member variable):
function Box(col)
{
var color = col;
this.getColor = function()
{
return color;
};
}
Usage:
var blueBox = new Box("blue");
alert(blueBox.getColor()); // will alert blue
var greenBox = new Box("green");
alert(greenBox.getColor()); // will alert green
Here's a template I sometimes use for OOP-similar behavior in JavaScript. As you can see, you can simulate private (both static and instance) members using closures. What new MyClass() will return is an object with only the properties assigned to the this object and in the prototype object of the "class."
var MyClass = (function () {
// private static
var nextId = 1;
// constructor
var cls = function () {
// private
var id = nextId++;
var name = 'Unknown';
// public (this instance only)
this.get_id = function () { return id; };
this.get_name = function () { return name; };
this.set_name = function (value) {
if (typeof value != 'string')
throw 'Name must be a string';
if (value.length < 2 || value.length > 20)
throw 'Name must be 2-20 characters long.';
name = value;
};
};
// public static
cls.get_nextId = function () {
return nextId;
};
// public (shared across instances)
cls.prototype = {
announce: function () {
alert('Hi there! My id is ' + this.get_id() + ' and my name is "' + this.get_name() + '"!\r\n' +
'The next fellow\'s id will be ' + MyClass.get_nextId() + '!');
}
};
return cls;
})();
I've been asked about inheritance using this pattern, so here goes:
// It's a good idea to have a utility class to wire up inheritance.
function inherit(cls, superCls) {
// We use an intermediary empty constructor to create an
// inheritance chain, because using the super class' constructor
// might have side effects.
var construct = function () {};
construct.prototype = superCls.prototype;
cls.prototype = new construct;
cls.prototype.constructor = cls;
cls.super = superCls;
}
var MyChildClass = (function () {
// constructor
var cls = function (surName) {
// Call super constructor on this instance (any arguments
// to the constructor would go after "this" in call(…)).
this.constructor.super.call(this);
// Shadowing instance properties is a little bit less
// intuitive, but can be done:
var getName = this.get_name;
// public (this instance only)
this.get_name = function () {
return getName.call(this) + ' ' + surName;
};
};
inherit(cls, MyClass); // <-- important!
return cls;
})();
And an example to use it all:
var bob = new MyClass();
bob.set_name('Bob');
bob.announce(); // id is 1, name shows as "Bob"
var john = new MyChildClass('Doe');
john.set_name('John');
john.announce(); // id is 2, name shows as "John Doe"
alert(john instanceof MyClass); // true
As you can see, the classes correctly interact with each other (they share the static id from MyClass, the announce method uses the correct get_name method, etc.)
One thing to note is the need to shadow instance properties. You can actually make the inherit function go through all instance properties (using hasOwnProperty) that are functions, and automagically add a super_<method name> property. This would let you call this.super_get_name() instead of storing it in a temporary value and calling it bound using call.
For methods on the prototype you don't need to worry about the above though, if you want to access the super class' prototype methods, you can just call this.constructor.super.prototype.methodName. If you want to make it less verbose you can of course add convenience properties. :)
It seems to me most of you are giving example of getters and setters not a constructor, ie http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming).
lunched-dan was closer but the example didn't work in jsFiddle.
This example creates a private constructor function that only runs during the creation of the object.
var color = 'black';
function Box()
{
// private property
var color = '';
// private constructor
var __construct = function() {
alert("Object Created.");
color = 'green';
}()
// getter
this.getColor = function() {
return color;
}
// setter
this.setColor = function(data) {
color = data;
}
}
var b = new Box();
alert(b.getColor()); // should be green
b.setColor('orange');
alert(b.getColor()); // should be orange
alert(color); // should be black
If you wanted to assign public properties then the constructor could be defined as such:
var color = 'black';
function Box()
{
// public property
this.color = '';
// private constructor
var __construct = function(that) {
alert("Object Created.");
that.color = 'green';
}(this)
// getter
this.getColor = function() {
return this.color;
}
// setter
this.setColor = function(color) {
this.color = color;
}
}
var b = new Box();
alert(b.getColor()); // should be green
b.setColor('orange');
alert(b.getColor()); // should be orange
alert(color); // should be black
So what is the point of "constructor"
property? Cannot figure out where it
could be useful, any ideas?
The point of the constructor property is to provide some way of pretending JavaScript has classes. One of the things you cannot usefully do is change an object's constructor after it's been created. It's complicated.
I wrote a fairly comprehensive piece on it a few years ago: http://joost.zeekat.nl/constructors-considered-mildly-confusing.html
Example here: http://jsfiddle.net/FZ5nC/
Try this template:
<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Name = Name||{};
Name.Space = Name.Space||{};
//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Name.Space.ClassName = function Name_Space_ClassName(){}
//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Name.Space.ClassName.prototype = {
v1: null
,v2: null
,f1: function Name_Space_ClassName_f1(){}
}
//============================================================
// Static Variables
//------------------------------------------------------------
Name.Space.ClassName.staticVar = 0;
//============================================================
// Static Functions
//------------------------------------------------------------
Name.Space.ClassName.staticFunc = function Name_Space_ClassName_staticFunc(){
}
</script>
You must adjust your namespace if you are defining a static class:
<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};
Shape.Rectangle = Shape.Rectangle||{};
// In previous example, Rectangle was defined in the constructor.
</script>
Example class:
<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};
//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Shape.Rectangle = function Shape_Rectangle(width, height, color){
this.Width = width;
this.Height = height;
this.Color = color;
}
//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Shape.Rectangle.prototype = {
Width: null
,Height: null
,Color: null
,Draw: function Shape_Rectangle_Draw(canvasId, x, y){
var canvas = document.getElementById(canvasId);
var context = canvas.getContext("2d");
context.fillStyle = this.Color;
context.fillRect(x, y, this.Width, this.Height);
}
}
//============================================================
// Static Variables
//------------------------------------------------------------
Shape.Rectangle.Sides = 4;
//============================================================
// Static Functions
//------------------------------------------------------------
Shape.Rectangle.CreateSmallBlue = function Shape_Rectangle_CreateSmallBlue(){
return new Shape.Rectangle(5,8,'#0000ff');
}
Shape.Rectangle.CreateBigRed = function Shape_Rectangle_CreateBigRed(){
return new Shape.Rectangle(50,25,'#ff0000');
}
</script>
Example instantiation:
<canvas id="painting" width="500" height="500"></canvas>
<script>
alert("A rectangle has "+Shape.Rectangle.Sides+" sides.");
var r1 = new Shape.Rectangle(16, 12, "#aa22cc");
r1.Draw("painting",0, 20);
var r2 = Shape.Rectangle.CreateSmallBlue();
r2.Draw("painting", 0, 0);
Shape.Rectangle.CreateBigRed().Draw("painting", 10, 0);
</script>
Notice functions are defined as A.B = function A_B(). This is to make your script easier to debug. Open Chrome's Inspect Element panel, run this script, and expand the debug backtrace:
<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Fail = Fail||{};
//============================================================
// Static Functions
//------------------------------------------------------------
Fail.Test = function Fail_Test(){
A.Func.That.Does.Not.Exist();
}
Fail.Test();
</script>
This is a constructor:
function MyClass() {}
When you do
var myObj = new MyClass();
MyClass is executed, and a new object is returned of that class.
Yes, you can define a constructor inside a class declaration like this:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
I found this tutorial very useful. This approach is used by most of jQuery plug-ins.
http://www.htmlgoodies.com/html5/tutorials/create-an-object-oriented-javascript-class-constructor.html#fbid=OVYAQL_TDpK
var Class = function(methods) {
var klass = function() {
this.initialize.apply(this, arguments);
};
for (var property in methods) {
klass.prototype[property] = methods[property];
}
if (!klass.prototype.initialize) klass.prototype.initialize = function(){};
return klass;
};
Now ,
var Person = Class({
initialize: function(name, age) {
this.name = name;
this.age = age;
},
toString: function() {
return "My name is "+this.name+" and I am "+this.age+" years old.";
}
});
var alice = new Person('Alice', 26);
alert(alice.name); //displays "Alice"
alert(alice.age); //displays "26"
alert(alice.toString()); //displays "My name is Alice and I am 26 years old" in most browsers.
//IE 8 and below display the Object's toString() instead! "[Object object]"
This pattern has served me well. With this pattern, you create classes in separate files, load them into your overall app "as needed".
// Namespace
// (Creating new if not instantiated yet, otherwise, use existing and just add to it)
var myApp = myApp || {};
// "Package"
// Similar to how you would establish a package in other languages
(function() {
// "Class"
var MyClass = function(params) {
this.initialize(params);
}
// "Private Static" vars
// - Only accessible to functions in this class.
// - Doesn't get wiped out when we create a new instance.
var countInstances = 0;
var allInstances = [];
// "Private Static" functions
// - Same as above, but it's a function accessible
// only to other functions in this class.
function doSomething(){
}
// "Public Static" vars
// - Everyone has access.
// - Doesn't get wiped out when we create a new instance.
MyClass.counter = 0;
// "Public Static" functions
// - Same as above, but anyone can call this "static method".
// - Kinda like a singleton class situation.
MyClass.foobar = function(){
}
// Public properties and methods are built into the "prototype"
// - This is how each instance can become unique unto itself.
// - Establishing "p" as "local" (Static Private) variable
// simply so we don't have to keep typing "MyClass.prototype"
// for each property and function.
var p = MyClass.prototype;
// "Public" vars
p.id = null;
p.firstname = null;
p.lastname = null;
// "Private" vars
// - Only used by "this" instance.
// - There isn't "true" privacy for each
// instance so we have to fake it.
// - By tradition, we indicate "privacy"
// by prefixing it with an underscore.
// - So technically, anyone can access, but we simply
// don't tell anyone about it (e.g. in your API)
// so no one knows about it :)
p._foo = null;
p.initialize = function(params){
this.id = MyClass.counter++;
this.firstname = params.firstname;
this.lastname = params.lastname;
MyClass.counter++;
countInstances++;
allInstances.push(this);
}
p.doAlert = function(theMessage){
alert(this.firstname + " " + this.lastname + " said: " + theMessage + ". My id:" + this.id + ". Total People:" + countInstances + ". First Person:" + allInstances[0].firstname + " " + allInstances[0].lastname);
}
// Assign class to app
myApp.MyClass = MyClass;
// Close the "Package"
}());
// Usage example:
var bob = new myApp.MyClass({ firstname : "bob",
lastname : "er"
});
bob.doAlert("hello there");
I guess I'll post what I do with javascript closure since no one is using closure yet.
var user = function(id) {
// private properties & methods goes here.
var someValue;
function doSomething(data) {
someValue = data;
};
// constructor goes here.
if (!id) return null;
// public properties & methods goes here.
return {
id: id,
method: function(params) {
doSomething(params);
}
};
};
Comments and suggestions to this solution are welcome. :)
Maybe it's gotten a little simpler, but below is what I've come up with now in 2017:
class obj {
constructor(in_shape, in_color){
this.shape = in_shape;
this.color = in_color;
}
getInfo(){
return this.shape + ' and ' + this.color;
}
setShape(in_shape){
this.shape = in_shape;
}
setColor(in_color){
this.color = in_color;
}
}
In using the class above, I have the following:
var newobj = new obj('square', 'blue');
//Here, we expect to see 'square and blue'
console.log(newobj.getInfo());
newobj.setColor('white');
newobj.setShape('sphere');
//Since we've set new color and shape, we expect the following: 'sphere and white'
console.log(newobj.getInfo());
As you can see, the constructor takes in two parameters, and we set the object's properties. We also alter the object's color and shape by using the setter functions, and prove that its change remained upon calling getInfo() after these changes.
A bit late, but I hope this helps. I've tested this with a mocha unit-testing, and it's working well.
Using Nick's sample above, you can create a constructor for objects without parameters using a return statement as the last statement in your object definition. Return your constructor function as below and it will run the code in __construct each time you create the object:
function Box()
{
var __construct = function() {
alert("Object Created.");
this.color = 'green';
}
this.color = '';
this.getColor = function() {
return this.color;
}
__construct();
}
var b = new Box();
They do if you use Typescript - open source from MicroSoft :-)
class BankAccount {
balance: number;
constructor(initially: number) {
this.balance = initially;
}
deposit(credit: number) {
this.balance += credit;
return this.balance;
}
}
Typescript lets you 'fake' OO constructs that are compiled into javascript constructs. If you're starting a large project it may save you a lot of time and it just reached milestone 1.0 version.
http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf
The above code gets 'compiled' to :
var BankAccount = (function () {
function BankAccount(initially) {
this.balance = initially;
}
BankAccount.prototype.deposit = function (credit) {
this.balance += credit;
return this.balance;
};
return BankAccount;
})();
In JavaScript the invocation type defines the behaviour of the function:
Direct invocation func()
Method invocation on an object obj.func()
Constructor invocation new func()
Indirect invocation func.call() or func.apply()
The function is invoked as a constructor when calling using new operator:
function Cat(name) {
this.name = name;
}
Cat.prototype.getName = function() {
return this.name;
}
var myCat = new Cat('Sweet'); // Cat function invoked as a constructor
Any instance or prototype object in JavaScript have a property constructor, which refers to the constructor function.
Cat.prototype.constructor === Cat // => true
myCat.constructor === Cat // => true
Check this post about constructor property.
While using Blixt's great template from above, I found out that it doesn't work well with multi-level inheritance (MyGrandChildClass extending MyChildClass extending MyClass) – it cycles on calling first parent's constructor over and over. So here is a simple workaround – if you need multi-level inheritance, instead of using this.constructor.super.call(this, surName); use chainSuper(this).call(this, surName); with the chain function defined like this:
function chainSuper(cls) {
if (cls.__depth == undefined) cls.__depth = 1; else cls.__depth++;
var depth = cls.__depth;
var sup = cls.constructor.super;
while (depth > 1) {
if (sup.super != undefined) sup = sup.super;
depth--;
}
return sup;
}
http://www.jsoops.net/ is quite good for oop in Js. If provide private, protected, public variable and function, and also Inheritance feature. Example Code:
var ClassA = JsOops(function (pri, pro, pub)
{// pri = private, pro = protected, pub = public
pri.className = "I am A ";
this.init = function (var1)// constructor
{
pri.className += var1;
}
pub.getData = function ()
{
return "ClassA(Top=" + pro.getClassName() + ", This=" + pri.getClassName()
+ ", ID=" + pro.getClassId() + ")";
}
pri.getClassName = function () { return pri.className; }
pro.getClassName = function () { return pri.className; }
pro.getClassId = function () { return 1; }
});
var newA = new ClassA("Class");
//***Access public function
console.log(typeof (newA.getData));
// function
console.log(newA.getData());
// ClassA(Top=I am A Class, This=I am A Class, ID=1)
//***You can not access constructor, private and protected function
console.log(typeof (newA.init)); // undefined
console.log(typeof (newA.className)); // undefined
console.log(typeof (newA.pro)); // undefined
console.log(typeof (newA.getClassName)); // undefined
just to offer up some variety. ds.oop is a nice way to declare classes with constructors in javascript. It supports every possible type of inheritance (Including 1 type that even c# does not support) as well as Interfaces which is nice.
var Color = ds.make.class({
type: 'Color',
constructor: function (r,g,b) {
this.r = r; /* now r,g, and b are available to */
this.g = g; /* other methods in the Color class */
this.b = b;
}
});
var red = new Color(255,0,0); // using the new keyword to instantiate the class
Here we need to notice one point in java script, it is a class-less language however,we can achieve it by using functions in java script. The most common way to achieve this we need to create a function in java script and use new keyword to create an object and use this keyword to define property and methods.Below is the example.
// Function constructor
var calculator=function(num1 ,num2){
this.name="This is function constructor";
this.mulFunc=function(){
return num1*num2
};
};
var objCal=new calculator(10,10);// This is a constructor in java script
alert(objCal.mulFunc());// method call
alert(objCal.name);// property call
//Constructors With Prototypes
var calculator=function(){
this.name="Constructors With Prototypes";
};
calculator.prototype.mulFunc=function(num1 ,num2){
return num1*num2;
};
var objCal=new calculator();// This is a constructor in java script
alert(objCal.mulFunc(10,10));// method call
alert(objCal.name); // property call
In most cases you have to somehow declare the property you need before you can call a method that passes in this information. If you do not have to initially set a property you can just call a method within the object like so. Probably not the most pretty way of doing this but this still works.
var objectA = {
color: '';
callColor : function(){
console.log(this.color);
}
this.callColor();
}
var newObject = new objectA();

In javascript, Is there a perfect way to define class

I am looking for a perfect way to define class. "perfect" here means:`
create instances will not create copies of methods.
public function could easily(not to much hassle) access private variable
For example, way 1:
function Foo1() {
var private1;
this.publicMethod1 = function() {//create instance will create copy of this function}
}
will not meet rule No.1 above.
Another example, way 2:
function Foo2() {
var private2;
}
Foo2.prototype.Method2 = function() {//cannot access private2}
will not meet rule No.2 above.
So is it possible to meet both rules? Thanks.
In JavaScript it's more about conventions. Private properties or methods are defined with a underscore first like _private. With a few helpers you can make classes easily. I find this setup easy enough, all you need is a helper inherits to extend classes, and instead of using multiple arguments you pass in an object props and simply call "super" on the inherited classes with arguments. For example, using a module pattern:
Function.prototype.inherits = function(parent) {
this.prototype = Object.create(parent.prototype);
};
var Person = (function PersonClass() {
function Person(props) {
this.name = props.name || 'unnamed';
this.age = props.age || 0;
}
Person.prototype = {
say: function() {
return 'My name is '+ this.name +'. I am '+ this.age +' years old.';
}
};
return Person;
}());
var Student = (function StudentClass(_super) {
Student.inherits(_super);
function Student(props) {
_super.apply(this, arguments);
this.grade = props.grade || 'untested';
}
Student.prototype.say = function() {
return 'My grade is '+ this.grade +'.';
};
return Student;
}(Person));
var john = new Student({
name: 'John',
age: 25,
grade: 'A+'
});
console.log(JSON.stringify(john)); //=> {"name":"John","age":25,"grade":"A+"}
console.log(john.say()); //=> "My grade is A+"
About the private variable "issue" just stick to convention for instance properties and use closures when needed for everything else private.
function Foo3() {
this.private = {};
}
Foo3.prototype.set_x = function (x) {
this.private.x = x;
};
To make a long story short: no, it is not. You cannot extend the prototype with methods that could access private variables. At least if these private variables are made private via a closure.
Though, it is a convention in javascript that you mark your private fields with an underscore, for example _myPrivateField. These would be still public, but i have seen this solution being used in many libraries and i also prefer that style to meet your first rule.
A basic example is below:
Foo = function(id)
{
// private instances.
var _id;
var _self = this;
// constructor
_id = id;
// private method
function _get()
{
return _id;
};
// public function
_self.set = function(id)
{
_id = id;
};
_self.get = function()
{
return _get();
};
};
var bar = Foo(100);
console.log( bar.get() );
bar.set(1000);
console.log( bar.get() );
I would recommend you use prototype.

how do i namespace pseudo-classical javascript

I have some simple OO code I've written that I'm playing with:
//define a constructor function
function person(name, sex) {
this.name = name;
this.sex = sex;
}
//now define some instance methods
person.prototype.returnName = function() {
alert(this.name);
}
person.prototype.returnSex = function() {
return this.sex;
}
person.prototype.talk = function(sentence) {
return this.name + ' says ' + sentence;
}
//another constructor
function worker(name, sex, job, skills) {
this.name = name;
this.sex = sex;
this.job = job;
this.skills = skills;
}
//now for some inheritance - inherit only the reusable methods in the person prototype
//Use a temporary constructor to stop any child overwriting the parent prototype
var f = function() {};
f.prototype = person.prototype;
worker.prototype = new f();
worker.prototype.constructor = worker;
var person = new person('james', 'male');
person.returnName();
var hrTeamMember = new worker('kate', 'female', 'human resources', 'talking');
hrTeamMember.returnName();
alert(hrTeamMember.talk('I like to take a lot'));
Now this is all well and good. But I'm confused. I want to include namespacing as part of my code writing practice. How can I namespace the above code. As it is now I have 2 functions defined in the global namespace.
The only way I can think to do this is to switch to object literal syntax. But then how do I implement the pseudo-classical style above with object literals.
You could for example do following:
var YourObject;
if (!YourObject) {
YourObject = {};
YourObject.Person = function(name, sex) {
// ...
}
YourObject.Person.prototype.returnName = function() {
// ...
}
// ...
}
You don't have to use object literals, at least, not exclusively.
Decide on the single global symbol you'd like to use.
Do all your declaration work in an anonymous function, and explicitly attach "public" methods as desired to your global object:
(function(global) {
// all that stuff
global.elduderino = {};
global.elduderino.person = person;
global.elduderino.worker = worker;
})(this);
I may not be completely understanding the nuances of your issue here, but the point I'm trying to make is that Javascript makes it possible for you to start with your symbols being "hidden" as locals in a function, but they can be selectively "exported" in various ways.

Categories

Resources