javascript objects questions - javascript

I am from c# object oriented background and which to work similar priniciples in javascript. Any good I articles that could help with me research?
This is an example i put together for a Product Javascript object:
function Product() {
this.reset = function () {
this.id = 0;
this.name = '';
}
}
Product.prototype = {
loadFromJson: function (json) {
this.reset();
this.id = json.Id;
this.name = json.Name;
},
checkAvailability: function (qty) {
// Just to illustrate
return true;
}
};
So to create an instance of Product:
var p = new Product();
To access a public method:
var isAvailable = p.checkAvailability(1);
To access a public property:
var name = p.name;
Is the reset function I create a valid private function?
Is what I am doing above correct or is there a better way? I am new to this!
Also, if I create an instance of product in another javascript file, can I get intellisence on the properties of the Product object?

The reset is this.reset(); so that is in the scope of the object and thus could be called public, but remains in that scope. In your example p.reset(); but reset(); fails.
Better way? It depends, some circumstances require this complex, some do not. There are a number of ways to instantiate objects (everything is an object in JavaScript) and your examples are some of the ways.
No intellisence unless you build and attach your own (a LOT of work). (search on jQuery intellisence to see how that is done)
See this for some more regarding namespace. Note the internal and public functions and variables.
var myStuffApp = new function()
{
var internalFunction = function()
{
alert('soy una función interna');
};
this.publicFunction = function()
{
alert('soy una función pública');
};
var test1 = 'testing 1';//private/internal
this.test2 = 'testing 2';// namespaced
testA="ho";// global
};

I suggest the read this msdn page for basic information. It's like a crash course for c# oriented developers.

Is the reset function I create a valid private function?
No. It differs from the functions set on prototype because you get a different copy of reset for every instance of Product:
var p1= new Product();
var p2= new Product();
alert(p1.loadFromJson===p2.loadFromJson); // true
alert(p1.reset===p2.reset); // false
but it is not private. You can still do:
var p= new Product();
p.reset();
Whilst you can do private functions in JavaScript using closures, it's almost never worth it. Consider just using the Python convenition of naming all members you don't intend to be used outside the implementation with a preceding underscore.
See this question for extensive discussion of JS object models.

Related

Javascript - how do you add properties to an object constructor function

