2009/12/8 Brendan Eich <[email protected]>:
> On Dec 8, 2009, at 10:10 AM, Mike Samuel wrote:
>
>>> 1) Does the object have the special semantics around .length? This is
>>> potentially useful to know and the normal way to find out doesn't
>>> work. Instanceof is affected by setting __proto__, yet the special
>>> .length handling persists and instanceof doesn't work for cross-iframe
>>> objects.
>>
>> I think I agree with the bit about length, but __proto__ doesn't work
>> on non mozilla interpreters
>
> WebKit JSC implemented too :-/.
>
>> and isn't likely to be standardized.
>
> You got that part right :-).
>
>
>> I don't see how it's relevant to array-like-ness.
>
> Agreed, but Erik's point here was about instanceof. Not only mutable
> __proto__, but mutable bindings for constructors, and the issue of multiple
> global objects with their unrelated suites of builtin constructors, make
> instanceof less than ideal for deciding "array-like".
Ah ok. I agree with Erik then. Even moreso, instanceof doesn't work
cross context.
>> Efficiency is obviously important, but another important distinction
>> is whether 'length' should be included in the set of keys iterated
>> over,
>
> In ES1-5, length is not enumerable for Array, String, and arguments objects.
> Anything array-like, same deal or it's not "like" enough.
Maybe I'm imagining things, but I'm pretty sure that on some browsers
length is enumerable on arr in
var arr = [1,2,3]
arr.length = 2;
>
>> and whether iteration over array-index keys should be in numeric
>> order.
>
> I'm suspicious of real code depending on insertion order. Typically arrays
> are built front to back so the two are the same. Exceptional cases may break
> existing for-in loops that inspect arrays and want numeric order. This is
> something to investigate (google codesearch?).
>
>
>>> But really for..in is pretty sick for arrays. It will convert every
>>> single index in the array to a string. That's not something to be
>>> encouraged IMHO.
>>
>> Also agreed.
>
> Yes, that is an ES1 change from my Netscape implementation. It is costly
> enough that optimizing implementations use memoized or static strings for
> small integer literals!
>
> Yet for-in on an array-like is attractive, especially in light of
> comprehensions and generator expressions. One way forward would be to change
> to number type under opt-in Harmony versioning. Another option is new
> syntax, but that requires opt-in versioning anyway, and it's not clear to me
> that changing for-in on Arrays, or on all array-likes, to return numbers for
> indexes, is an incompatibility that we could not "get away with".
>
> If anyone knows of real-world code that would be broken by the type of the
> for-in loop variable not always being string, I'm all ears.
>
> /be
>
>>
>>
>>> --
>>> Erik Corry
>>
>>
>>
>> Prototype.js dodges this problem by adding an each method to
>> Array.prototype and others. This obviously fails for cross-context
>> Arrays, and also suffers from the large sparse array and missing
>> non-array-index properties problems.
>>
>> It does switch on arrays in places, and does so inconsistently though
>> -- in one case (unnecessarily?) filtering out arguments objects?
>> if (Object.isArray(item) && !('callee' in item)) {
>> for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
>> array.push(item[j]);
>> } else {
>>
>> function flatten() {
>> return this.inject([], function(array, value) {
>> if (Object.isArray(value))
>> return array.concat(value.flatten());
>> array.push(value);
>> return array;
>>
>> dojo.clone does
>> if(d.isArray(o)){
>> r = [];
>> for(i = 0, l = o.length; i < l; ++i){
>> if(i in o){
>> r.push(d.clone(o[i]));
>> }
>> }
>> }else{
>> // generic objects
>> r = o.constructor ? new o.constructor() : {};
>> }
>> dojo.isArray = function(/*anything*/ it){
>> // summary:
>> // Return true if it is an Array.
>> // Does not work on Arrays created in other
>> windows.
>> return it && (it instanceof Array || typeof it == "array");
>> // Boolean
>> }
>> dojo.isArrayLike = function(/*anything*/ it){
>> // summary:
>> // similar to dojo.isArray() but more
>> permissive
>> // description:
>> // Doesn't strongly test for "arrayness".
>> Instead, settles for "isn't
>> // a string or number and has a length
>> property". Arguments objects
>> // and DOM collections will return true when
>> passed to
>> // dojo.isArrayLike(), but will return false
>> when passed to
>> // dojo.isArray().
>> // returns:
>> // If it walks like a duck and quacks like a
>> duck, return `true`
>> return it && it !== undefined && // Boolean
>> // keep out built-in constructors (Number, String,
>> ...) which have length
>> // properties
>> !d.isString(it) && !d.isFunction(it) &&
>> !(it.tagName && it.tagName.toLowerCase() == 'form')
>> &&
>> (d.isArray(it) || isFinite(it.length));
>> }
>> and dojo uses these definitions to do type coercion
>> }else if(!dojo.isArray(content)){
>> //To get to this point, content is
>> array-like, but
>> //not an array, which likely means a DOM
>> NodeList. Convert it now.
>> content = dojo._toArray(content);
>>
>>
>> The closure library similarly defines both isArray and isArrayLike,
>> but with differences (
>>
>> http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/base.js
>> ):
>> goog.isArrayLike = function(val) {
>> var type = goog.typeOf(val);
>> return type == 'array' || type == 'object' && typeof val.length
>> == 'number';
>> };
>> which is then used in many places (
>>
>> http://www.google.com/codesearch?q=goog.isArrayLike+package%3Ahttp%3A%2F%2Fclosure-library%5C.googlecode%5C.com&origq=goog.isArrayLike
>> ), e.g. in iter.js
>> goog.iter.forEach = function(iterable, f, opt_obj) {
>> if (goog.isArrayLike(iterable)) {
>>
>>
>> MooTools is the only library I looked at that does not check
>> array-likedness. They do something similar to prototype by
>> monkey-patching Array, which will fail for cross-context arrays. They
>> do extend the concept of length to their Hash class:
>> getLength: function(){
>> var length = 0;
>> for (var key in this){
>> if (this.hasOwnProperty(key)) length++;
>> }
>> return length;
>> }
>> _______________________________________________
>> es-discuss mailing list
>> [email protected]
>> https://mail.mozilla.org/listinfo/es-discuss
>
>
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss