JSON Style JavaScript Class/Object declaration

  • Thread starter M A Hossain Tonu
  • Start date
M

M A Hossain Tonu

JSON stands for JavaScript Object Notation. The current trend among
many JavaScript developers seems to be to write code JSON style, i.e.
to collect a number of functions/methods into a singleton object
written in object notation.

What! did i heard Singleton Object? Whats dat ?

Well Wiki says: The singleton pattern is a design pattern that is used
to restrict instantiation of a class to one object

Actually JSON objects are singleton objects by design, not by choice,
since they have no constructor. I really like JSON

So using the JSON you can define a class, while at the same time
creating an instance (object) of that class, means that you can have
only one single instance of this class at any time, you cannot
instantiate more objects of the same class.

I have written here more:

http://mahtonu.wordpress.com/2010/04/13/json-style-javascript-object-declaration/
 
R

RobG

JSON stands for JavaScript Object Notation. The current trend among
many JavaScript developers seems to be to write code JSON style, i.e.
to collect a number of functions/methods into a singleton object
written in object notation.

What! did i heard Singleton Object? Whats dat ?

Well Wiki says: The singleton pattern is a design pattern that is used
to restrict instantiation of a class to one object

JSON is a means of describing objects using javascript object literal
syntax, nothing more. It is not intended to be a singleton pattern,
nor does it restrict a "class" to one object only. Consider:

var jsonString = "{foo:'foo', bar:'bar'}";

var obj1 = eval('(' + jsonString + ')');
var obj2 = eval('(' + jsonString + ')');

Would you say obj1 and obj2 are two instances of the same "class"?
Javascript has no classes, using classic class-baesd OO terminology to
describe a language that does not have classes only confuses.

Actually JSON objects are singleton objects by design, not by choice,
since they have no constructor. I really like JSON

What is a "JSON object"? If it's an object created by eval'ing a JSON
string, then not only is it not possible to tell afterward how it was
created (i.e. to tell it's a "JSON object"), but also it is simple to
create a second "instance" as shown above. How is this a "singleton"?

So using the JSON you can define a class, while at the same time
creating an instance (object) of that class, means that you can have
only one single instance of this class at any time, you cannot
instantiate more objects of the same class.

Not correct, as shown above.

As I understand it, the primary motivation for using an object literal
as you describe is as a simple method to provide a "namespace" for
what would otherwise be global functions and variables. An alternative
is:

var obj1 = {};
obj1.foo = 'foo';
obj1.bar = 'bar';

The result is indistinguishable from the JSON version above.
 
R

Ry Nohryb

JSON stands for JavaScript Object Notation. The current trend among
many JavaScript developers seems to be to write code JSON style, i.e.
to collect a number of functions/methods into a singleton object
written in object notation. (...)

One thing is for sure: if it contains a function / method, it's *not*
a JSON text... :)

See: http://json.org/
 
R

Richard Cornford

One thing is for sure: if it contains a function / method,
it's *not* a JSON text... :)

See:http://json.org/

"Contains" is a bit ambiguous. In principle there is no reason for
javascript source code not to be string data within a JSON text, at
which point the odds are good that the JSON will 'contain' a function
(in one sense).

If a piece of text (sequence of characters) is such that its
processing as javascript source text by an (ECMAScript conforming)
javascript engine would result in the creation of a javascript
function object then that text is not JSON (does not satisfy the JSON
syntax rules).

There is a huge confusion between javascript object literal notation
and the restricted sub-set of its syntax that defines JSON. Any talk
of "a JSON object" is probably a good indicator that this confusion is
involved.

Richard.
 
R

Ry Nohryb

(...)
There is a huge confusion between javascript object literal notation
and the restricted sub-set of its syntax that defines JSON. Any talk
of "a JSON object" is probably a good indicator that this confusion is
involved.

<FAQENTRY> JSON !== JSOL </FAQENTRY>

:)
 
J

Justin Johnson

* Duplicating the comment I made on the blog for the benefit of the
discussion here

Two things.

1) You are using the wrong terminology. There is a confusion between
object literal notation and JSON. What you are using and describing is
*object literal notation.* JSON is intended as a means of data
transport (either between applications and/or across a network), is
always in string form, cannot define functions, and is a subset of
object literal notation.