How do I add properties to a constructor function in JavaScript? For example. If I have the following function.
function Hotel(name)
{
this.name = name;
};
var hotel1 = new Hotel('Park');
can I add a "local" variable that can be used locally within the class as if it were private with the same notation using the keyword "this". Of course it would not be private since objects created will be able to use it correct?
Can I do something like this. Do I use the this keyword or do I use the var keyword
which one is it? I have example 2 on the function constructor on the bottom
1. var numRooms = 40;
2. this.numRooms = 40;
3. numRooms : 40,
function Hotel(name)
{
this.name = name;
this.numRooms = 40;
};
I know that if I want a function within the object constructor I need to use the this word. Will that work as well for normal variables as I have asked above.
function Hotel(name)
{
this.name = name;
this.numRooms = 40;
this.addNumRoomsPlusFive = function()
{
return this.numRooms + 5;
}
};
You can simple add a private variable to your constructor:
function Hotel(name) {
var private = 'private';
this.name = name;
};
But if you will use your Hotel function without a new operator, all properties and functions which was attached to this will become global.
function Hotel(name) {
var private = 'private';
this.name = name;
};
var hotel = Hotel('test');
console.log(name); // test
It is good idea to return an object in constructor function:
function Hotel(name) {
var
private_var = 'private',
private_func = function() {
// your code
};
retur {
name: 'name',
public_func: private_func
}
};
var hotel = Hotel('test');
console.log(name); // undefined
So if you will use Hotel constructor without new operator no global variable will be created. This is possible only if the return value is an object. Otherwise, if you try to return anything that is not an object, the constructor will proceed with its usual behaviour and return this.
can I add a "local" variable that can be used locally within the class as if it were private with the same notation using the keyword "this".
Yes we can:
// API implementation in the library
function Hotel(name) {
// only our library code knows about the actual value
const numRooms = 'privateNoRoomsVar';
this.name = name;
this[numRooms] = 40;
this.addNumRoomsPlusFive = function() {
return this[numRooms] + 5;
}
};
// from the library user's perspective
const hotel = new Hotel('Transylvania');
console.log('rooms+5 =', hotel.addNumRoomsPlusFive());
console.log('hotel.numRooms =', hotel.numRooms); // undefined
// also, users don't have access to 'numRooms' variable so they can't use hotel[numRooms].
If a user looks at the source code and finds out the value privateNoRoomsVar, then they can misuse the API.
For that we need to use symobls:
// API implementation in the library
function Hotel(name) {
// no one can duplicate a symbol so the variable is really private
const numRooms = Symbol();
this.name = name;
this[numRooms] = 40;
this.addNumRoomsPlusFive = function() {
return this[numRooms] + 5;
}
};
// from the library user's perspective
const hotel = new Hotel('Transylvania');
console.log('rooms+5 =', hotel.addNumRoomsPlusFive());
console.log('hotel.numRooms =', hotel.numRooms); // undefined
// there is no way users will get access to the symbol object so the variable remains private.
Private class features, #privateField, are supported by all the browsers so we don’t have to worry about this anymore.
// API implementation in the library
class Hotel {
// private field
#numRooms = 40;
constructor(name) {
this.name = name;
}
addNumRoomsPlusFive() {
return this.#numRooms + 5;
}
};
// from the library user's perspective
const hotel = new Hotel('Transylvania');
console.log('rooms+5 =', hotel.addNumRoomsPlusFive());
console.log('hotel.numRooms =', hotel.numRooms); // undefined
//console.log('hotel.numRooms =', hotel.#numRooms); // throws error
Javascript historically creates objects from prototypes of other objects. It was a result of EMCA2015, that you have a distinct syntax of a class that specifies an object. As an aside, if you mouse over the table in that link it gives dates of when the feature was implemented.
A javascript object created by the new operator is more or less a combination of an associative array ( what you make with let avar={}; ) that can access the function level scopes it is defined in. The keys of the array are its properties. According to its creator, Javascript was created to be an easy to use program language without a hierarchy of types. One of the ways it accomplished this is by more or less considering its mapping type to be equivalent to the prototypical Object which object oriented programming languages describe.
Adding properties in 2022
function AProtoype(arg1, arg2, arg3){
//this defines a property
this.pa=arg1;
/* unicorns in this section */
let x = 1;
/*
a getter which has the same syntax as a property
but returns x from the scope which it references and
not the object.
*/
get getx() => x;
}
let object = new AProtoype(2,3,4);
Is equivalent to the following code for the purposes of data access but not inheritance and typing. The new operator also sets variables on an object that are used for these purposes.
function NewObject(arg1, arg2, arg3){
let prototype = {};
/*dragons in this section, as you are not using the this keyword to accomplish things*/
prototype.pa = arg1;
Object.defineProperty(prototype, "getx", {get:()=>x});
return prototype;
}
//If you do this instead of using the new operator it is an anti-pattern.
//And like all anti-patterns: "But it works!"
let object = NewObject(2,3,4);
The relevant property defining methods where in some sense supported as early as 2010, 2011. I do not have a contemporary source to that time to confirm if you could pull off what I'm doing though, and you'd only want to if all else failed and it needed to run on Internet Explorer 9. In the event all else is failing, you may want to read the documentation for Object.create, which is also of interest because more or less provides an api to make new objects.
Now, for a fun time and horror, you can also define a function that returns this, and get an object back with an equivalent binding of that function. The horror comes when it is an object in global scope, and you rename a property of that object; as Javascript will resolve the name collision by happily writing on whatever it finds if it can. You can then use this to re-implement the prototype pattern that javascripts new operator is built off of conceptually, for the sake of science.
When you use a "constructor function" in Javascript, any properties defined on the instance using the this keyword become public. This is unavoidable, because Javascript objects have no concept of private properties - if it exists, it can be accessed directly as object.property.
For example, if you tried to do as in the following snippet, mimicking a typical getter/setter pattern with a private variable in Java or C# (note that even if this worked, this is not idiomatic Javascript):
function MyObject(privateVar) {
this.privateVar = privateVar;
}
MyObject.prototype.getVar = function() {
return this.privateVar;
};
MyObject.prototype.setVar = function(newVal) {
this.privateVar = newVal;
};
then while you can indeed use the getter and setter to do as you expect, you can also just access and set the private variable directly! Demonstration:
function MyObject(privateVar) {
this.privateVar = privateVar;
}
MyObject.prototype.getVar = function() {
return this.privateVar;
};
MyObject.prototype.setVar = function(newVal) {
this.privateVar = newVal;
};
var obj = new MyObject(1);
// using public getter/setter
console.log(obj.getVar()); // 1
obj.setVar(2);
console.log(obj.getVar()); // 2
// using private variable directly - not intended to work
console.log(obj.privateVar); // 2
obj.privateVar = 3;
console.log(obj.getVar()); // 3 (using public API to get it to show that the direct update to the private variable also affects the intended public methods)
There is though a way to mimic the effect of private variables. They're not actually object properties - because, as I have just demonstrated, such are intrinsically public - but the same can be mimicked by:
not using a "constructor function" at all, but a regular function that happens to return an object. This is all a constructor function really does, anyway - the difference in JS is only syntactic, that you do not need to use the new keyword when you call the function. (Although you still can, if you really prefer - any function that returns an object can be called with new and behave in the same way as without it, although performance will likely suffer a little as the function would then construct a brand new object and throw it away. See MDN for a justification of these statements, particularly step 4.)
inside this function, using a regular variable as the private variable. This variable will be completely inaccessible from outside by the simple rules of scope, but you can still have the returned object retain access to it by the "magic" of closures.
Here is the above getter/setter example translated to this procedure, as well as demonstrations of it working. (I hasten to add again though, that this wouldn't be considered idiomatic code in Javascript.)
function makeObjectWithPrivateVar(privateVar) {
function getPrivateVar() {
return privateVar;
}
function setPrivateVar(newVal) {
privateVar = newVal;
}
return { getPrivateVar, setPrivateVar };
}
var obj = makeObjectWithPrivateVar(1);
// getter
console.log(obj.getPrivateVar()); // 1
// setter
obj.setPrivateVar(2);
// getter again to observe the change
console.log(obj.getPrivateVar()); // 2
// but how could we access the private var directly??
// answer, we can't
console.log(obj.privateVar); // undefined
console.log(privateVar); // ReferenceError, privateVar is not in scope!
Note finally though that it's rare in modern Javascript to use the function-based constructors in this style, since the class keyword makes it easier to mimic traditional class-based languages like Java if you really want to. And in particular, more recent browsers support private properties directly (you just have to prefix the property name with a #), so the initial code snippet translated into a class and using this feature, will work fine:
class MyObject {
#privateVar
constructor(privateVar) {
this.#privateVar = privateVar;
}
getVar() {
return this.#privateVar;
}
setVar(newVal) {
this.#privateVar = newVal;
}
}
var obj = new MyObject(1);
// using public getter/setter
console.log(obj.getVar()); // 1
obj.setVar(2);
console.log(obj.getVar()); // 2
// using private variable directly - now doesn't work
console.log(obj.privateVar); // undefined, it doesn't exist
// console.log(obj.#privateVar); // error as it's explicitly private, uncomment to see error message
Usually it's performed using closures:
var Hotel = (function() {
var numrooms=40; // some kind of private static variable
return function(name) { // constructor
this.numrooms = numrooms;
this.name = name;
};
}());
var instance = new Hotel("myname");

Does anyone know of a robust JavaScript pseudoclass class?

I'm looking for a relatively simple but efficient mechanism to implement clean looking:
public, private and protected members (with actual public/private/protected access, but still extensible)
inheritance (single or multiple)
constructor overloading (prefer not to have to count args and check types with a complex set of nested conditionals)
All right...made myself a cup of coffee before writing this. Only thing I can't help you with is overloading. But never mind, here we go:
// Class pattern with
// - dynamic prototypes
// - public, private, static, static private members
// Keeps functions named the way you want it to.
// Working example:
var YourClass = (function(){
var Pseudo = function(){
var args = arguments;
// constuct the instance in here:
var YourClass = function(){
var public = this,
private = {};
public.foo = args[0] ? args[0] : "bar";
public.staticPrivateInt = ++static_private.someInt;
private.fibo = "nacci";
// fibo is private - return it's value
// with a getter to make it "protected"
public.getFibo = function(){
return private.fibo;
}
public.setFibo = function(value){
if(typeof value === "string"){
// handle optional events here
return private.fibo = value;
}else{
return false;
}
}
};
var static = Pseudo,
static_private = {};
// statics:
static_private.someInt = 100;
static.increaseSomeInt = function(){
++static_private.someInt;
}
// extend on creation of an instance:
YourClass.prototype = args[0] || new Object(); // or anything else, just an example
return new YourClass;
};
return Pseudo;
}());
Usage:
var myInstance = new YourClass({
someCfg: true
});
console.log(myInstance.someCfg === true); // will log true
Thanks to JavaScript's lexical scoping and closures one can indeed simulate the way classes are designed in other languages like C++, Java etc.
Keep a few things in mind when using that pattern:
Variable names like static, private or public will lead to errors
when in strict mode. You can rename them if needed.
Static private variables should not be stored as static.private cause they wouldnt be private anymore (thus the variable static_private).
How it works
Basically, what you'll want is:
public members to be accessible with <object>.<member>. In Javascript, that is usually done with this.<member> = <assignment>;.
=> For convenienve, create a simple alias:
var public = this;
private members to be visible in the constructor, but not in the instance. Still they need to be accessible for public methods.
=> var private = {};
You can create simple variables to, for example var fibo="nacci";, I find private.fibo="nacci"; more readable though. Any variable created with the var keyword will not be accessible from the outer scope of the constructor function.
static members to be ready even if no instance of the class has been created yet. The usual way to do that in JavaScript is assigning a value or function to the constructor itself. See SO question here
=> Again, for readability:
var static = Pseudo;
static private members: Occasionaly, you might want to have static members that are invisible outside your constructor.
=> Use lexical scope to store them. var static_private = {};
For further reading on class patterns:
The YAHOO module pattern:
http://www.yuiblog.com/blog/2007/06/12/module-pattern/
Douglas Crockford (the JS-Hercules) on private members: http://javascript.crockford.com/private.html
http://www.google.de/search?q=javascript+class+pattern&aq=f&oq=javascript+class+pattern

Javascript object properties and functions

In JavaScript I see a few different ways, certain tasks can be performed within an object for example, the object Egg I have below.
Can anyone tell me the difference between each one, why I would use one and not the other etc
var Egg = function(){
//Properties
var shell = "cracked" // private property
this.shell = "cracked" // public property
shell: "cracked" // what is this??
//functions
function cook(){
//standard function
}
cook: function(){
//what kind of function is this?
}
//not sure what this is
details: {
//What is this? an array :S it holds 2 elements?
cost: 1.23,
make: 'Happy Egg';
}
}
Your code snippet isn't quite valid, but here are a few things it raises:
Property initializers, object initializers
You've asked what shell: cracked is. It's a property initializer. You find them in object initializers (aka "object literals"), which are written like this:
var obj = {
propName: "propValue"
};
That's equivalent to:
var obj = {};
obj.propName = "propValue";
Both of the above create an object with a property called propName which has a string value "propValue". Note that this doesn't come into it.
Functions
There are a couple of places where functions typically come into it vis-a-vis objects:
Constructor functions
There are constructor functions, which are functions you call via the new operator. Here's an example:
// Constructor function
function Foo(name) {
this.name = name;
}
// Usage
var f = new Foo("Fred");
Note the use of the keyword this in there. That's where you've seen that (most likely). When you call a constructor function via new, this refers to the new object created by the new operator.
this is a slippery concept in JavaScript (and completely different from this in C++, Java, or C#), I recommend these two (cough) posts on my blog:
You must remember this
Mythical methods
Builder/factory functions
You don't have to use constructor functions and new, another pattern uses "builder" or "factory" functions instead:
// A factory function
function fooFactory(name) {
var rv = {}; // A new, blank object
rv.name = name;
return rv;
}
// Usage
var f = fooFactory("Fred");
Private properties
You mentioned "private" properties in your question. JavaScript doesn't have private properties at all (yet, they're on their way). But you see people simulate them, by defining functions they use on the object as closures over an execution context (typically a call to a constructor function or a factory function) which contains variables no one else can see, like this:
// Constructor function
function EverUpwards() {
var counter = 0;
this.increment = function() {
return ++counter;
};
}
// Usage:
var e = new EverUpwards();
console.log(e.increment()); // "1"
console.log(e.increment()); // "2"
(That example uses a constructor function, but you can do the same thing with a factory function.)
Note that even though the function we assign to increment can access counter, nothing else can. So counter is effectively a private property. This is because the function is a closure. More: Closures are not complicated
Sure, Ben.
This sort of gets to the bottom of the dynamism of JavaScript.
First, we'll look at basics -- if you're coming from a place where you understand class-based languages, like, say, Java or C++/C#, the one that is going to make the most sense is the constructor pattern which was included very early on:
function Egg (type, radius, height, weight) {
// private properties (can also have private functions)
var cost = (type === "ostrich") ? 2.05 * weight : 0.35 * weight;
// public properties
this.type = type;
this.radius = radius;
this.height = height;
this.weight = weight;
this.cracked = false;
// this is a public function which has access to private variables of the instance
this.getCost = function () { return cost; };
}
// this is a method which ALL eggs inherit, which can manipulate "this" properly
// but it has ***NO*** access to private properties of the instance
Egg.prototype.Crack = function () { this.cracked = true; };
var myEgg = new Egg("chicken", 2, 3, 500);
myEgg.cost; // undefined
myEgg.Crack();
myEgg.cracked; // true
That's fine, but sometimes there are easier ways of getting around things.
Sometimes you really don't need a class.
What if you just wanted to use one egg, ever, because that's all your recipe called for?
var myEgg = {}; // equals a new object
myEgg.type = "ostrich";
myEgg.cost = "......";
myEgg.Crack = function () { this.cracked = true; };
That's great, but there's still a lot of repetition there.
var myEgg = {
type : "ostrich",
cost : "......",
Crack : function () { this.cracked = true; }
};
Both of the two "myEgg" objects are exactly the same.
The problem here is that EVERY property and EVERY method of myEgg is 100% public to anybody.
The solution to that is immediately-invoking functions:
// have a quick look at the bottom of the function, and see that it calls itself
// with parens "()" as soon as it's defined
var myEgg = (function () {
// we now have private properties again!
var cost, type, weight, cracked, Crack, //.......
// this will be returned to the outside var, "myEgg", as the PUBLIC interface
myReturnObject = {
type : type,
weight : weight,
Crack : Crack, // added benefit -- "cracked" is now private and tamper-proof
// this is how JS can handle virtual-wallets, for example
// just don't actually build a financial-institution around client-side code...
GetSaleValue : function () { return (cracked) ? 0 : cost; }
};
return myReturnObject;
}());
myEgg.GetSaleValue(); // returns the value of private "cost"
myEgg.Crack();
myEgg.cracked // undefined ("cracked" is locked away as private)
myEgg.GetSaleValue(); // returns 0, because "cracked" is true
Hope that's a decent start.
You are mixing syntaxes between object property declaration and simple javascript statements.
// declare an object named someObject with one property
var someObject = {
key: value
};
// declare an anonymous function with some statements in it
// and assign that to a variable named "someFunction"
var someFunction = function () {
// any javascript statements or expressions can go here
};
There's a key distinction in JavaScript between objects and functions. Objects hold a bunch of data (including functions), and functions can be used to make or modify objects, but they aren't inherently the same thing. OOP in JavaScript is based around using functions as classes. For example, take the following class:
Test = function(){
this.value = 5;
}
If you just call the function Test(), then nothing will happen. Even if you say var x = Test(), the value of x will be undefined. However, using the new keyword, magic happens! So if we say var x = new Test(), then now the variable x will contain a Test object. If you do console.log(x.value), it would print 5.
That's how we can use functions to make objects. There's also a key different in syntax--a function can contain any sort of JavaScript block you want, whether that's if statements or for loops or what have you. When declaring an object, though, you have to use the key: value syntax.
Hope that clears things up a little bit!

Implementing setter and getter in JavaScript object

I want to implement setter and getter on local
javascript variable. Here is an example function:
function someThing() {
var someLocalvariable = '';
}
// with this function I want to
// return value of someLocalvariable
// also if it is possible to implement
// setter in this way.
someThing.prototype.getLocalVar = function() {
}
I want variable to be 'realy' private. I don't wont
to use something like this:
someThing.prototype.someLocalvariable =
or
function someThing() {
this.someLocalvariable = '';
}
or attaching function inside someThing() like this:
function someThing() {
var someLocalvariable = '';
this.getLocalvariable = function() {
return someLocalvariable;
}
}
I would be very grateful for any guidance and assistance.
Your last example of what you don't want to do won't work (it has syntax errors), (it's been fixed) but I think you may have meant the usual way of doing this, which is to make the getter and setter closures within the constructor function (below).
Unfortunately, if you want truly private variables, this is just about your only option. There is no other way to get truly private, instance-specific variables. However, see "hack" below.
Here's the correct version of the usual way of doing this (which I think you said you don't want, but for completeness):
function SomeThing() {
var privateVar;
this.setPrivateVar = function(val) {
privateVar = val;
};
this.getPrivateVar = function() {
return privateVar;
};
}
// use:
var t = new Something();
t.setPrivateVar("foo");
console.log(t.getPrivateVar()); // "foo"
Like most, I first read of this pattern on Douglas Crockford's site.
This option does carry a downside: Every instance created via the SomeThing constructor function gets its own two functions. They cannot be shared between instances. So if there are going to be hundreds or thousands of SomeThing instances in your app, that's something to be considered from a memory perspective. If there are going to be a couple of hundred or fewer, it probably doesn't matter. (Those numbers are pulled out of a hat and you should not trust them, you'll have to review your code's memory use when/if there's some kind of issue; but you get the idea.)
The hack: If your instances will already have some kind of unique identifier on them as public data (or you're willing to add one, again it will be public), and if you're willing to add a fair bit of complication into the use of the instances, you can have a private cache that holds the data for all of your instances that only your code can access, and key into that cache via the unique identifier of the object. Like this (in this example, I'm allocating the id values, but you can use existing unique IDs if you have them):
var SomeThing = (function() {
var cache = {}, idAllocator = 0;
function SomeThing() {
this.id = ++idAllocator; // The unique identifier, can be a string if desired
cache[this.id] = {};
}
SomeThing.prototype.getPrivateVar = function() {
var data = cache[this.id];
return data && data.privateVar;
};
SomeThing.prototype.setPrivateVar = function(value) {
cache[this.id].privateVar = value;
};
SomeThing.prototype.destroy = function() {
delete cache[this.id];
};
return SomeThing;
})();
Here's how that works: All of the functions are closures over the cache local variable in the outer scoping function. We index into that using the unique ID of the object, which gives us an object on which we put our private data members. When the code using the instance is done using it, that code must call destroy (which is a major downside to this pattern) so we remove the private data object from cache by deleting the property for our id.
Caveats and costs:
You still have a public piece of data that is the key to your private data (id in the above)
Users of the instances created by SomeThing must call destroy on those instances when they're done with them. This is anathema to the way JavaScript's garbage handling works, but it's a requirement of the pattern above because otherwise you end up with cruft building up in the cache object.
(I wouldn't worry about this one) Eventually, if you're using the automatic id values above, you'll run out of them, if your app creates and destroys a lot of these instances. But JavaScript numbers go very high up indeed, and if that's an issue just find a different way to allocate IDs rather than the simplistic always-increasing system above.
I haven't had to use the pattern above in my work yet, but I expect there are use-cases for it involving thousands of SomeThing instances and thus the desire not to have per-instance functions.
Side note: In the above, I changed someThing to SomeThing. In JavaScript, the standard practice is for the names of normal functions to start with a lower-case letter, and for the names of constructor functions (ones you use with new) to start with a capital letter. Since SomeThing is meant to be used with new, I capped it. This is only convention, but it's an overwhelmingly popular one and, of course, it's used within the language definition itself (Date is a constructor, setHours is a function).
Use Object.defineProperty() in the function constructor in order to define your getter and setter more info here..
To make truly private (not visible to the outside) some values use a Closure,
more info can be found here.
In the following example we define a getter and setter for property temperature, where the inner "private" value is stored in a variable var temperature.
var temperature will never be visible/accessibly from the outside of Archiver() has it is a Closure.
Please note that this pattern works on ES5 as Object.defineProperty() it is not supported on ES3.
function Archiver() {
var temperature = null;
var archive = [];
Object.defineProperty(this, 'temperature', {
get: function () {
console.log('get!');
return temperature;
},
set: function (value) {
temperature = value;
archive.push({ val: temperature });
}
});
this.getArchive = function () {
return archive;
};
}
var arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]
Something like this:
function Field(val){
var value = val;
this.getValue = function(){
return value;
};
this.setValue = function(val){
value = val;
};
}
var field = new Field("test");
field.value
// => undefined
field.setValue("test2")
field.getValue()
Check ref: http://ejohn.org/blog/javascript-getters-and-setters/
Douglas Crockford has written this on implementing private members in JavaScript
That's not possible. If you have a local variable in someThing(), the function you attach to the prototype can't read its value (it's private, remember?). Your last example is the normal solution to this problem, why isn't this good enough for you?
Try these two ways to achieve setter and getter
var address = {
street : "No street",
city : "No city",
state : "No state",
get getAddress()
{
return (this.street+","+this.city+","+this.state);
},
set setAddress(theAddress)
{
var part = theAddress.toString().split(", ");
this.street = part[0] || "";
this.city = part[1] || "";
this.state = part[2] || "";
}
};
address.setAddress = "27 Sus Road, Pune, MH";
console.log(address.getAddress);
//Other setter and getter
function Square(side)
{
this._side = side;
};
Square.prototype = {
set setSide(side){
this._side = side;
},
get getSide(){
return this._side;
},
get getArea(){
return (this._side * this._side);
}
};
var mySquare = new Square(10);
mySquare.setSide = 15;
console.log("Area of square is "+mySquare.getArea+" with side "+mySquare.getSide);
First method
var address = {
street : "No street",
city : "No city",
state : "No state",
get getAddress()
{
return (this.street+","+this.city+","+this.state);
},
set setAddress(theAddress)
{
var part = theAddress.toString().split(", ");
this.street = part[0] || "";
this.city = part[1] || "";
this.state = part[2] || "";
}
};
address.setAddress = "27 Sus Road, Pune, MH";
console.log(address.getAddress);
Second method
function Square(side)
{
this._side = side;
};
Square.prototype = {
set setSide(side){
this._side = side;
},
get getSide(){
return this._side;
},
get getArea(){
return (this._side * this._side);
}
};
var mySquare = new Square(10);
mySquare.setSide = 15;
console.log("Area of square is "+mySquare.getArea+" with side "+mySquare.getSide);

Privateness in JavaScript

I know you can achieve something as "privateness" in JavaScript by using closures and Immediate Invoked Functions.
But what if I need full featured prototyping? There simply is no way I know of of having private members in an object's prototype. If I used privileged methods I can have private variables and public methods but I lose the option of prototyping.
Douglas Crockford "forbids" the use of dangling (putting an underscore in front of an identifier to indicate that it is not part of the public interface).
But is it that bad to use it? Since there is no way to make it real private.
What is your opinion about this? How do you handle it?
Well at first, you don't really lose the prototyping-effect when using a functional-inheritance pattern. I just assume you're talking about The good parts, crockford also introduced a pretty easy and effective way to have shared variables for that pattern aswell. Which basically looks like:
var Human = (function(my, priv) {
var my = my || {},
priv = priv || {};
my.privatedata = "foobar";
priv.walk = function() {
console.log('walking');
return priv;
};
priv.talk = function() {
console.log('blah blah');
return priv;
};
return priv;
}());
var Andy = (function(my, priv) {
var my = my || {},
priv = Human(my, priv);
priv.SpecialAndyThing = function() {
console.log('bloggin at typeofnan.com');
return priv;
};
return priv;
}());
var myAndy = Andy();
myAndy.talk().SpecialAndyThing();
You can even simply extend this techniqe to have somekind of super methods. Using cryptic variable-conventions like underscores or whatnot is just bad practice in general. Its confusing since nobody just knows what is going on there (probably that argument fails if you're the only one using the codebase).
However, ECMAscript Edition 5 introduces some goodys to have more "private" members in a prototype chain. One important method for that is .defineProperty, where you can define a property which does not "shallow" through. Would look like:
var Human = {};
Object.defineProperty(Human, 'privateStuff', {
value: 'secret',
enumerable: false
});
Now, the property privateStuff is not visible for an object that inherits from Human's prototype chain. Anyway, this stuff requires Javascript 1.8.5 and is only available in cutting edge browsers for now. See https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty
You may be interested in JavaScript Design Patterns. It discusses the Module Pattern too.
Here is an example of how to allow prototypal functions to access private variables in all browsers:
var Book = (function() {
var $ = {};
var Book = function(newFirst, newLast) {
// Private variables stored in an object literal.
var _ = {
author_first : newFirst,
author_last : newLast
};
// Public privileged method for accessing private variables.
this._ = function(key) {
if(key === $)
return _;
throw new Error("The _() function must be called internally.");
};
};
// Public accessor method.
Book.prototype.getAuthor = function() {
var _ = this._($);
return _.author_first + " " + _.author_last;
};
return Book;
})();
var bookA = new Book("Chris", "West"),
bookB = new Book("Douglas", "Crockford");
alert(bookA.getAuthor());
alert(bookB.getAuthor());
This is the same way that I implemented the Color class in jPaq.

Categories