On Sep 10, 2013, at 4:38 PM, Andrea Giammarchi wrote:
> right now? the `[[Class]]` such as `'[object Array]'` ... and the magic is
> this smarter slice.
And what does [[Class]] == "Array" actually tell you? Primarily that the Array
length invariant is automatic enforced.
You seems to be conflating two orthogonal concepts:
1) whether an object is an exotic array object (ie, enforces the length
invariant)
2) whether an object inherits from Array.prototype
Even in ES5+web reality, these are separable concepts:
var exotic = [ ]; exotic.__proto__=Object.prototype;
//exotic has the array invariant, Array.isArray(exotic) is true, exotic
instanceof Array is false, exotic does not expose any Array methods
function ArrayLIkeSubclass() {
this.length = 0;
}
ArrayLikeSubclass.prototype = {
__proto__: Array.prototype,
constructor: ArrayLikeSubclass
}
var alike= new ArrayLikeSubclass();
//alike doesn't have array invariant, Array.isArray(alike) is false, alike
instanceof Array is true, alike inherits all of the Array methods
function ArrayExoticSubclass() {
var obj = [ ];
obj.__proto__ = Object.getPrototypeOf(this);
return obj;
}
ArrayExoticSubclass.prototype = {
__proto__: Array.prototype,
constructor: ArrayExoticSubclass
}
var asub= new ArrayExoticSubclass();
//asub has the array invariant, Array.isArray(asub) is true, asub instanceof
Array is true, and it inherits all of the Aarray methods
>
> I insist this would be way better and already possible today:
>
> ```javascript
> (function(Object, ArrayPrototype){
> if (typeof ArrayObject !== 'undefined') return;
> ArrayObject = function(){};
> for(var
> modify = [
> 'concat',
> 'copyWithin',
> 'filter',
> 'map',
> 'slice',
> 'splice'
> ],
> keys = Object.getOwnPropertyNames(ArrayPrototype),
> create = function(method) {
> return function() {
> return Object.setPrototypeOf(
> method.apply(this, arguments),
> Object.getPrototypeOf(this)
> );
> };
> },
> i = keys.length,
> current, key;
> i--;
> ) {
> key = keys[i];
> current = Object.getOwnPropertyDescriptor(ArrayPrototype, key);
> if (~modify.indexOf(key)) current.value = create(current.value);
> Object.defineProperty(ArrayObject.prototype, key, current);
> }
> }(Object, Array.prototype));
> ```
>
> where any class that extends `ArrayObject` will have the new behavior and
> less problem with the past.
>
> ```javascript
> var a = new ArrayObject;
> a.push(1, 2, 3);
> a.slice() instanceof ArrayObject; // true
> ```
The above is essentially equivalent to the following ES6 code:
class ArrayObject extends Array {
slice(...args) {return this.constructor.from(super(...args))}
//do the same thing for concat, map, etc.
}
except that, Array.isArray(new ArrayObject) is true
(new Array).slice() instanceof Array //true
(new Array).slice() instanceof ArrayObject //false
Array.isArray(new Array) //true
(new ArrayObject).slice instanceof ArrayObject //true
(new ArrayObject).slice instanceof Array //true
Array.isArray(new ArrayObject) //true
All the ES6 spec. does for slice and friends is to make the subclass over-rides
unnecessary. You will get the exact same results, without the over-rides.
Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss