N
nick
Well, it's the weekend again, time for more experimental fun with
js
Last week I was trying to pass primitives by reference (or, more
precisely, passing mutable object wrappers representing
primitives) ... anyway the point was to be able to do stuff like this
(pseudocode):
func ModifyValue(a,b) { increase a by b; }
let x = 4;
ModifyValue(x, 3);
print(x); // x is now 7
Now, last time I tried to accomplish this by adding function
properties to Object's prototype, which as I learned is a Bad Thing
(it breaks iterating over object properties using 'for ... in'). This
time I'm trying another approach; again I'd love to hear feedback from
you guys...
This time, instead of modifying Object's prototype, I'm modifying
prototypes only for constructors of primitive types. Before I go on
with the implementation, this brings up my first worry... a String, in
some browsers, acts as a collection of characters-as-strings with
'for ... in.' Does anyone actually use that functionality, or is it ok
to add stuff to String's constructor?
More generally, will it be a huge performance hit if I modify
constructors for Boolean, Integer, and String with one small function
property?
Alright, here we go:
....
(function(){
var p = [Boolean,Number,String];
for(var t in p) p[t].prototype.set =
function(v) { return wrap(Object(this), v) }
function wrap(o, v)
{
var c = o.constructor;
o.value = v===undefined ? c(o) : v ? c(v) : c();
o.valueOf = function() { return o.value.valueOf() }
o.toString = function() { return o.value.toString() }
o.set = function(v) { o.value = v ? c(v) : c(); return o }
return o;
}
})();
....
This extends [Boolean,Number,String].prototype with a method 'set'
that changes the current object by adding a property 'value' and
overriding valueOf and toString to return 'value'.
On the fourth line, 'Object(this)' is needed instead of just 'this'
for Chrome to act as expected when using the "// this works too"
notation below. The rest should be pretty straightforward. Here's a
quick test:
....
// some test functions
function square(n) { n.set(n*n) }
function bold(n) { n.set('<b>'+n+'</b>') }
// let's do some tests...
var foo = new Number(5);
// var foo = (5).set(); // this works too
var bar = foo;
alert(bar);
square(bar);
alert(foo);
bar.set(3);
square(foo);
alert(bar);
var baz = new String("asfaf");
// var baz = "asfaf".set(); // this works too
bold(baz);
alert(baz);
....
Thoughts? Criticisms? Cries of outrage from PE? Can't wait to hear
'em
-- Nick
js
Last week I was trying to pass primitives by reference (or, more
precisely, passing mutable object wrappers representing
primitives) ... anyway the point was to be able to do stuff like this
(pseudocode):
func ModifyValue(a,b) { increase a by b; }
let x = 4;
ModifyValue(x, 3);
print(x); // x is now 7
Now, last time I tried to accomplish this by adding function
properties to Object's prototype, which as I learned is a Bad Thing
(it breaks iterating over object properties using 'for ... in'). This
time I'm trying another approach; again I'd love to hear feedback from
you guys...
This time, instead of modifying Object's prototype, I'm modifying
prototypes only for constructors of primitive types. Before I go on
with the implementation, this brings up my first worry... a String, in
some browsers, acts as a collection of characters-as-strings with
'for ... in.' Does anyone actually use that functionality, or is it ok
to add stuff to String's constructor?
More generally, will it be a huge performance hit if I modify
constructors for Boolean, Integer, and String with one small function
property?
Alright, here we go:
....
(function(){
var p = [Boolean,Number,String];
for(var t in p) p[t].prototype.set =
function(v) { return wrap(Object(this), v) }
function wrap(o, v)
{
var c = o.constructor;
o.value = v===undefined ? c(o) : v ? c(v) : c();
o.valueOf = function() { return o.value.valueOf() }
o.toString = function() { return o.value.toString() }
o.set = function(v) { o.value = v ? c(v) : c(); return o }
return o;
}
})();
....
This extends [Boolean,Number,String].prototype with a method 'set'
that changes the current object by adding a property 'value' and
overriding valueOf and toString to return 'value'.
On the fourth line, 'Object(this)' is needed instead of just 'this'
for Chrome to act as expected when using the "// this works too"
notation below. The rest should be pretty straightforward. Here's a
quick test:
....
// some test functions
function square(n) { n.set(n*n) }
function bold(n) { n.set('<b>'+n+'</b>') }
// let's do some tests...
var foo = new Number(5);
// var foo = (5).set(); // this works too
var bar = foo;
alert(bar);
square(bar);
alert(foo);
bar.set(3);
square(foo);
alert(bar);
var baz = new String("asfaf");
// var baz = "asfaf".set(); // this works too
bold(baz);
alert(baz);
....
Thoughts? Criticisms? Cries of outrage from PE? Can't wait to hear
'em
-- Nick