2) While an object created in this fashion might *act* like a
singleton, it is not really a singleton. There is nothing to stop
someone from cloning the object, resulting in more than one
representation/instance of the same data.

var clone = function(o) {
var no = {};
for ( var i in o ) {
no = o;
}
return no;
}

var a = {a: 1, b: 2},
b = clone(a),
c = a;

a.a = 3;
b.b = 4;
console.log(a, b, c);

The only way to have a true singleton in JavaScript is to use all
private members so that the data cannot be cloned from one object to
another.

var a = (function() {
var _a = 1, _b = 2;
return {
getA: function() { return _a; },
setA: function(a) { _a = a; },
getB: function() { return _b; },
setB: function(b) { _b = b; }
};
})();

var b = clone(a);

a.setA(3);
b.setB(4);
console.log(a.getA(), a.getB(), b.getA(), b.getB());

However, this might be splitting hairs. For most applications, the
object literal approach to singletons is probably sufficient.
 
M

M A Hossain Tonu

@Rob, @Jorge, @Richard, @Justin:
Thank you very much for your valuable discussion, i will be updating
my post shortly.

Thnx again for the help, cheers :D
 
M

M A Hossain Tonu

Hi Rob,

Now a days use of JSON doesn't limit within only in data-
interchanging.
Due to it is based on subset of JavaScript programming language itself
it starts confusion cause JavaScript itself confusing regarding OO.

Again if we use JSON format to describe an object, at the same time we
are instantiating the object.

Consider your example:

var jsonString = "{foo:'foo', bar:'bar'}";

var obj1 = eval('(' + jsonString + ')');
var obj2 = eval('(' + jsonString + ')');

Here you have used JSON string, i am not talking about JSON string
rather talking about Object Notation. well if u consider like this:

var jsonObj = {foo:'foo', bar:'bar'};//description and instantiation
at a time here

var obj1 = jsonObj ;
var obj2 = clone(jsonObj);

Then the only object instantiated here is jsonObj not the obj1, obj2,
they are the simple copy or clone of that object though it can't be
tell afterward how it was
created(in this point you are right).

Note that there are no classes in JavaScript.
Functions can be used to somewhat simulate classes, but in general
JavaScript is a class-less language.

Everything is an object. And when it comes to inheritance, objects
inherit from objects, not classes from classes as in the "class"-ical
languages.
This scheme is called Prototype-based programming where classes are
not present rather class behavior reused.

This model can also be known as class-less, prototype-oriented or
instance-based programming. And has been grown increasingly popular
and adopted in JavaScript.


Any suggestion will be highly appreciable.

Updating my post too.
 
M

M A Hossain Tonu

* Duplicating the comment I made on the blog for the benefit of the
discussion here

Two things.

1) You are using the wrong terminology. There is a confusion between
object literal notation and JSON. What you are using and describing is
*object literal notation.* JSON is intended as a means of data
transport (either between applications and/or across a network), is
always in string form, cannot define functions, and is a subset of
object literal notation.

2) While an object created in this fashion might *act* like a
singleton, it is not really a singleton. There is nothing to stop
someone from cloning the object, resulting in more than one
representation/instance of the same data.

var clone = function(o) {
    var no = {};
    for ( var i in o ) {
        no = o;
    }
    return no;

}

var a = {a: 1, b: 2},
    b = clone(a),
    c = a;

a.a = 3;
b.b = 4;
console.log(a, b, c);



a.a = 3;
b.a = 4;
console.log(a.a, b.a, c.a);

outputs 4 4 4 they are using same memory...
cause they are copy not an unique instance....so where is the
singelton pattern violated?
 
R

Ry Nohryb


A susbset of.
It is not intended to be a singleton pattern,

(...)

Note that the text into that jsonString is *not* valid JSON. It should
be:

jsonString= '{ "foo":"foo", "bar":"bar" }';

IOW: "javascript object literal syntax" !== JSON
 
A

Asen Bozhilov

Justin said:
The only way to have a true singleton in JavaScript is to use all
private members so that the data cannot be cloned from one object to
another.

