Skip to content

Instantly share code, notes, and snippets.

@rwaldron
Created July 27, 2012 07:01
Show Gist options
  • Save rwaldron/3186576 to your computer and use it in GitHub Desktop.
Save rwaldron/3186576 to your computer and use it in GitHub Desktop.
Correct implementation of Array.from and Array.of as they are currently spec'ed. Includes "isConstructor"
(function( global ) {
"use strict";
function isConstructor( C ) {
try {
new C();
return true;
} catch ( e ) {
return false;
}
}
Array.from = function( arrayLike ) {
var items, len, C, A, k, Pk, kPresent, kValue;
// 1. Let items be ToObject(arrayLike).
items = Object(arrayLike);
// 3. Let lenValue be the result of calling the [[Get]]
// internal method of items with the argument "length".
// 4. Let len be ToInteger(lenValue).
len = +items.length;
// 6. Let C be the |this| value.
C = this;
// 7. If isConstructor(C) is true, then
if ( isConstructor(C) ) {
// a. Let newObj be the result of calling the
// [[Construct]] internal method of C with an argument
// list containing the single item len.
// b. Let A be ToObject(newObj).
A = Object(new C(len));
} else {
A = new Array(len);
}
// 10. Let k be 0.
k = 0;
// 11. Repeat, while k < len
while ( k < len ) {
// a. Let Pk be ToString(k).
Pk = String(k);
// b. Let kPresent be the result of calling the [[HasProperty]]
// internal method of items with argument Pk.
kPresent = items.hasOwnProperty(Pk);
// c. If kPresent is true, then...
if ( kPresent ) {
// i. Let kValue be the result of calling the [[Get]]
// internal method of items with argument Pk.
kValue = items[ Pk ];
// ii. ReturnIfAbrupt(kValue).
// iii. Let defineStatus be the result of calling the
// [[DefineOwnProperty]] internal method of A with
// arguments Pk, Property Descriptor
// {[[Value]]: kValue.[[value]],
// [[Writable]]: true,
// [[Enumerable]]: true,
// [[Configurable]]: true}, and true.
A[ k ] = kValue;
}
// d. Increase k by 1.
k++;
}
// 14. Return A.
return A;
};
Array.of = function() {
var items, len, C, A, k, Pk, kPresent, kValue;
// X. Let items be ToObject(arrayLike).
items = Object(arguments);
// 1. Let lenValue be the result of calling the [[Get]]
// internal method of items with the argument "length".
// 2. Let len be ToInteger(lenValue).
len = +items.length;
// 3. Let C be the |this| value.
C = this;
// 4. If isConstructor(C) is true, then
if ( isConstructor(C) ) {
// a, b.
A = Object(new C(len));
} else {
// 5. Else, a.
A = new Array(len);
}
// 6. omitted
// 7. Let k be 0.
k = 0;
// 8. Repeat, while k < len
while ( k < len ) {
// a. Let Pk be ToString(k).
Pk = String(k);
// b. Let kValue be the result of calling the [[Get]]
// internal method of items with argument Pk.
kValue = items[ Pk ];
// c. Let defineStatus be the result of calling the
// [[DefineOwnProperty]] internal method of A with
// arguments Pk, Property Descriptor
// {[[Value]]: kValue.[[value]],
// [[Writable]]: true,
// [[Enumerable]]: true,
// [[Configurable]]: true}, and true.
A[ k ] = kValue;
// d. omitted
// e. Increase k by 1.
k++;
}
// 9, 10. omitted
// 11. Return A.
return A;
};
global.Array.from = Array.from;
global.Array.of = Array.of;
})( global );
{
// tests
var arrayLike = { 0: "a", 1: "b", 2: "c", length: 3 };
console.log( Array.from(arrayLike) );
console.log( Array.of(0) );
console.log( Array.of(1, null, undefined, false, 2) );
console.log( Array.of() );
var other = {
from: Array.from,
of: Array.of
};
console.log( other.from(arrayLike) );
console.log( other.of(1, null, undefined, false, 2) );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy