Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #24641 > unrolled thread
| Started by | JJ <duh@nah.meh> |
|---|---|
| First post | 2014-06-07 16:08 +0700 |
| Last post | 2014-06-07 15:17 +0100 |
| Articles | 6 — 4 participants |
Back to article view | Back to comp.lang.javascript
Object instance's local variable is not separate JJ <duh@nah.meh> - 2014-06-07 16:08 +0700
Re: Object instance's local variable is not separate Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-06-07 13:48 +0200
Re: Object instance's local variable is not separate JJ <duh@nah.meh> - 2014-06-07 22:35 +0700
Re: Object instance's local variable is not separate Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-06-07 21:03 +0200
Re: Object instance's local variable is not separate JJ <jj4public@vfemail.net> - 2014-06-09 08:18 +0700
Re: Object instance's local variable is not separate John Harris <niam@jghnorth.org.uk.invalid> - 2014-06-07 15:17 +0100
| From | JJ <duh@nah.meh> |
|---|---|
| Date | 2014-06-07 16:08 +0700 |
| Subject | Object instance's local variable is not separate |
| Message-ID | <12u13ppz1f252.63eqsi8uwd9r.dlg@40tude.net> |
I wanted to create a class that closely mimic the primitive type clases such
as Number, Boolean, Array, etc. I think they use a local variable to store
the value instead of a property. I got a sample code from MDN here:
<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures#Emulating_private_methods_with_closures>
To start with, I change it to below since it needs to be prototypal and be
an instance of the class.
function Num() {
var val = 0;
Num.prototype.changeTo= function(n) {
val = n;
};
Num.prototype.value= function() {
return val;
};
}
But the local variable seems no longer separate into each object instance as
tested below. Why is that?
n1 = new Num();
n2 = new Num();
n2.changeTo(1);
console.log(n1.value() + ", " + n2.value()); //1, 1 = fail (should be 0, 1)
console.log(n1 instanceof Num); //true = ok
console.log(Object.getPrototypeOf(n1).constructor===Num); //true = ok
[toc] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2014-06-07 13:48 +0200 |
| Message-ID | <5180532.WuG82CC6N6@PointedEars.de> |
| In reply to | #24641 |
JJ <duh@nah.meh> wrote:
^^^^^^^^^^^^^^^^
<http://www.interhack.net/pubs/munging-harmful/>. Please fix.
> I wanted to create a class that closely mimic the primitive type clases
> such as Number, Boolean, Array, etc.
There are no classes.
<http://ecma-international.org/ecma-262/5.1/#sec-4.2.1>
> I think they use a local variable to store the value instead of a
> property. I got a sample code from MDN here:
>
> <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures#Emulating_private_methods_with_closures>
>
> To start with, I change it to below since it needs to be prototypal and be
> an instance of the class.
>
> function Num() {
> var val = 0;
> Num.prototype.changeTo= function(n) {
> val = n;
> };
> Num.prototype.value= function() {
> return val;
> };
> }
Your change has b0rked the functionality of the original code.
> But the local variable seems no longer separate into each object instance
> as tested below. Why is that?
>
> n1 = new Num();
> n2 = new Num();
After this constructor call, “val” in Num.prototype.value is bound to the
local variable in the context of *that* call.
> n2.changeTo(1);
This changes *that* variable.
> console.log(n1.value() + ", " + n2.value()); //1, 1 = fail (should be 0,
And both calls return the value of *that* variable, because both objects
have the *same* object referred to by Num.prototype next in their prototype
chain.
A property can only have one value, in this case one reference to a Function
instance. Property values are resolved at runtime, through the prototype
chain if necessary.
> 1) console.log(n1 instanceof Num); //true = ok
> console.log(Object.getPrototypeOf(n1).constructor===Num); //true = ok
It has to be
function Num ()
{
var val = 0;
this.changeTo = function(n) {
val = n;
};
this.value = function() {
return val;
};
}
if objects should not share their property value, and should be something
similar to
function Num (value)
{
var _value = 0;
this.setValue = function (n) {
_value = +n;
};
this.getValue = function () {
return _value;
};
if (typeof Object.defineProperty == "function")
{
Object.defineProperty(this, "value", {
set: this.setValue
get: this.getValue,
});
}
if (arguments.length > 0)
{
this.setValue(value);
}
}
--
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | JJ <duh@nah.meh> |
|---|---|
| Date | 2014-06-07 22:35 +0700 |
| Message-ID | <4dy7dfnuv1vq$.1i9vecn58t2n8$.dlg@40tude.net> |
| In reply to | #24642 |
On Sat, 07 Jun 2014 13:48:14 +0200, Thomas 'PointedEars' Lahn wrote:
> JJ <duh@nah.meh> wrote:
> ^^^^^^^^^^^^^^^^
> <http://www.interhack.net/pubs/munging-harmful/>. Please fix.
What are the options other than using my real email address?
> There are no classes.
>
> <http://ecma-international.org/ecma-262/5.1/#sec-4.2.1>
My bad.
>> n1 = new Num();
>> n2 = new Num();
>
> After this constructor call, “val” in Num.prototype.value is bound to the
> local variable in the context of *that* call.
So, does this means there's only one "val" variable in that context?
>> 1) console.log(n1 instanceof Num); //true = ok
>> console.log(Object.getPrototypeOf(n1).constructor===Num); //true = ok
>
> It has to be
>
> function Num ()
> {
> var val = 0;
>
> this.changeTo = function(n) {
> val = n;
> };
>
> this.value = function() {
> return val;
> };
> }
What about the prototypal Number object, where:
(new Number()).toFixed === Number.prototype.toFixed
How to implement that?
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2014-06-07 21:03 +0200 |
| Message-ID | <4155262.DTQR67hhvp@PointedEars.de> |
| In reply to | #24668 |
JJ wrote:
> On Sat, 07 Jun 2014 13:48:14 +0200, Thomas 'PointedEars' Lahn wrote:
>> JJ <duh@nah.meh> wrote:
>> ^^^^^^^^^^^^^^^^
>> <http://www.interhack.net/pubs/munging-harmful/>. Please fix.
>
> What are the options other than using my real email address?
Your reasonable options are discussed in that document.
I recommend to use the address of an aggressively-filtered, seldom-read (but
*read*) mailbox for the From header field, and the address of a more often
read mailbox for the Reply-To header field. That is what I do.
>>> n1 = new Num();
>>> n2 = new Num();
>>
>> After this constructor call, “val” in Num.prototype.value is bound to the
>> local variable in the context of *that* call.
>
> So, does this means there's only one "val" variable in that context?
There is only one “val” variable per execution context. However, the point
here is that by overwriting the prototype’s property value in the
constructor you are binding the identifier reference in the prototype method
always to *that* variable, i. e. that of the execution context of the last
constructor call.
>>> 1) console.log(n1 instanceof Num); //true = ok
>>> console.log(Object.getPrototypeOf(n1).constructor===Num); //true = ok
>>
>> It has to be
>>
>> function Num ()
>> {
>> var val = 0;
>>
>> this.changeTo = function(n) {
>> val = n;
>> };
>>
>> this.value = function() {
>> return val;
>> };
>> }
>
> What about the prototypal Number object, where:
>
> (new Number()).toFixed === Number.prototype.toFixed
>
> How to implement that?
The expression evaluates to true because the left-hand side is resolved
to Number.prototype.toFixed through the prototype chain.
("toFixed" in (new Number())) === true
but
(new Number()).hasOwnProperty("toFixed") === false
(Besides, new Number(…) should be avoided.)
As for exactly the same functionality as the built-in object, I do not think
that is possible. A user-defined prototype method needs a publicly
accessible property on the instance. You could only have a public prototype
method calling a "privileged" instance method which accesses the context-
local variable aka the "private property". The following comes close:
"use strict";
Object.defineProperty(this, "Num", {
configurable: true,
/* not enumerable */
writable: true,
value: function Num (value) {
var has_args = (arguments.length > 0);
if (!(this instanceof Num))
{
if (has_args)
{
return +value;
}
return 0;
}
var _primitive_value = (has_args ? +value : 0);
Object.defineProperty(this, "_getPrimitiveValue", {
/* not configurable, not enumerable, not writable */
value: function () {
return _primitive_value;
}
});
}
});
Object.defineProperty(this.Num, "prototype", {
/* not configurable, not enumerable, not writable */
value: (function (_global) {
var prototype = new _global.Num();
Object.defineProperties(prototype, {
/* … */
toFixed: {
configurable: true,
writable: true,
value: function (precision) {
var primitive_value = this._getPrimitiveValue();
/* achieve precision */
return primitive_value;
}
},
toString: {
configurable: true,
writable: true,
value: function (radix) {
return this._getPrimitiveValue().toString(radix);
}
},
valueOf: {
configurable: true,
writable: true,
value: function () {
return this._getPrimitiveValue();
}
}
});
return prototype;
}(this))
});
See also <http://ecma-international.org/ecma-262/5.1/#sec-15.7>.
--
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | JJ <jj4public@vfemail.net> |
|---|---|
| Date | 2014-06-09 08:18 +0700 |
| Message-ID | <1dw0asfqcs5z2$.1xn1ekepntglc$.dlg@40tude.net> |
| In reply to | #24671 |
On Sat, 07 Jun 2014 21:03:17 +0200, Thomas 'PointedEars' Lahn wrote: > > Your reasonable options are discussed in that document. > > I recommend to use the address of an aggressively-filtered, seldom-read (but > *read*) mailbox for the From header field, and the address of a more often > read mailbox for the Reply-To header field. That is what I do. OK, thanks. > As for exactly the same functionality as the built-in object, I do not think > that is possible. A user-defined prototype method needs a publicly > accessible property on the instance. You could only have a public prototype > method calling a "privileged" instance method which accesses the context- > local variable aka the "private property". The following comes close: [snip] Bummer. > See also <http://ecma-international.org/ecma-262/5.1/#sec-15.7>. Will definitely do. Thanks again.
[toc] | [prev] | [next] | [standalone]
| From | John Harris <niam@jghnorth.org.uk.invalid> |
|---|---|
| Date | 2014-06-07 15:17 +0100 |
| Message-ID | <jf76p9luip4r69a7jqn1kdj26mifgfa65v@4ax.com> |
| In reply to | #24641 |
On Sat, 7 Jun 2014 16:08:34 +0700, JJ <duh@nah.meh> wrote: >I wanted to create a class Beware! The word 'class' can start furious arguments in ECMAScript circles. >that closely mimic the primitive type clases such >as Number, Boolean, If you want to mimic primitive numbers and booleans then you mustn't make them changeable. You can change the value currently held by a variable, but you'd better not be able to change 5 into 27 or false into true. (Oh, look : 6 - 1 = 27). If you want a different value you create a new value and throw away the old one. >Array, etc. Is an Array really primitive? Certainly an Array object isn't. >I think they use a local variable to store >the value instead of a property. I very much doubt it. It's extremely unlikely to be a local var in the code of an ECMAScript function body. The compiler will translate x = 42; into machine code where the floating point number with the value 42 is written into the value field of whatever machine data structure is used for holding the variable. (Or if not it's going to run very slowly.) >I got a sample code from MDN here: > ><https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures#Emulating_private_methods_with_closures> Closures stop other people changing values that mustn't be changed, or corrupting values that are held in a special internal format. Is either of these applicable to general, as opposed to restricted, primitive values? John
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.javascript
csiph-web