var a = (function() {
    var _a = 1, _b = 2;
    return {
        getA: function()  { return _a; },
        setA: function(a) { _a = a;    },
        getB: function()  { return _b; },
        setB: function(b) { _b = b;    }
    };

})();

var b = clone(a);

a.setA(3);
b.setB(4);
console.log(a.getA(), a.getB(), b.getA(), b.getB());

If someone need copy of a singleton object there is design mistake.
That is contradiction with conception of a singleton pattern. Your
defense is not enough for unreasonable development and should not. If
there is a developer who misunderstand your concept, he always can
broke your code.
 
L

Lasse Reichstein Nielsen

M A Hossain Tonu said:
var clone = function(o) {
    var no = {};
    for ( var i in o ) {
        no = o;
    }
    return no;

}

var a = {a: 1, b: 2},
    b = clone(a),
    c = a;

a.a = 3;
b.a = 4;
console.log(a.a, b.a, c.a);

outputs 4 4 4 they are using same memory...

No, it doesn't. The b variable holds a reference to a different object,
and it writes 3,4,3.
cause they are copy not an unique instance....so where is the
singelton pattern violated?

The "singleton pattern" makes no sense in a classless language.
It means that you can only create one instance of a specific class.
It has no meaning when there are no classes.
What would it be that you could only create on instance of?

/L 'You could do it with host objects, but then, you can do
anything with those'
 
V

VK

Any suggestion will be highly appreciable.

The further is not a group consensus but my own private opinion.

[1] Of course there are classes in JavaScript. Like in any OO language
there are classes of things and instances of those classes of things.
Semi-hysterical "there are no classes in JavaScript!!" and tabooed
word "class" itself comes from the JavaScript childhood. Then it was a
protection mechanics against "real languages" that were laughing over
"that toy language". So the story was that "I am not primitive, I am
different! Very very different and hard to be understood by outsiders.
I am the Wrrrld's Most Misunderstood Programming Language! (c)2001
Crockford http://javascript.crockford.com/javascript.html " :)

For the same reason the prototype-based inheritance, that is as simple
as a moo-cow, was often presented nearly as a ultimate lore with a
bunch of convoluted samples proving its complex nature.

The childhood is way over and this "protection behavior" is not
needed. There are classes and instances in JavaScript just like
everywhere else. The core difference from C-like languages is that
there we have the strict specialization: there are objects that create
new objects (classes) and there are object that do the actual job the
program is created for (instances). They are not interchangeable: one
cannot use a class to calculate 2*2=? and one cannot use an instance,
calculating 2*2=?, as a class.
In JavaScript constructor is the same first order function so
theoretically it can be used as an instance constructor or just be
called as a function. This polymorphism is purely theoretical though:
it can't be a descent code with function Foo being used in either way
in the same program, like this
var obj = new Foo();
and then some later
Foo();

[2] Your article is rather confusing by its layout. Basically you are
describing some elements of CC scope management, namely the creation
of protected properties and privileged methods. Other words instance
properties that can be accessed only over particular instance methods.
It is a commonly used practice now, but it has nothing to do with
singletons. It can be N instances of the same class with protected
properties and privileged methods. It can be a singleton without any
protected properties and privileged methods. These are simply
unrelated things. And most definitely neither first nor second has any
relation with JSON data-interchange format. What you really wrote, in
proper JavaScript terms, is "Using privileged methods in JavaScript:
how to and benefits". And if writing about Cornford-Crockford scope
management aspects it may be useful to read the original papers:
"Private Members in JavaScript" by Douglas Crockford (2001)
http://www.crockford.com/javascript/private.html
and
"Private Static Members in JavaScript" by Richard Cornford (2003)
The article is gone but still available over Wayback Machine:
http://web.archive.org/web/20031205082329/http://www.litotes.demon.co.uk/js_info/private_static.html

A nice summary can be found in this group archives in the discussion
"closures, what are they good for?" (April-May 2003)
http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/793cd655ad56fe91

[3] In reference to singleton it would be a whole different article
and a different discussion. If you are interested in singletons and
not in CC scope management, let's talk about singletons.
 
