From: Thomas 'PointedEars' Lahn on
Garrett Smith wrote:

> Scott Sauyet wrote:
>> On Jan 25, 3:50 pm, Asen Bozhilov <asen.bozhi...(a)gmail.com> wrote:
>>> I want Singleton with properties:
>>> - Doesn't have constructor
>
> Why not?

The question is pointless; it simply cannot be done. Every object has a
constructor, even those created with initializers.

>>> - Create instance properties when i call `Singleton.getInstance()`
>>> - Create instance properties only once
>>>
>>> var x = Singleton.getInstance();
>>> window.alert(typeof x.method1); //function
>>> window.alert(typeof x.method2); //function
>>> window.alert(Singleton.getInstance().method1 === x.method1); //true
>>
>> This looks more complicated than necessary, but I think would work:
>
> [snip]
> It doesn't look complicated at all.
>
>>
>> Are there simplifications to be done here?
>
> I added var, removed the extra comma, and added a couple of semicolons
> that were omitted.

ACK, AISB. Speaking about Pretty Printing, there should be a space between
the `if' keyword and the opening parenthesis.

> I also removed the null assignment and null check.

That is only a partial optimization, though. If this is called the first
time, type conversion from Undefined to Boolean must happen where no type
conversion was necessary before as both operands were of the same type (the
Abstract Equality Comparison Algorithm would have returned in step 3
according to ES3F, and step 1b according to ES5).

If this is called the second time, third time aso., type conversion from
Object to Boolean must happen. This is an optimization because several
type tests were necessary before, as Object is not the same type as Null
(the Abstract Equality Comparison Algorithm would have returned only in the
very last step).

However, if the null assignment was kept and the loose comparison would be
changed into a strict one, which according to my findings is probably safe
by now¹ --

if (instance === null)

--, I think that would be even more efficient (only two type checks and no
type conversion at all).


PointedEars
___________
¹ supported since JavaScript 1.3 (NN 4.06), JScript 5.1.5010 (MSHTML 5),
JSCore 531.9.1 (Safari 4.0.3) or earlier (could not test yet), Opera
5.02, KJS 4.3.4 (Konqueror 4.3.4) or earlier (cannot test this, need to
check source code)
--
Danny Goodman's books are out of date and teach practices that are
positively harmful for cross-browser scripting.
-- Richard Cornford, cljs, <cife6q$253$1$8300dec7(a)news.demon.co.uk> (2004)
From: Asen Bozhilov on
Scott Sauyet wrote:

> I don't follow this.  Do you have an example of how you'd want to use
> it?

I wrote in my previous post. If i want to have instance properties in
my Singleton, `getInstance' make a sense for my.

> This doesn't make any sense to me.  What is "this" here?

The question is rhetorical? `this' associated with execution context
created when i call `getInstance', refer `object' referred from
`Singleton' from `10.1.7 This`, `11.2.1 Property Accessors` and
`11.2.3 Function Calls` ECMA 262-3 specification.

From: Scott Sauyet on
On Jan 26, 4:04 am, Asen Bozhilov <asen.bozhi...(a)gmail.com> wrote:
> Scott Sauyet wrote:
>> I don't follow this.  Do you have an example of how you'd want to use
>> it?
>
> I wrote in my previous post. If i want to have instance properties in
> my Singleton, `getInstance' make a sense for my.

I think we're having some kind of communication difficulties. It
seems to me that in the code I supplied (preferably with the
improvements from Thomas and Garrett) you can have whatever instance
properties you like; so far we have two functions named "method1" and
"method2", but you can have any additional properties you like.


