View Full Version : "new Number(1.23)" vs. "Number(1.23)" vs. "1.23"
ell022
December 9th, 2009, 04:16 PM
var a:Number = new Number(1.23);
var b:Number = Number(1.23);
var c:Number = 1.23;
var d:String = new String("abc");
var e:String = String("abc");
var f:String = "abc"
var g:Array = new Array("a", "b", "c");
// var h:Array = Array("a", "b", "c"); creates compiler error - 1137: Incorrect number of arguments. Expected no more than 1.
var h:Array = Array(3);
h[0] = "a";
h[1] = "b";
h[2] = "c";
var i:Array = ["a", "b", "c"];
trace(a); // returns: 1.23
trace(b); // returns: 1.23
trace(c); // returns: 1.23
trace(d); // returns: abc
trace(e); // returns: abc
trace(f); // returns: abc
trace(g); // returns: a,b,c
trace(h); // returns: a,b,c
trace(i); // returns: a,b,c
Can someone explain the differences between these constructor methods?
When should "new" be used?
TheCanadian
December 9th, 2009, 04:35 PM
If I remember right, which I probably don't, new Number(1.23) actually creates an object (with methods and properties) whereas 1.23 is primitive, meaning it is has no methods or properties and is just the number. When you access a property of a primitive type Flash creates a new temporary object of the same type and value, calls the method, and then delete the temporary object. From this I would assume that new Number() takes up more memory but a primitive value would be slower for calling methods.
Example:
var n1:Number = 1.23;
var n2:Number = new Number(1.23);
n1["prop"] = "foo";
n2["prop"] = "bar";
trace(n1["prop"]); //undefined
trace(n2["prop"]); //bar
senocular
December 9th, 2009, 04:51 PM
^ That applies to AS2, but not AS3. In AS3 that would result in an Error, in both cases.
I'm not sure there's a lot of difference in AS3, but I want to say that there is some "object" weirdness with the new Number() format.
I'd suggest never using new Number and sticking to the primitive value. Use Number() only when you need to cast or convert another value to a number (such as a string).
wvxvw
December 9th, 2009, 05:16 PM
Strictly following the ECMAScript definition, Array, Object, Number, Date etc. aren't classes in a sense all other AS3 classes are because AS3 class is a separate structure (more like interface) which together with the constructor function forms an entity we usually call a class.
So, when it comes down to practice, those ECMAScript "classes" are implemented as functions that return value of specific type. This also explains why calling Array() creates a new Array rather then converts an object to Array or calling Object() creates a new Object rather then converting object to Object.
Example:
trace(Object(null)); // [object Object]
As you would imagine, casting would fail to create a new object in such case.
Using new keyword with these functions is IMO a waste. Since these aren't classes - no new keyword for them :P And if you want to code in like JavaScript manner - simply turn the switch from -as to -es :) They do behave like classes just for the sake of a pattern, but, in fact they aren't.
Now, literals ([], "", //, {}) When you use literal instead of a new SomeClass() construction, the compiler creates the instance without calling the constructor function associated with it - the types that may be declared using literals can be written into bytecode as is, however, new SomeClass() is treated by compiler as method call + instruction to create an instance. So, in this regard, using literals is a preferred way to declare constants, and, arguably, variables too.
Here's something to add to this mess :)
AS3 code:
Object.prototype.foo = function():void { trace("foo"); }
(Object)["constructor"] = function() { trace("constructor"); return {}; }
(Object).prototype["constructor"] = function() { trace("constructor"); return {}; }
var obj1:Object = {};
var obj2:Object = new Object();
obj1.foo();
obj2.foo();
Output:
foo
constructor
TypeError: Error #1010: A term is undefined and has no properties.
at Untitled_fla::MainTimeline/frame1()
AS2 code:
Object.prototype.foo = function():Void { trace("foo"); }
(Object)["constructor"] = function() { trace("constructor"); return {}; }
var obj1:Object = {};
var obj2:Object = new Object();
obj1.foo();
obj2.foo();
Output:
constructor
constructor
AS2 code, again:
(Object)["constructor"] = function() { trace("constructor"); return {}; }
Object.prototype.foo = function():Void { trace("foo"); }
var obj1:Object = {};
var obj2:Object = new Object();
obj1.foo();
obj2.foo();
Output:
foo
foo
PS. Never try that stuff in live projects ;)
Krilnon
December 9th, 2009, 05:22 PM
The constructor doesn't do much:
// actually this is C++ not AS
Atom NumberClass::construct(int argc, Atom* argv)
{
// Number called as constructor creates new Number instance
// Note: SpiderMonkey returns 0 for new Number() with no args
if (argc == 0)
return 0|kIntegerType; // yep this is zero atom
else
return core()->numberAtom(argv[1]);
// TODO ArgumentError if argc > 1
}
…and AvmCore::numberAtom just does a bunch of checking to see if what you've passed in is already an int, Number, Namespace, or whatever. So, by using the constructor on something that you already know is a Number, you're just wasting some time attempting to convert it into a Number.
Powered by vBulletin® Version 4.1.10 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.