M

M A Hossain Tonu

The problem with that clone method, that if you have sub objects
within the obj, their references will be cloned, and not the values of
every sub object.

var clone = function(o) {
    var no = {};
    for ( var i in o ) {
        no = o;
    }
    return no;
}
var a = {a: 1, b: 2},
    b = clone(a),
    c = a;

a.a = 3;
b.a = 4;
console.log(a.a, b.a, c.a);

outputs 4 4 4 they are using same memory...

No, it doesn't. The b variable holds a reference to a different object,
and it writes 3,4,3.
cause they are copy not an unique instance....so where is the
singelton pattern violated?

The "singleton pattern" makes no sense in a classless language.
It means that you can only create one instance of a specific class.
It has no meaning when there are no classes.
What would it be that you could only create on instance of?

/L 'You could do it with host objects, but then, you can do
    anything with those'
 
M

M A Hossain Tonu

Thank you very much for your valuable suggestion. I am altering and
filling the post.

Tonu


Any suggestion will be highly appreciable.

The further is not a group consensus but my own private opinion.

[1] Of course there are classes in JavaScript. Like in any OO language
there are classes of things and instances of those classes of things.
Semi-hysterical "there are no classes in JavaScript!!" and tabooed
word "class" itself comes from the JavaScript childhood. Then it was a
protection mechanics against "real languages" that were laughing over
"that toy language". So the story was that "I am not primitive, I am
different! Very very different and hard to be understood by outsiders.
I am the Wrrrld's Most Misunderstood Programming Language! (c)2001
Crockfordhttp://javascript.crockford.com/javascript.html" :)

For the same reason the prototype-based inheritance, that is as simple
as a moo-cow, was often presented nearly as a ultimate lore with a
bunch of convoluted samples proving its complex nature.

The childhood is way over and this "protection behavior" is not
needed. There are classes and instances in JavaScript just like
everywhere else. The core difference from C-like languages is that
there we have the strict specialization: there are objects that create
new objects (classes) and there are object that do the actual job the
program is created for (instances). They are not interchangeable: one
cannot use a class to calculate 2*2=? and one cannot use an instance,
calculating 2*2=?, as a class.
In JavaScript constructor is the same first order function so
theoretically it can be used as an instance constructor or just be
called as a function. This polymorphism is purely theoretical though:
it can't be a descent code with function Foo being used in either way
in the same program, like this
 var obj = new Foo();
and then some later
 Foo();

[2] Your article is rather confusing by its layout. Basically you are
describing some elements of CC scope management, namely the creation
of protected properties and privileged methods. Other words instance
properties that can be accessed only over particular instance methods.
It is a commonly used practice now, but it has nothing to do with
singletons. It can be N instances of the same class with protected
properties and privileged methods. It can be a singleton without any
protected properties and privileged methods. These are simply
unrelated things. And most definitely neither first nor second has any
relation with JSON data-interchange format. What you really wrote, in
proper JavaScript terms, is "Using privileged methods in JavaScript:
how to and benefits". And if writing about Cornford-Crockford scope
management aspects it may be useful to read the original papers:
  "Private Members in JavaScript" by Douglas Crockford (2001)
 http://www.crockford.com/javascript/private.html
and
  "Private Static Members in JavaScript" by Richard Cornford (2003)
  The article is gone but still available over Wayback Machine:
 http://web.archive.org/web/20031205082329/http://www.litotes.demon.co....

A nice summary can be found in this group archives in the discussion
  "closures, what are they good for?" (April-May 2003)
 http://groups.google.com/group/comp.lang.javascript/browse_frm/thread....

[3] In reference to singleton it would be a whole different article
and a different discussion. If you are interested in singletons and
not in CC scope management, let's talk about singletons.
 
V

VK

If someone need copy of a singleton object there is design mistake.

One can clone an object, but it is not possible to clone a closure
state, so it is not possible to get access to the actual protected
member values other way than using privileged methods. That is the
core idea of CC, see
"Private Members in JavaScript" by Douglas Crockford (2001)
http://www.crockford.com/javascript/private.html