>> This doesn't make any sense to me.  What is "this" here?
>
> The question is rhetorical? `this' associated with execution context
> created when i call `getInstance', refer `object' referred from
> `Singleton' from `10.1.7 This`, `11.2.1 Property Accessors` and
> `11.2.3 Function Calls` ECMA 262-3 specification.

No, I understand what "this" represents. I just couldn't figure out
why you'd want to use it here; it seems to muddy the issues.

Right now, with the code you propose, we would have:

var Singleton = {};
Singleton.getInstance = function() {
this.method1 = function(){};
this.method2 = function(){};
this.getInstance = function(){
return this;
};
return this;
};

var x = Singleton.getInstance();
var y = Singleton.getInstance();
var z = new Singleton.getInstance();

window.alert(typeof x.method1); //function
window.alert(typeof x.method2); //function
window.alert(Singleton.getInstance().method1 === x.method1); //
true
window.alert(x === y); //true
window.alert(x === z); //false

That last "false" is probably not what you want, though, correct? And
with the "this", it can get worse:

var w = Singleton.getInstance.call(window);
var x = Singleton.getInstance();

window.alert(x === w); //false
window.alert(typeof window.method1); //function -- OOPS

The other proposal doesn't have these issues, I believe:

var Singleton = (function() {
var instance = null;
return {
getInstance: function() {
if (instance === null) {
instance = {
method1: function() {},
method2: function() {}
};
}
return instance;
}
}
})();

var w = Singleton.getInstance.call(window);
var x = Singleton.getInstance();
var y = Singleton.getInstance();
var z = new Singleton.getInstance();

window.alert(typeof window.method1); //undefined -- CORRECT
window.alert(x === w); //true
window.alert(typeof x.method1); //function
window.alert(typeof x.method2); //function
window.alert(Singleton.getInstance().method1 === x.method1); //
true
window.alert(x === y); //true
window.alert(x === z); //true

So in this case, although you can use Singleton.getInstance as a
constructor, it returns the same object as when used normally. And
you can call it on other objects (such as window) without setting
properties on them. But it's not clear to me what it doesn't do that
you need.

-- Scott
From: Richard Cornford on
On Jan 26, 2:28 pm, Scott Sauyet wrote:
<snip>
> Right now, with the code you propose, we would have:
>
> var Singleton = {};
> Singleton.getInstance = function() {
> this.method1 = function(){};
> this.method2 = function(){};
> this.getInstance = function(){
> return this;
> };
> return this;
> };
>
> var x = Singleton.getInstance();
> var y = Singleton.getInstance();
> var z = new Singleton.getInstance();
>
> window.alert(typeof x.method1); //function
> window.alert(typeof x.method2); //function
> window.alert(Singleton.getInstance().method1 === x.method1); //
> true
> window.alert(x === y); //true
> window.alert(x === z); //false
>
> That last "false" is probably not what you want, though, correct?

So you sack the nitwit who wrote "new Singleton.getInstance();".

> And with the "this", it can get worse:
>
> var w = Singleton.getInstance.call(window);
> var x = Singleton.getInstance();
>
> window.alert(x === w); //false
> window.alert(typeof window.method1); //function -- OOPS

Remember that javascript is sufficiently flexible that if someone is
trying to break something then they will. Otherwise constructs like
"Singleton.getInstance.call(window)" are not going to randomly appear
in source code, and so in context can only be the products of complete
fools who are better removed from the equation than pandered to.

> The other proposal doesn't have these issues, I believe:
>
> var Singleton = (function() {
> var instance = null;
> return {
> getInstance: function() {
> if (instance === null) {
> instance = {
> method1: function() {},
> method2: function() {}
> };
> }
> return instance;
> }
> }
> })();

But if you are trying to guard against the random scrubbings of fools
and halfwits what are you going to do to prevent someone re-assigning
a new object with its own - getInstance - method to - Singleton -?

> var w = Singleton.getInstance.call(window);
> var x = Singleton.getInstance();
> var y = Singleton.getInstance();
> var z = new Singleton.getInstance();
>
> window.alert(typeof window.method1); //undefined -- CORRECT
> window.alert(x === w); //true
> window.alert(typeof x.method1); //function
> window.alert(typeof x.method2); //function
> window.alert(Singleton.getInstance().method1 === x.method1); //
> true
> window.alert(x === y); //true
> window.alert(x === z); //true
>
> So in this case, although you can use Singleton.getInstance as a
> constructor, it returns the same object as when used normally.
<snip>

And what type of person is it that uses something that is not a
constructor as a constructor?

Richard.
From: Scott Sauyet on
On Jan 26, 9:51 am, Richard Cornford <Rich...(a)litotes.demon.co.uk>
wrote:

> But if you are trying to guard against the random scrubbings of fools
> and halfwits what are you going to do to prevent someone re-assigning
> a new object with its own - getInstance - method to - Singleton -?

No, of course you can't safeguard everything. Asen asked for advice
on how to do something, and specifically asked for

| I want Singleton with properties:
| - Doesn't have constructor

which, as already pointed out, is a strange requirement.

I supplied my answer, which seems not to meet Asen's needs, although I
haven't yet understood the objections. Asen gave some alternative
code. It's not clear to me if it's code that meets the needs or just
a starting point. But if somehow Asen is worried about his code
having spurious constructors, the tests I supplied might help decide
the matter.

-- Scott