Reputation: 66404
In my investigation into making Array-like objects, I made this function,
Array2 = function(){
var out = [];
Object.defineProperty(out, 'prototype', { value : Array2.prototype }); // store a reference
out.__proto__ = Array2.prototype; // necessary as Array uses __proto__ and not prototype
if(arguments.length > 1) Array.prototype.push.apply(out, arguments); // re-implement constructor's
else if(arguments.length === 1) out.length = arguments[0]; // argument handling behaviour
return out;
};
// allow for normal prototyping behaviour
Array2.prototype = [];
Object.defineProperty(Array2.prototype, 'constructor', { value : Array2 });
and noticed that calling Array2()
was returning the same as calling new Array2()
, which isn't what I was expecting, so I considered a similar function for integers
Int = function(n){
var out = ~~n;
out.prototype = Int.prototype;
out.__proto__ = Int.prototype;
this.value = out; // added to check value when working as object
return out;
};
Int.prototype = 0;
Int.prototype.constructor = Int;
this time, Int
returns a normal instance of a Number (__proto__
and prototype
as for any number literal) and new Int
returns an "Int" Object with Empty
as __proto__
and undefined
for prototype
, with the number available through .value
, same as calling without new
.
Why are these very similar functions acting so differently, and why is new
resulting in the for the first one? It is most likely something obvious I've overlooked.
Only tested in Google Chrome.
Upvotes: 3
Views: 92
Reputation: 665476
Actually, your Array2
function return real Arrays instead of only Array-like objects, this does not change when setting the [[prototype]]
to an object that inherits from Array.prototype
(altough you should not have created an array using []
, but a plain object using Object.create(Array.prototype)
.
Your function Int
has several problems.
out
is a primitive number value, and has no properties. When assigning some, it will be implicitly casted to a Number
object, which is discarded rightafter. The same problem with the "constructor" property on Int.prototype = 0
.
Also, you can't use primitive values like 0
as prototype objects. When creating a new Int
instance, it will inherit from the default Object.prototype
as 0
is not of type "object". I'm not sure what happens when assigning such to the non-standard __proto__
property, but I guess it just fails.
Use this instead:
function Int(n){
var out = ~~n;
this.valueOf = function(){ return out; };
return out; // when not used as a constructor, return int-casted number
};
Int.prototype = Object.create(Number.prototype, {
constructor:{value:Int}
});
Upvotes: 1