Again, OP used a misleading title for the article, it is all about
protected members and privileged methods. Singletons and the
"singleton pattern" has no relation with the topic of discussion.
Singletons in JavaScript are mainly used at the script start stage,
when a bunch of environment testing and instantiation has to be done.
To keep the namespace clean afterworlds, it is often wrapped into
anonymous function:

(function(){
// DO stuff
})();

or equivalent:

(function(){
// DO stuff
}());

If one needs to get a permanent single instance of something and then
to eliminate the possibility of creating new instances, then by KISS
the simplest is just to eliminate the constructor:

var foo = new Foo();
Foo = null;
foo.constructor = null;

JavaScript function being called as constructor may return anything
instead of new instance, as long as it is typeof object. That allows
to create singletons, doubletons, tripletons etc. but I hope I will
never see it in a real code.
 
A

Asen Bozhilov

VK said:
One can clone an object, but it is not possible to clone a closure
state, so it is not possible to get access to the actual protected
member values other way than using privileged methods.

That is depend on implementation, some implementations provide access
to internal [[Scope]] property. For example Rhino, there is
`__parent__' property which is mimic of [[Scope]]. So I can get
reference to VO associated with execution context in which some
Function Declaration/Expression is evaluated.

var a = (function() {
var _a = 1, _b = 2;
return {
getA: function() { return _a; },
setA: function(a) { _a = a; },
getB: function() { return _b; },
setB: function(b) { _b = b; }
};

})();

var aVO = a.getA.__parent__;
for (var i in aVO) {
print(i);
}

The output in Rhino 1.7 from code above is:

arguments
_a
_b
 
V

VK

That is depend on implementation, some implementations provide access
to internal [[Scope]] property. For example Rhino, there is
`__parent__' property which is mimic of [[Scope]]. So I can get
reference to VO associated with execution context in which some
Function Declaration/Expression is evaluated.

var a = (function() {
     var _a = 1, _b = 2;
     return {
         getA: function()  { return _a; },
         setA: function(a) { _a = a;    },
         getB: function()  { return _b; },
         setB: function(b) { _b = b;    }
     };

})();

var aVO = a.getA.__parent__;
for (var i in aVO) {
    print(i);

}

The output in Rhino 1.7 from code above is:

arguments
_a
_b

That is an important info, thank you. So Rhino breaks any
encapsulation attempts and cannot be used for some commercial projects
where encapsulation is really a must. Overall the __properties__ like
__parent__ or __proto__ are for the *engine* testing only. Why
Netscape and now Mozilla doesn't lock it in release versions and
prefers to compromise the security and the stability - is a dark
misery. Too busy with getter/setter crap and with breaking backward
compatibility. Just a guess...
 
D

Dmitry A. Soshnikov

That is depend on implementation, some implementations provide access
to internal [[Scope]] property. For example Rhino, there is
`__parent__' property which is mimic of [[Scope]]. So I can get
reference to VO associated with execution context in which some
Function Declaration/Expression is evaluated.

var a = (function() {
var _a = 1, _b = 2;
return {
getA: function() { return _a; },
setA: function(a) { _a = a; },
getB: function() { return _b; },
setB: function(b) { _b = b; }
};

})();

var aVO = a.getA.__parent__;
for (var i in aVO) {
print(i);

}

The output in Rhino 1.7 from code above is:

arguments
_a
_b

That is an important info, thank you. So Rhino breaks any
encapsulation attempts and cannot be used for some commercial projects
where encapsulation is really a must.

Don't understand an encapsulation incorrectly. This is less about
security, and more about increasing of an abstraction ;)

For details: <URL: http://bit.ly/am38pU>
About __parent__: <URL: http://bit.ly/9L1hWe>

Dmitry.
 
V

VK

Don't understand an encapsulation incorrectly. This is less about
security, and more about increasing of an abstraction ;)

Well, JavaScript never cared about abstraction and other theoretical
stuff, so the only way it could understand encapsulation is by
interpreting it in access restriction / data security terms :) Which
is IMHO the original purpose of encapsulation in the first case. The
global abstraction logic is secondary, to make CS students to use
encapsulation instinctively by the end of the university.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top