Is there any way to turn an existing Javascript object into an array without creating a new separate array?












7















There are a lot of mentions on differentes readings that arrays are a special class of object in Javascript. For example here:



https://www.codingame.com/playgrounds/6181/javascript-arrays---tips-tricks-and-examples



So, and since an object is a collection of properties (or keys) and values, I was thinking if there is a way to start with an object and ends with an array (in the sense that the method Array.isArray() returns true for that object emulating an array). I have started looking at the arrays properties:






let arr = [0, 1, 2, 3, 4, 5];
console.log(Object.getOwnPropertyNames(arr));
console.log(Array.isArray(arr));





So I tried to emulate the same using an object:






let arrEmulation = {0:0, 1:1, 2:2, 3:3, 4:4, 5:5, "length":6};
console.log(Object.getOwnPropertyNames(arrEmulation));
console.log(Array.isArray(arrEmulation));





But Array.isArray(arrEmulation) still returns false. First, I want to apologize if this is an stupid question, but is there any way I can manually convert an object to array adding special properties (or keys) to it?




Please, note I don't want to know how to convert object to array, I just want to understand which are those special things that make possible to interpret an object like an array.











share|improve this question









New contributor




SmaGal is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1





    Possible duplicate of How to convert an Object {} to an Array of key-value pairs in JavaScript

    – jmargolisvt
    3 hours ago






  • 7





    I don't believe the suggested duplicate addresses this portion of OP's question: "I just want to understand which are those special things that make possible to interpret an object like an array." OP, perhaps this MIT article might be of use. It's the one referenced in MDN's own isArray() documentation... though I'm not sure it really hits the detail you're looking for.

    – Tyler Roper
    3 hours ago








  • 1





    @jmargolisvt I don't want to know how to convert an object to array, I want to undesrtand what are the properties or keys that I need to add to an object so they are interpreted like an array.

    – SmaGal
    3 hours ago











  • @TylerRoper thanks, I'm going to give it a read...

    – SmaGal
    3 hours ago








  • 1





    Looking at the MDN polyfill (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) perhaps you can try getting Object.prototype.toString.call(arrEmulation) to return [object Array]. I'm not sure what the definition of that function is though.

    – david
    2 hours ago
















7















There are a lot of mentions on differentes readings that arrays are a special class of object in Javascript. For example here:



https://www.codingame.com/playgrounds/6181/javascript-arrays---tips-tricks-and-examples



So, and since an object is a collection of properties (or keys) and values, I was thinking if there is a way to start with an object and ends with an array (in the sense that the method Array.isArray() returns true for that object emulating an array). I have started looking at the arrays properties:






let arr = [0, 1, 2, 3, 4, 5];
console.log(Object.getOwnPropertyNames(arr));
console.log(Array.isArray(arr));





So I tried to emulate the same using an object:






let arrEmulation = {0:0, 1:1, 2:2, 3:3, 4:4, 5:5, "length":6};
console.log(Object.getOwnPropertyNames(arrEmulation));
console.log(Array.isArray(arrEmulation));





But Array.isArray(arrEmulation) still returns false. First, I want to apologize if this is an stupid question, but is there any way I can manually convert an object to array adding special properties (or keys) to it?




Please, note I don't want to know how to convert object to array, I just want to understand which are those special things that make possible to interpret an object like an array.











share|improve this question









New contributor




SmaGal is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1





    Possible duplicate of How to convert an Object {} to an Array of key-value pairs in JavaScript

    – jmargolisvt
    3 hours ago






  • 7





    I don't believe the suggested duplicate addresses this portion of OP's question: "I just want to understand which are those special things that make possible to interpret an object like an array." OP, perhaps this MIT article might be of use. It's the one referenced in MDN's own isArray() documentation... though I'm not sure it really hits the detail you're looking for.

    – Tyler Roper
    3 hours ago








  • 1





    @jmargolisvt I don't want to know how to convert an object to array, I want to undesrtand what are the properties or keys that I need to add to an object so they are interpreted like an array.

    – SmaGal
    3 hours ago











  • @TylerRoper thanks, I'm going to give it a read...

    – SmaGal
    3 hours ago








  • 1





    Looking at the MDN polyfill (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) perhaps you can try getting Object.prototype.toString.call(arrEmulation) to return [object Array]. I'm not sure what the definition of that function is though.

    – david
    2 hours ago














7












7








7


1






There are a lot of mentions on differentes readings that arrays are a special class of object in Javascript. For example here:



https://www.codingame.com/playgrounds/6181/javascript-arrays---tips-tricks-and-examples



So, and since an object is a collection of properties (or keys) and values, I was thinking if there is a way to start with an object and ends with an array (in the sense that the method Array.isArray() returns true for that object emulating an array). I have started looking at the arrays properties:






let arr = [0, 1, 2, 3, 4, 5];
console.log(Object.getOwnPropertyNames(arr));
console.log(Array.isArray(arr));





So I tried to emulate the same using an object:






let arrEmulation = {0:0, 1:1, 2:2, 3:3, 4:4, 5:5, "length":6};
console.log(Object.getOwnPropertyNames(arrEmulation));
console.log(Array.isArray(arrEmulation));





But Array.isArray(arrEmulation) still returns false. First, I want to apologize if this is an stupid question, but is there any way I can manually convert an object to array adding special properties (or keys) to it?




Please, note I don't want to know how to convert object to array, I just want to understand which are those special things that make possible to interpret an object like an array.











share|improve this question









New contributor




SmaGal is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












There are a lot of mentions on differentes readings that arrays are a special class of object in Javascript. For example here:



https://www.codingame.com/playgrounds/6181/javascript-arrays---tips-tricks-and-examples



So, and since an object is a collection of properties (or keys) and values, I was thinking if there is a way to start with an object and ends with an array (in the sense that the method Array.isArray() returns true for that object emulating an array). I have started looking at the arrays properties:






let arr = [0, 1, 2, 3, 4, 5];
console.log(Object.getOwnPropertyNames(arr));
console.log(Array.isArray(arr));





So I tried to emulate the same using an object:






let arrEmulation = {0:0, 1:1, 2:2, 3:3, 4:4, 5:5, "length":6};
console.log(Object.getOwnPropertyNames(arrEmulation));
console.log(Array.isArray(arrEmulation));





But Array.isArray(arrEmulation) still returns false. First, I want to apologize if this is an stupid question, but is there any way I can manually convert an object to array adding special properties (or keys) to it?




Please, note I don't want to know how to convert object to array, I just want to understand which are those special things that make possible to interpret an object like an array.







let arr = [0, 1, 2, 3, 4, 5];
console.log(Object.getOwnPropertyNames(arr));
console.log(Array.isArray(arr));





let arr = [0, 1, 2, 3, 4, 5];
console.log(Object.getOwnPropertyNames(arr));
console.log(Array.isArray(arr));





let arrEmulation = {0:0, 1:1, 2:2, 3:3, 4:4, 5:5, "length":6};
console.log(Object.getOwnPropertyNames(arrEmulation));
console.log(Array.isArray(arrEmulation));





let arrEmulation = {0:0, 1:1, 2:2, 3:3, 4:4, 5:5, "length":6};
console.log(Object.getOwnPropertyNames(arrEmulation));
console.log(Array.isArray(arrEmulation));






javascript arrays object






share|improve this question









New contributor




SmaGal is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




SmaGal is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 1 hour ago









CertainPerformance

84.3k154169




84.3k154169






New contributor




SmaGal is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 3 hours ago









SmaGalSmaGal

625




625




New contributor




SmaGal is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





SmaGal is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






SmaGal is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








  • 1





    Possible duplicate of How to convert an Object {} to an Array of key-value pairs in JavaScript

    – jmargolisvt
    3 hours ago






  • 7





    I don't believe the suggested duplicate addresses this portion of OP's question: "I just want to understand which are those special things that make possible to interpret an object like an array." OP, perhaps this MIT article might be of use. It's the one referenced in MDN's own isArray() documentation... though I'm not sure it really hits the detail you're looking for.

    – Tyler Roper
    3 hours ago








  • 1





    @jmargolisvt I don't want to know how to convert an object to array, I want to undesrtand what are the properties or keys that I need to add to an object so they are interpreted like an array.

    – SmaGal
    3 hours ago











  • @TylerRoper thanks, I'm going to give it a read...

    – SmaGal
    3 hours ago








  • 1





    Looking at the MDN polyfill (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) perhaps you can try getting Object.prototype.toString.call(arrEmulation) to return [object Array]. I'm not sure what the definition of that function is though.

    – david
    2 hours ago














  • 1





    Possible duplicate of How to convert an Object {} to an Array of key-value pairs in JavaScript

    – jmargolisvt
    3 hours ago






  • 7





    I don't believe the suggested duplicate addresses this portion of OP's question: "I just want to understand which are those special things that make possible to interpret an object like an array." OP, perhaps this MIT article might be of use. It's the one referenced in MDN's own isArray() documentation... though I'm not sure it really hits the detail you're looking for.

    – Tyler Roper
    3 hours ago








  • 1





    @jmargolisvt I don't want to know how to convert an object to array, I want to undesrtand what are the properties or keys that I need to add to an object so they are interpreted like an array.

    – SmaGal
    3 hours ago











  • @TylerRoper thanks, I'm going to give it a read...

    – SmaGal
    3 hours ago








  • 1





    Looking at the MDN polyfill (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) perhaps you can try getting Object.prototype.toString.call(arrEmulation) to return [object Array]. I'm not sure what the definition of that function is though.

    – david
    2 hours ago








1




1





Possible duplicate of How to convert an Object {} to an Array of key-value pairs in JavaScript

– jmargolisvt
3 hours ago





Possible duplicate of How to convert an Object {} to an Array of key-value pairs in JavaScript

– jmargolisvt
3 hours ago




7




7





I don't believe the suggested duplicate addresses this portion of OP's question: "I just want to understand which are those special things that make possible to interpret an object like an array." OP, perhaps this MIT article might be of use. It's the one referenced in MDN's own isArray() documentation... though I'm not sure it really hits the detail you're looking for.

– Tyler Roper
3 hours ago







I don't believe the suggested duplicate addresses this portion of OP's question: "I just want to understand which are those special things that make possible to interpret an object like an array." OP, perhaps this MIT article might be of use. It's the one referenced in MDN's own isArray() documentation... though I'm not sure it really hits the detail you're looking for.

– Tyler Roper
3 hours ago






1




1





@jmargolisvt I don't want to know how to convert an object to array, I want to undesrtand what are the properties or keys that I need to add to an object so they are interpreted like an array.

– SmaGal
3 hours ago





@jmargolisvt I don't want to know how to convert an object to array, I want to undesrtand what are the properties or keys that I need to add to an object so they are interpreted like an array.

– SmaGal
3 hours ago













@TylerRoper thanks, I'm going to give it a read...

– SmaGal
3 hours ago







@TylerRoper thanks, I'm going to give it a read...

– SmaGal
3 hours ago






1




1





Looking at the MDN polyfill (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) perhaps you can try getting Object.prototype.toString.call(arrEmulation) to return [object Array]. I'm not sure what the definition of that function is though.

– david
2 hours ago





Looking at the MDN polyfill (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) perhaps you can try getting Object.prototype.toString.call(arrEmulation) to return [object Array]. I'm not sure what the definition of that function is though.

– david
2 hours ago












4 Answers
4






active

oldest

votes


















3














I don't think it's possible, in the strictest sense, given the standard specification. Looking up Array.isArray:




If the value of the [[Class]] internal property of arg is "Array", then return true.




So, for Array.isArray(arrEmulation) to return true, you must somehow modify the [[Class]] of the object to be Array, rather than Object. But, looking at ES5's 8.6.2 Object Internal Properties and Methods regarding [[Class]]:




Note: This specification defines no ECMAScript language operators or built-in functions that permit a program to modify an object’s [[Class]] or [[Prototype]] internal properties or to change the value of [[Extensible]] from false to true. Implementation specific extensions that modify [[Class]], [[Prototype]] or [[Extensible]] must not violate the invariants defined in the preceding paragraph.




Also:




Note that this specification does not provide any means for a program to access that value except through Object.prototype.toString




So, the official specification doesn't provide a way to do it in ES5 - if there was a way to do it, it would be non-standard and implementation dependent.



That said, unless you absolutely need to use Array.isArray or have Object.prototype.toString.call(arrEmulation) to return [object Array], you can still use Object.setPrototypeOf to set the prototype of arrEmulation to Array.prototype, allowing you to use array methods on the object and have instanceof Array return true:






const arrEmulation = {0:0, 1:1, 2:2, "length":6};
Object.setPrototypeOf(arrEmulation, Array.prototype);

console.log(arrEmulation instanceof Array);
arrEmulation.forEach((value) => {
console.log(value);
});
// Internal [[Class]] property is still `Object`, though:
console.log(Object.prototype.toString.call(arrEmulation));
// Unlike a true array:
console.log(Object.prototype.toString.call());

console.log('-----');

// although you can set the `toStringTag` to the string 'Array' in ES6+,
// it is cosmetic only and does not pass an `Array.isArray` test:
arrEmulation[Symbol.toStringTag] = 'Array';
console.log(Object.prototype.toString.call(arrEmulation));
console.log(Array.isArray(arrEmulation));





But note that you should avoid using Object.setPrototypeOf in real code:




Warning: Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, a very slow operation, in every browser and JavaScript engine. The effects on performance of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in the Object.setPrototypeOf(...) statement, but may extend to any code that has access to any object whose [[Prototype]] has been altered. If you care about performance you should avoid setting the [[Prototype]] of an object. Instead, create a new object with the desired [[Prototype]] using Object.create().




(of course, Object.create involves creating a new object, which is different from what you want to do, which is to change the existing arrEmulation object)



There doesn't look to be a way to do it in ES6+ either - its text is somewhat similar, but not identical. Specifically, for Array.isArray to return true, the object in question needs to be an "Array exotic object" (or a Proxy that points to one) - but setPrototypeOf only sets the prototype, neither it nor any other method can make the object actually become an Array exotic object (which looks like it has to be natively constructed by the interpreter, and is not emulatable enough).






share|improve this answer


























  • Thanks dude, this information gives me some more clarity to understand the differences between and standard object and an array. Just to you know, I'm not really looking to emulate an array with an object, but just to understand they differences and this helps me. +1!

    – SmaGal
    2 hours ago



















1














Javascript is all about prototypal inheritance:




Prototype Inheritance
All JavaScript objects inherit properties and methods from a
prototype:



Date objects inherit from Date.prototype Array objects inherit from
Array.prototype Person objects inherit from Person.prototype The
Object.prototype is on the top of the prototype inheritance chain:



Date objects, Array objects, and Person objects inherit from
Object.prototype.




As seen here isArray is an function in prototype chain of the Array object.



An polyfill as suggested in MDN Array.isArray() alternate if isArray is not present is:



if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}


So the type is determined by the prototype chain instead of what value it returns.




Similarly, as per Tio Zed's answer



const newArray = Array.from(arrEmulation) // [0, 1, 2, 3, 4, 5]
Array.isArray(newArray)



What it really does is just change to prototype from that of object to that of an Array.



A deeper go through of isArray thanks @Kaiido for making me dig deeper.
The Array is array checks these there points




If Type(arg) is not Object, return false.
If the value of the [[Class]] internal property of arg is "Array",
then return true. Return false.




And




Array instances inherit properties from the Array prototype object and
their [[Class]] internal property value is "Array". Array instances
also have the following properties.







share|improve this answer


























  • Hum... nope. That's not what Array.isArray checks. That is a simple polyfill posted on an MDN article, it is in no way how any browser will implement it. Here is what the specs asks though they're not clear as to how the check is made to know if it is an Array exotic Object. And here is a proof that it's not how it is implemented: jsfiddle.net/f6182mkh

    – Kaiido
    1 hour ago











  • I edited my answer I just wanted to show that it all depends on prototypes and not the keys they see in the value. BTW thanks for correcting me. Please edit my answer if you still feel something wrong with my answer. @Kaiido

    – Black Mamba
    1 hour ago











  • Well even the prototype thing is not correct either: jsfiddle.net/vLrgdp86

    – Kaiido
    1 hour ago











  • The above I defined is currently used as a Polyfill in many browsers that doesn't support it. I've searched about how it is currently officially implemented but got no success. It'll be helpful if you can provide me a doc for it. Here's a little detail about the Array.isArray I've been able to find. A official doc is here showing how prototypes are implemented for defining array @Kaiido

    – Black Mamba
    57 mins ago





















1















Turn an existing Javascript object into an array without creating a new separate array




This feels like an adapter pattern, for which JS Proxy seems suited.



Ok, the code to implement this is quite lengthy, and technically we do need a new Array() to meet the requirements of Array.isArray(), but if you have a particularly big object and do not wish to transfer all it's properties to an array, this might fit the bill.






console.clear()
let arrProxy = new Proxy(new Array(), {
get: function(target, property) {
if (property === 'length') {
return length;
}
if (property in target.data) {
return target.data[property];
}
if (property in Array.prototype) {
return Array.prototype[property].bind(obj);
}
},
set: function(target, property, value) {
if (property === 'length') {
for (var i = value; i < length; i++) {
delete target[i];
}
length = value;
return;
}
target.data[property] = value;
if (Number(property) >= length) {
length = Number(property) + 1;
}
},
ownKeys: function(target) { // for getOwnPropertyNames()
return [...Object.keys(target.data), 'length']
}
})

let arrEmulation = {0:'a', 1:'b', 2:'c'};
arrProxy.data = arrEmulation

console.log(Object.getOwnPropertyNames(arrProxy));
console.log(arrProxy[0]);
console.log(arrProxy[1]);
console.log(arrProxy[2]);
console.log(Array.isArray(arrProxy));







I should attribute the source - this is adapted from https://gist.github.com/alessioalex/c0562958b112ae7fcccd






share|improve this answer

































    0














    You can convert anything that is close enough to an array by using Array.from().
    In your example, we could just call:



    const arrEmulation = {0:0, 1:1, 2:2, 3:3, 4:4, 5:5, length: 6};

    const newArray = Array.from(arrEmulation) // [0, 1, 2, 3, 4, 5]
    Array.isArray(newArray) // true





    share|improve this answer



















    • 1





      I'm not looking at how to convert object to array, but to understand they differences...

      – SmaGal
      2 hours ago






    • 1





      @SmaGal, be fair - do you not say 'convert' in the question title?

      – eric99
      2 hours ago











    • @eric99 the down-vote don't come from me. I just explained that I was not looking for that.

      – SmaGal
      1 hour ago











    • @SmaGal my comment was a bit tongue-in-cheek. TioZed deserves some credit for his answer, given the question has now morphed into something more specific.

      – eric99
      1 hour ago











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });






    SmaGal is a new contributor. Be nice, and check out our Code of Conduct.










    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54527480%2fis-there-any-way-to-turn-an-existing-javascript-object-into-an-array-without-cre%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    I don't think it's possible, in the strictest sense, given the standard specification. Looking up Array.isArray:




    If the value of the [[Class]] internal property of arg is "Array", then return true.




    So, for Array.isArray(arrEmulation) to return true, you must somehow modify the [[Class]] of the object to be Array, rather than Object. But, looking at ES5's 8.6.2 Object Internal Properties and Methods regarding [[Class]]:




    Note: This specification defines no ECMAScript language operators or built-in functions that permit a program to modify an object’s [[Class]] or [[Prototype]] internal properties or to change the value of [[Extensible]] from false to true. Implementation specific extensions that modify [[Class]], [[Prototype]] or [[Extensible]] must not violate the invariants defined in the preceding paragraph.




    Also:




    Note that this specification does not provide any means for a program to access that value except through Object.prototype.toString




    So, the official specification doesn't provide a way to do it in ES5 - if there was a way to do it, it would be non-standard and implementation dependent.



    That said, unless you absolutely need to use Array.isArray or have Object.prototype.toString.call(arrEmulation) to return [object Array], you can still use Object.setPrototypeOf to set the prototype of arrEmulation to Array.prototype, allowing you to use array methods on the object and have instanceof Array return true:






    const arrEmulation = {0:0, 1:1, 2:2, "length":6};
    Object.setPrototypeOf(arrEmulation, Array.prototype);

    console.log(arrEmulation instanceof Array);
    arrEmulation.forEach((value) => {
    console.log(value);
    });
    // Internal [[Class]] property is still `Object`, though:
    console.log(Object.prototype.toString.call(arrEmulation));
    // Unlike a true array:
    console.log(Object.prototype.toString.call());

    console.log('-----');

    // although you can set the `toStringTag` to the string 'Array' in ES6+,
    // it is cosmetic only and does not pass an `Array.isArray` test:
    arrEmulation[Symbol.toStringTag] = 'Array';
    console.log(Object.prototype.toString.call(arrEmulation));
    console.log(Array.isArray(arrEmulation));





    But note that you should avoid using Object.setPrototypeOf in real code:




    Warning: Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, a very slow operation, in every browser and JavaScript engine. The effects on performance of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in the Object.setPrototypeOf(...) statement, but may extend to any code that has access to any object whose [[Prototype]] has been altered. If you care about performance you should avoid setting the [[Prototype]] of an object. Instead, create a new object with the desired [[Prototype]] using Object.create().




    (of course, Object.create involves creating a new object, which is different from what you want to do, which is to change the existing arrEmulation object)



    There doesn't look to be a way to do it in ES6+ either - its text is somewhat similar, but not identical. Specifically, for Array.isArray to return true, the object in question needs to be an "Array exotic object" (or a Proxy that points to one) - but setPrototypeOf only sets the prototype, neither it nor any other method can make the object actually become an Array exotic object (which looks like it has to be natively constructed by the interpreter, and is not emulatable enough).






    share|improve this answer


























    • Thanks dude, this information gives me some more clarity to understand the differences between and standard object and an array. Just to you know, I'm not really looking to emulate an array with an object, but just to understand they differences and this helps me. +1!

      – SmaGal
      2 hours ago
















    3














    I don't think it's possible, in the strictest sense, given the standard specification. Looking up Array.isArray:




    If the value of the [[Class]] internal property of arg is "Array", then return true.




    So, for Array.isArray(arrEmulation) to return true, you must somehow modify the [[Class]] of the object to be Array, rather than Object. But, looking at ES5's 8.6.2 Object Internal Properties and Methods regarding [[Class]]:




    Note: This specification defines no ECMAScript language operators or built-in functions that permit a program to modify an object’s [[Class]] or [[Prototype]] internal properties or to change the value of [[Extensible]] from false to true. Implementation specific extensions that modify [[Class]], [[Prototype]] or [[Extensible]] must not violate the invariants defined in the preceding paragraph.




    Also:




    Note that this specification does not provide any means for a program to access that value except through Object.prototype.toString




    So, the official specification doesn't provide a way to do it in ES5 - if there was a way to do it, it would be non-standard and implementation dependent.



    That said, unless you absolutely need to use Array.isArray or have Object.prototype.toString.call(arrEmulation) to return [object Array], you can still use Object.setPrototypeOf to set the prototype of arrEmulation to Array.prototype, allowing you to use array methods on the object and have instanceof Array return true:






    const arrEmulation = {0:0, 1:1, 2:2, "length":6};
    Object.setPrototypeOf(arrEmulation, Array.prototype);

    console.log(arrEmulation instanceof Array);
    arrEmulation.forEach((value) => {
    console.log(value);
    });
    // Internal [[Class]] property is still `Object`, though:
    console.log(Object.prototype.toString.call(arrEmulation));
    // Unlike a true array:
    console.log(Object.prototype.toString.call());

    console.log('-----');

    // although you can set the `toStringTag` to the string 'Array' in ES6+,
    // it is cosmetic only and does not pass an `Array.isArray` test:
    arrEmulation[Symbol.toStringTag] = 'Array';
    console.log(Object.prototype.toString.call(arrEmulation));
    console.log(Array.isArray(arrEmulation));





    But note that you should avoid using Object.setPrototypeOf in real code:




    Warning: Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, a very slow operation, in every browser and JavaScript engine. The effects on performance of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in the Object.setPrototypeOf(...) statement, but may extend to any code that has access to any object whose [[Prototype]] has been altered. If you care about performance you should avoid setting the [[Prototype]] of an object. Instead, create a new object with the desired [[Prototype]] using Object.create().




    (of course, Object.create involves creating a new object, which is different from what you want to do, which is to change the existing arrEmulation object)



    There doesn't look to be a way to do it in ES6+ either - its text is somewhat similar, but not identical. Specifically, for Array.isArray to return true, the object in question needs to be an "Array exotic object" (or a Proxy that points to one) - but setPrototypeOf only sets the prototype, neither it nor any other method can make the object actually become an Array exotic object (which looks like it has to be natively constructed by the interpreter, and is not emulatable enough).






    share|improve this answer


























    • Thanks dude, this information gives me some more clarity to understand the differences between and standard object and an array. Just to you know, I'm not really looking to emulate an array with an object, but just to understand they differences and this helps me. +1!

      – SmaGal
      2 hours ago














    3












    3








    3







    I don't think it's possible, in the strictest sense, given the standard specification. Looking up Array.isArray:




    If the value of the [[Class]] internal property of arg is "Array", then return true.




    So, for Array.isArray(arrEmulation) to return true, you must somehow modify the [[Class]] of the object to be Array, rather than Object. But, looking at ES5's 8.6.2 Object Internal Properties and Methods regarding [[Class]]:




    Note: This specification defines no ECMAScript language operators or built-in functions that permit a program to modify an object’s [[Class]] or [[Prototype]] internal properties or to change the value of [[Extensible]] from false to true. Implementation specific extensions that modify [[Class]], [[Prototype]] or [[Extensible]] must not violate the invariants defined in the preceding paragraph.




    Also:




    Note that this specification does not provide any means for a program to access that value except through Object.prototype.toString




    So, the official specification doesn't provide a way to do it in ES5 - if there was a way to do it, it would be non-standard and implementation dependent.



    That said, unless you absolutely need to use Array.isArray or have Object.prototype.toString.call(arrEmulation) to return [object Array], you can still use Object.setPrototypeOf to set the prototype of arrEmulation to Array.prototype, allowing you to use array methods on the object and have instanceof Array return true:






    const arrEmulation = {0:0, 1:1, 2:2, "length":6};
    Object.setPrototypeOf(arrEmulation, Array.prototype);

    console.log(arrEmulation instanceof Array);
    arrEmulation.forEach((value) => {
    console.log(value);
    });
    // Internal [[Class]] property is still `Object`, though:
    console.log(Object.prototype.toString.call(arrEmulation));
    // Unlike a true array:
    console.log(Object.prototype.toString.call());

    console.log('-----');

    // although you can set the `toStringTag` to the string 'Array' in ES6+,
    // it is cosmetic only and does not pass an `Array.isArray` test:
    arrEmulation[Symbol.toStringTag] = 'Array';
    console.log(Object.prototype.toString.call(arrEmulation));
    console.log(Array.isArray(arrEmulation));





    But note that you should avoid using Object.setPrototypeOf in real code:




    Warning: Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, a very slow operation, in every browser and JavaScript engine. The effects on performance of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in the Object.setPrototypeOf(...) statement, but may extend to any code that has access to any object whose [[Prototype]] has been altered. If you care about performance you should avoid setting the [[Prototype]] of an object. Instead, create a new object with the desired [[Prototype]] using Object.create().




    (of course, Object.create involves creating a new object, which is different from what you want to do, which is to change the existing arrEmulation object)



    There doesn't look to be a way to do it in ES6+ either - its text is somewhat similar, but not identical. Specifically, for Array.isArray to return true, the object in question needs to be an "Array exotic object" (or a Proxy that points to one) - but setPrototypeOf only sets the prototype, neither it nor any other method can make the object actually become an Array exotic object (which looks like it has to be natively constructed by the interpreter, and is not emulatable enough).






    share|improve this answer















    I don't think it's possible, in the strictest sense, given the standard specification. Looking up Array.isArray:




    If the value of the [[Class]] internal property of arg is "Array", then return true.




    So, for Array.isArray(arrEmulation) to return true, you must somehow modify the [[Class]] of the object to be Array, rather than Object. But, looking at ES5's 8.6.2 Object Internal Properties and Methods regarding [[Class]]:




    Note: This specification defines no ECMAScript language operators or built-in functions that permit a program to modify an object’s [[Class]] or [[Prototype]] internal properties or to change the value of [[Extensible]] from false to true. Implementation specific extensions that modify [[Class]], [[Prototype]] or [[Extensible]] must not violate the invariants defined in the preceding paragraph.




    Also:




    Note that this specification does not provide any means for a program to access that value except through Object.prototype.toString




    So, the official specification doesn't provide a way to do it in ES5 - if there was a way to do it, it would be non-standard and implementation dependent.



    That said, unless you absolutely need to use Array.isArray or have Object.prototype.toString.call(arrEmulation) to return [object Array], you can still use Object.setPrototypeOf to set the prototype of arrEmulation to Array.prototype, allowing you to use array methods on the object and have instanceof Array return true:






    const arrEmulation = {0:0, 1:1, 2:2, "length":6};
    Object.setPrototypeOf(arrEmulation, Array.prototype);

    console.log(arrEmulation instanceof Array);
    arrEmulation.forEach((value) => {
    console.log(value);
    });
    // Internal [[Class]] property is still `Object`, though:
    console.log(Object.prototype.toString.call(arrEmulation));
    // Unlike a true array:
    console.log(Object.prototype.toString.call());

    console.log('-----');

    // although you can set the `toStringTag` to the string 'Array' in ES6+,
    // it is cosmetic only and does not pass an `Array.isArray` test:
    arrEmulation[Symbol.toStringTag] = 'Array';
    console.log(Object.prototype.toString.call(arrEmulation));
    console.log(Array.isArray(arrEmulation));





    But note that you should avoid using Object.setPrototypeOf in real code:




    Warning: Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, a very slow operation, in every browser and JavaScript engine. The effects on performance of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in the Object.setPrototypeOf(...) statement, but may extend to any code that has access to any object whose [[Prototype]] has been altered. If you care about performance you should avoid setting the [[Prototype]] of an object. Instead, create a new object with the desired [[Prototype]] using Object.create().




    (of course, Object.create involves creating a new object, which is different from what you want to do, which is to change the existing arrEmulation object)



    There doesn't look to be a way to do it in ES6+ either - its text is somewhat similar, but not identical. Specifically, for Array.isArray to return true, the object in question needs to be an "Array exotic object" (or a Proxy that points to one) - but setPrototypeOf only sets the prototype, neither it nor any other method can make the object actually become an Array exotic object (which looks like it has to be natively constructed by the interpreter, and is not emulatable enough).






    const arrEmulation = {0:0, 1:1, 2:2, "length":6};
    Object.setPrototypeOf(arrEmulation, Array.prototype);

    console.log(arrEmulation instanceof Array);
    arrEmulation.forEach((value) => {
    console.log(value);
    });
    // Internal [[Class]] property is still `Object`, though:
    console.log(Object.prototype.toString.call(arrEmulation));
    // Unlike a true array:
    console.log(Object.prototype.toString.call());

    console.log('-----');

    // although you can set the `toStringTag` to the string 'Array' in ES6+,
    // it is cosmetic only and does not pass an `Array.isArray` test:
    arrEmulation[Symbol.toStringTag] = 'Array';
    console.log(Object.prototype.toString.call(arrEmulation));
    console.log(Array.isArray(arrEmulation));





    const arrEmulation = {0:0, 1:1, 2:2, "length":6};
    Object.setPrototypeOf(arrEmulation, Array.prototype);

    console.log(arrEmulation instanceof Array);
    arrEmulation.forEach((value) => {
    console.log(value);
    });
    // Internal [[Class]] property is still `Object`, though:
    console.log(Object.prototype.toString.call(arrEmulation));
    // Unlike a true array:
    console.log(Object.prototype.toString.call());

    console.log('-----');

    // although you can set the `toStringTag` to the string 'Array' in ES6+,
    // it is cosmetic only and does not pass an `Array.isArray` test:
    arrEmulation[Symbol.toStringTag] = 'Array';
    console.log(Object.prototype.toString.call(arrEmulation));
    console.log(Array.isArray(arrEmulation));






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 2 hours ago

























    answered 2 hours ago









    CertainPerformanceCertainPerformance

    84.3k154169




    84.3k154169













    • Thanks dude, this information gives me some more clarity to understand the differences between and standard object and an array. Just to you know, I'm not really looking to emulate an array with an object, but just to understand they differences and this helps me. +1!

      – SmaGal
      2 hours ago



















    • Thanks dude, this information gives me some more clarity to understand the differences between and standard object and an array. Just to you know, I'm not really looking to emulate an array with an object, but just to understand they differences and this helps me. +1!

      – SmaGal
      2 hours ago

















    Thanks dude, this information gives me some more clarity to understand the differences between and standard object and an array. Just to you know, I'm not really looking to emulate an array with an object, but just to understand they differences and this helps me. +1!

    – SmaGal
    2 hours ago





    Thanks dude, this information gives me some more clarity to understand the differences between and standard object and an array. Just to you know, I'm not really looking to emulate an array with an object, but just to understand they differences and this helps me. +1!

    – SmaGal
    2 hours ago













    1














    Javascript is all about prototypal inheritance:




    Prototype Inheritance
    All JavaScript objects inherit properties and methods from a
    prototype:



    Date objects inherit from Date.prototype Array objects inherit from
    Array.prototype Person objects inherit from Person.prototype The
    Object.prototype is on the top of the prototype inheritance chain:



    Date objects, Array objects, and Person objects inherit from
    Object.prototype.




    As seen here isArray is an function in prototype chain of the Array object.



    An polyfill as suggested in MDN Array.isArray() alternate if isArray is not present is:



    if (!Array.isArray) {
    Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
    };
    }


    So the type is determined by the prototype chain instead of what value it returns.




    Similarly, as per Tio Zed's answer



    const newArray = Array.from(arrEmulation) // [0, 1, 2, 3, 4, 5]
    Array.isArray(newArray)



    What it really does is just change to prototype from that of object to that of an Array.



    A deeper go through of isArray thanks @Kaiido for making me dig deeper.
    The Array is array checks these there points




    If Type(arg) is not Object, return false.
    If the value of the [[Class]] internal property of arg is "Array",
    then return true. Return false.




    And




    Array instances inherit properties from the Array prototype object and
    their [[Class]] internal property value is "Array". Array instances
    also have the following properties.







    share|improve this answer


























    • Hum... nope. That's not what Array.isArray checks. That is a simple polyfill posted on an MDN article, it is in no way how any browser will implement it. Here is what the specs asks though they're not clear as to how the check is made to know if it is an Array exotic Object. And here is a proof that it's not how it is implemented: jsfiddle.net/f6182mkh

      – Kaiido
      1 hour ago











    • I edited my answer I just wanted to show that it all depends on prototypes and not the keys they see in the value. BTW thanks for correcting me. Please edit my answer if you still feel something wrong with my answer. @Kaiido

      – Black Mamba
      1 hour ago











    • Well even the prototype thing is not correct either: jsfiddle.net/vLrgdp86

      – Kaiido
      1 hour ago











    • The above I defined is currently used as a Polyfill in many browsers that doesn't support it. I've searched about how it is currently officially implemented but got no success. It'll be helpful if you can provide me a doc for it. Here's a little detail about the Array.isArray I've been able to find. A official doc is here showing how prototypes are implemented for defining array @Kaiido

      – Black Mamba
      57 mins ago


















    1














    Javascript is all about prototypal inheritance:




    Prototype Inheritance
    All JavaScript objects inherit properties and methods from a
    prototype:



    Date objects inherit from Date.prototype Array objects inherit from
    Array.prototype Person objects inherit from Person.prototype The
    Object.prototype is on the top of the prototype inheritance chain:



    Date objects, Array objects, and Person objects inherit from
    Object.prototype.




    As seen here isArray is an function in prototype chain of the Array object.



    An polyfill as suggested in MDN Array.isArray() alternate if isArray is not present is:



    if (!Array.isArray) {
    Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
    };
    }


    So the type is determined by the prototype chain instead of what value it returns.




    Similarly, as per Tio Zed's answer



    const newArray = Array.from(arrEmulation) // [0, 1, 2, 3, 4, 5]
    Array.isArray(newArray)



    What it really does is just change to prototype from that of object to that of an Array.



    A deeper go through of isArray thanks @Kaiido for making me dig deeper.
    The Array is array checks these there points




    If Type(arg) is not Object, return false.
    If the value of the [[Class]] internal property of arg is "Array",
    then return true. Return false.




    And




    Array instances inherit properties from the Array prototype object and
    their [[Class]] internal property value is "Array". Array instances
    also have the following properties.







    share|improve this answer


























    • Hum... nope. That's not what Array.isArray checks. That is a simple polyfill posted on an MDN article, it is in no way how any browser will implement it. Here is what the specs asks though they're not clear as to how the check is made to know if it is an Array exotic Object. And here is a proof that it's not how it is implemented: jsfiddle.net/f6182mkh

      – Kaiido
      1 hour ago











    • I edited my answer I just wanted to show that it all depends on prototypes and not the keys they see in the value. BTW thanks for correcting me. Please edit my answer if you still feel something wrong with my answer. @Kaiido

      – Black Mamba
      1 hour ago











    • Well even the prototype thing is not correct either: jsfiddle.net/vLrgdp86

      – Kaiido
      1 hour ago











    • The above I defined is currently used as a Polyfill in many browsers that doesn't support it. I've searched about how it is currently officially implemented but got no success. It'll be helpful if you can provide me a doc for it. Here's a little detail about the Array.isArray I've been able to find. A official doc is here showing how prototypes are implemented for defining array @Kaiido

      – Black Mamba
      57 mins ago
















    1












    1








    1







    Javascript is all about prototypal inheritance:




    Prototype Inheritance
    All JavaScript objects inherit properties and methods from a
    prototype:



    Date objects inherit from Date.prototype Array objects inherit from
    Array.prototype Person objects inherit from Person.prototype The
    Object.prototype is on the top of the prototype inheritance chain:



    Date objects, Array objects, and Person objects inherit from
    Object.prototype.




    As seen here isArray is an function in prototype chain of the Array object.



    An polyfill as suggested in MDN Array.isArray() alternate if isArray is not present is:



    if (!Array.isArray) {
    Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
    };
    }


    So the type is determined by the prototype chain instead of what value it returns.




    Similarly, as per Tio Zed's answer



    const newArray = Array.from(arrEmulation) // [0, 1, 2, 3, 4, 5]
    Array.isArray(newArray)



    What it really does is just change to prototype from that of object to that of an Array.



    A deeper go through of isArray thanks @Kaiido for making me dig deeper.
    The Array is array checks these there points




    If Type(arg) is not Object, return false.
    If the value of the [[Class]] internal property of arg is "Array",
    then return true. Return false.




    And




    Array instances inherit properties from the Array prototype object and
    their [[Class]] internal property value is "Array". Array instances
    also have the following properties.







    share|improve this answer















    Javascript is all about prototypal inheritance:




    Prototype Inheritance
    All JavaScript objects inherit properties and methods from a
    prototype:



    Date objects inherit from Date.prototype Array objects inherit from
    Array.prototype Person objects inherit from Person.prototype The
    Object.prototype is on the top of the prototype inheritance chain:



    Date objects, Array objects, and Person objects inherit from
    Object.prototype.




    As seen here isArray is an function in prototype chain of the Array object.



    An polyfill as suggested in MDN Array.isArray() alternate if isArray is not present is:



    if (!Array.isArray) {
    Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
    };
    }


    So the type is determined by the prototype chain instead of what value it returns.




    Similarly, as per Tio Zed's answer



    const newArray = Array.from(arrEmulation) // [0, 1, 2, 3, 4, 5]
    Array.isArray(newArray)



    What it really does is just change to prototype from that of object to that of an Array.



    A deeper go through of isArray thanks @Kaiido for making me dig deeper.
    The Array is array checks these there points




    If Type(arg) is not Object, return false.
    If the value of the [[Class]] internal property of arg is "Array",
    then return true. Return false.




    And




    Array instances inherit properties from the Array prototype object and
    their [[Class]] internal property value is "Array". Array instances
    also have the following properties.








    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 52 mins ago

























    answered 2 hours ago









    Black MambaBlack Mamba

    2,76912139




    2,76912139













    • Hum... nope. That's not what Array.isArray checks. That is a simple polyfill posted on an MDN article, it is in no way how any browser will implement it. Here is what the specs asks though they're not clear as to how the check is made to know if it is an Array exotic Object. And here is a proof that it's not how it is implemented: jsfiddle.net/f6182mkh

      – Kaiido
      1 hour ago











    • I edited my answer I just wanted to show that it all depends on prototypes and not the keys they see in the value. BTW thanks for correcting me. Please edit my answer if you still feel something wrong with my answer. @Kaiido

      – Black Mamba
      1 hour ago











    • Well even the prototype thing is not correct either: jsfiddle.net/vLrgdp86

      – Kaiido
      1 hour ago











    • The above I defined is currently used as a Polyfill in many browsers that doesn't support it. I've searched about how it is currently officially implemented but got no success. It'll be helpful if you can provide me a doc for it. Here's a little detail about the Array.isArray I've been able to find. A official doc is here showing how prototypes are implemented for defining array @Kaiido

      – Black Mamba
      57 mins ago





















    • Hum... nope. That's not what Array.isArray checks. That is a simple polyfill posted on an MDN article, it is in no way how any browser will implement it. Here is what the specs asks though they're not clear as to how the check is made to know if it is an Array exotic Object. And here is a proof that it's not how it is implemented: jsfiddle.net/f6182mkh

      – Kaiido
      1 hour ago











    • I edited my answer I just wanted to show that it all depends on prototypes and not the keys they see in the value. BTW thanks for correcting me. Please edit my answer if you still feel something wrong with my answer. @Kaiido

      – Black Mamba
      1 hour ago











    • Well even the prototype thing is not correct either: jsfiddle.net/vLrgdp86

      – Kaiido
      1 hour ago











    • The above I defined is currently used as a Polyfill in many browsers that doesn't support it. I've searched about how it is currently officially implemented but got no success. It'll be helpful if you can provide me a doc for it. Here's a little detail about the Array.isArray I've been able to find. A official doc is here showing how prototypes are implemented for defining array @Kaiido

      – Black Mamba
      57 mins ago



















    Hum... nope. That's not what Array.isArray checks. That is a simple polyfill posted on an MDN article, it is in no way how any browser will implement it. Here is what the specs asks though they're not clear as to how the check is made to know if it is an Array exotic Object. And here is a proof that it's not how it is implemented: jsfiddle.net/f6182mkh

    – Kaiido
    1 hour ago





    Hum... nope. That's not what Array.isArray checks. That is a simple polyfill posted on an MDN article, it is in no way how any browser will implement it. Here is what the specs asks though they're not clear as to how the check is made to know if it is an Array exotic Object. And here is a proof that it's not how it is implemented: jsfiddle.net/f6182mkh

    – Kaiido
    1 hour ago













    I edited my answer I just wanted to show that it all depends on prototypes and not the keys they see in the value. BTW thanks for correcting me. Please edit my answer if you still feel something wrong with my answer. @Kaiido

    – Black Mamba
    1 hour ago





    I edited my answer I just wanted to show that it all depends on prototypes and not the keys they see in the value. BTW thanks for correcting me. Please edit my answer if you still feel something wrong with my answer. @Kaiido

    – Black Mamba
    1 hour ago













    Well even the prototype thing is not correct either: jsfiddle.net/vLrgdp86

    – Kaiido
    1 hour ago





    Well even the prototype thing is not correct either: jsfiddle.net/vLrgdp86

    – Kaiido
    1 hour ago













    The above I defined is currently used as a Polyfill in many browsers that doesn't support it. I've searched about how it is currently officially implemented but got no success. It'll be helpful if you can provide me a doc for it. Here's a little detail about the Array.isArray I've been able to find. A official doc is here showing how prototypes are implemented for defining array @Kaiido

    – Black Mamba
    57 mins ago







    The above I defined is currently used as a Polyfill in many browsers that doesn't support it. I've searched about how it is currently officially implemented but got no success. It'll be helpful if you can provide me a doc for it. Here's a little detail about the Array.isArray I've been able to find. A official doc is here showing how prototypes are implemented for defining array @Kaiido

    – Black Mamba
    57 mins ago













    1















    Turn an existing Javascript object into an array without creating a new separate array




    This feels like an adapter pattern, for which JS Proxy seems suited.



    Ok, the code to implement this is quite lengthy, and technically we do need a new Array() to meet the requirements of Array.isArray(), but if you have a particularly big object and do not wish to transfer all it's properties to an array, this might fit the bill.






    console.clear()
    let arrProxy = new Proxy(new Array(), {
    get: function(target, property) {
    if (property === 'length') {
    return length;
    }
    if (property in target.data) {
    return target.data[property];
    }
    if (property in Array.prototype) {
    return Array.prototype[property].bind(obj);
    }
    },
    set: function(target, property, value) {
    if (property === 'length') {
    for (var i = value; i < length; i++) {
    delete target[i];
    }
    length = value;
    return;
    }
    target.data[property] = value;
    if (Number(property) >= length) {
    length = Number(property) + 1;
    }
    },
    ownKeys: function(target) { // for getOwnPropertyNames()
    return [...Object.keys(target.data), 'length']
    }
    })

    let arrEmulation = {0:'a', 1:'b', 2:'c'};
    arrProxy.data = arrEmulation

    console.log(Object.getOwnPropertyNames(arrProxy));
    console.log(arrProxy[0]);
    console.log(arrProxy[1]);
    console.log(arrProxy[2]);
    console.log(Array.isArray(arrProxy));







    I should attribute the source - this is adapted from https://gist.github.com/alessioalex/c0562958b112ae7fcccd






    share|improve this answer






























      1















      Turn an existing Javascript object into an array without creating a new separate array




      This feels like an adapter pattern, for which JS Proxy seems suited.



      Ok, the code to implement this is quite lengthy, and technically we do need a new Array() to meet the requirements of Array.isArray(), but if you have a particularly big object and do not wish to transfer all it's properties to an array, this might fit the bill.






      console.clear()
      let arrProxy = new Proxy(new Array(), {
      get: function(target, property) {
      if (property === 'length') {
      return length;
      }
      if (property in target.data) {
      return target.data[property];
      }
      if (property in Array.prototype) {
      return Array.prototype[property].bind(obj);
      }
      },
      set: function(target, property, value) {
      if (property === 'length') {
      for (var i = value; i < length; i++) {
      delete target[i];
      }
      length = value;
      return;
      }
      target.data[property] = value;
      if (Number(property) >= length) {
      length = Number(property) + 1;
      }
      },
      ownKeys: function(target) { // for getOwnPropertyNames()
      return [...Object.keys(target.data), 'length']
      }
      })

      let arrEmulation = {0:'a', 1:'b', 2:'c'};
      arrProxy.data = arrEmulation

      console.log(Object.getOwnPropertyNames(arrProxy));
      console.log(arrProxy[0]);
      console.log(arrProxy[1]);
      console.log(arrProxy[2]);
      console.log(Array.isArray(arrProxy));







      I should attribute the source - this is adapted from https://gist.github.com/alessioalex/c0562958b112ae7fcccd






      share|improve this answer




























        1












        1








        1








        Turn an existing Javascript object into an array without creating a new separate array




        This feels like an adapter pattern, for which JS Proxy seems suited.



        Ok, the code to implement this is quite lengthy, and technically we do need a new Array() to meet the requirements of Array.isArray(), but if you have a particularly big object and do not wish to transfer all it's properties to an array, this might fit the bill.






        console.clear()
        let arrProxy = new Proxy(new Array(), {
        get: function(target, property) {
        if (property === 'length') {
        return length;
        }
        if (property in target.data) {
        return target.data[property];
        }
        if (property in Array.prototype) {
        return Array.prototype[property].bind(obj);
        }
        },
        set: function(target, property, value) {
        if (property === 'length') {
        for (var i = value; i < length; i++) {
        delete target[i];
        }
        length = value;
        return;
        }
        target.data[property] = value;
        if (Number(property) >= length) {
        length = Number(property) + 1;
        }
        },
        ownKeys: function(target) { // for getOwnPropertyNames()
        return [...Object.keys(target.data), 'length']
        }
        })

        let arrEmulation = {0:'a', 1:'b', 2:'c'};
        arrProxy.data = arrEmulation

        console.log(Object.getOwnPropertyNames(arrProxy));
        console.log(arrProxy[0]);
        console.log(arrProxy[1]);
        console.log(arrProxy[2]);
        console.log(Array.isArray(arrProxy));







        I should attribute the source - this is adapted from https://gist.github.com/alessioalex/c0562958b112ae7fcccd






        share|improve this answer
















        Turn an existing Javascript object into an array without creating a new separate array




        This feels like an adapter pattern, for which JS Proxy seems suited.



        Ok, the code to implement this is quite lengthy, and technically we do need a new Array() to meet the requirements of Array.isArray(), but if you have a particularly big object and do not wish to transfer all it's properties to an array, this might fit the bill.






        console.clear()
        let arrProxy = new Proxy(new Array(), {
        get: function(target, property) {
        if (property === 'length') {
        return length;
        }
        if (property in target.data) {
        return target.data[property];
        }
        if (property in Array.prototype) {
        return Array.prototype[property].bind(obj);
        }
        },
        set: function(target, property, value) {
        if (property === 'length') {
        for (var i = value; i < length; i++) {
        delete target[i];
        }
        length = value;
        return;
        }
        target.data[property] = value;
        if (Number(property) >= length) {
        length = Number(property) + 1;
        }
        },
        ownKeys: function(target) { // for getOwnPropertyNames()
        return [...Object.keys(target.data), 'length']
        }
        })

        let arrEmulation = {0:'a', 1:'b', 2:'c'};
        arrProxy.data = arrEmulation

        console.log(Object.getOwnPropertyNames(arrProxy));
        console.log(arrProxy[0]);
        console.log(arrProxy[1]);
        console.log(arrProxy[2]);
        console.log(Array.isArray(arrProxy));







        I should attribute the source - this is adapted from https://gist.github.com/alessioalex/c0562958b112ae7fcccd






        console.clear()
        let arrProxy = new Proxy(new Array(), {
        get: function(target, property) {
        if (property === 'length') {
        return length;
        }
        if (property in target.data) {
        return target.data[property];
        }
        if (property in Array.prototype) {
        return Array.prototype[property].bind(obj);
        }
        },
        set: function(target, property, value) {
        if (property === 'length') {
        for (var i = value; i < length; i++) {
        delete target[i];
        }
        length = value;
        return;
        }
        target.data[property] = value;
        if (Number(property) >= length) {
        length = Number(property) + 1;
        }
        },
        ownKeys: function(target) { // for getOwnPropertyNames()
        return [...Object.keys(target.data), 'length']
        }
        })

        let arrEmulation = {0:'a', 1:'b', 2:'c'};
        arrProxy.data = arrEmulation

        console.log(Object.getOwnPropertyNames(arrProxy));
        console.log(arrProxy[0]);
        console.log(arrProxy[1]);
        console.log(arrProxy[2]);
        console.log(Array.isArray(arrProxy));





        console.clear()
        let arrProxy = new Proxy(new Array(), {
        get: function(target, property) {
        if (property === 'length') {
        return length;
        }
        if (property in target.data) {
        return target.data[property];
        }
        if (property in Array.prototype) {
        return Array.prototype[property].bind(obj);
        }
        },
        set: function(target, property, value) {
        if (property === 'length') {
        for (var i = value; i < length; i++) {
        delete target[i];
        }
        length = value;
        return;
        }
        target.data[property] = value;
        if (Number(property) >= length) {
        length = Number(property) + 1;
        }
        },
        ownKeys: function(target) { // for getOwnPropertyNames()
        return [...Object.keys(target.data), 'length']
        }
        })

        let arrEmulation = {0:'a', 1:'b', 2:'c'};
        arrProxy.data = arrEmulation

        console.log(Object.getOwnPropertyNames(arrProxy));
        console.log(arrProxy[0]);
        console.log(arrProxy[1]);
        console.log(arrProxy[2]);
        console.log(Array.isArray(arrProxy));






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 25 mins ago

























        answered 32 mins ago









        eric99eric99

        359310




        359310























            0














            You can convert anything that is close enough to an array by using Array.from().
            In your example, we could just call:



            const arrEmulation = {0:0, 1:1, 2:2, 3:3, 4:4, 5:5, length: 6};

            const newArray = Array.from(arrEmulation) // [0, 1, 2, 3, 4, 5]
            Array.isArray(newArray) // true





            share|improve this answer



















            • 1





              I'm not looking at how to convert object to array, but to understand they differences...

              – SmaGal
              2 hours ago






            • 1





              @SmaGal, be fair - do you not say 'convert' in the question title?

              – eric99
              2 hours ago











            • @eric99 the down-vote don't come from me. I just explained that I was not looking for that.

              – SmaGal
              1 hour ago











            • @SmaGal my comment was a bit tongue-in-cheek. TioZed deserves some credit for his answer, given the question has now morphed into something more specific.

              – eric99
              1 hour ago
















            0














            You can convert anything that is close enough to an array by using Array.from().
            In your example, we could just call:



            const arrEmulation = {0:0, 1:1, 2:2, 3:3, 4:4, 5:5, length: 6};

            const newArray = Array.from(arrEmulation) // [0, 1, 2, 3, 4, 5]
            Array.isArray(newArray) // true





            share|improve this answer



















            • 1





              I'm not looking at how to convert object to array, but to understand they differences...

              – SmaGal
              2 hours ago






            • 1





              @SmaGal, be fair - do you not say 'convert' in the question title?

              – eric99
              2 hours ago











            • @eric99 the down-vote don't come from me. I just explained that I was not looking for that.

              – SmaGal
              1 hour ago











            • @SmaGal my comment was a bit tongue-in-cheek. TioZed deserves some credit for his answer, given the question has now morphed into something more specific.

              – eric99
              1 hour ago














            0












            0








            0







            You can convert anything that is close enough to an array by using Array.from().
            In your example, we could just call:



            const arrEmulation = {0:0, 1:1, 2:2, 3:3, 4:4, 5:5, length: 6};

            const newArray = Array.from(arrEmulation) // [0, 1, 2, 3, 4, 5]
            Array.isArray(newArray) // true





            share|improve this answer













            You can convert anything that is close enough to an array by using Array.from().
            In your example, we could just call:



            const arrEmulation = {0:0, 1:1, 2:2, 3:3, 4:4, 5:5, length: 6};

            const newArray = Array.from(arrEmulation) // [0, 1, 2, 3, 4, 5]
            Array.isArray(newArray) // true






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 3 hours ago









            Tio ZedTio Zed

            404




            404








            • 1





              I'm not looking at how to convert object to array, but to understand they differences...

              – SmaGal
              2 hours ago






            • 1





              @SmaGal, be fair - do you not say 'convert' in the question title?

              – eric99
              2 hours ago











            • @eric99 the down-vote don't come from me. I just explained that I was not looking for that.

              – SmaGal
              1 hour ago











            • @SmaGal my comment was a bit tongue-in-cheek. TioZed deserves some credit for his answer, given the question has now morphed into something more specific.

              – eric99
              1 hour ago














            • 1





              I'm not looking at how to convert object to array, but to understand they differences...

              – SmaGal
              2 hours ago






            • 1





              @SmaGal, be fair - do you not say 'convert' in the question title?

              – eric99
              2 hours ago











            • @eric99 the down-vote don't come from me. I just explained that I was not looking for that.

              – SmaGal
              1 hour ago











            • @SmaGal my comment was a bit tongue-in-cheek. TioZed deserves some credit for his answer, given the question has now morphed into something more specific.

              – eric99
              1 hour ago








            1




            1





            I'm not looking at how to convert object to array, but to understand they differences...

            – SmaGal
            2 hours ago





            I'm not looking at how to convert object to array, but to understand they differences...

            – SmaGal
            2 hours ago




            1




            1





            @SmaGal, be fair - do you not say 'convert' in the question title?

            – eric99
            2 hours ago





            @SmaGal, be fair - do you not say 'convert' in the question title?

            – eric99
            2 hours ago













            @eric99 the down-vote don't come from me. I just explained that I was not looking for that.

            – SmaGal
            1 hour ago





            @eric99 the down-vote don't come from me. I just explained that I was not looking for that.

            – SmaGal
            1 hour ago













            @SmaGal my comment was a bit tongue-in-cheek. TioZed deserves some credit for his answer, given the question has now morphed into something more specific.

            – eric99
            1 hour ago





            @SmaGal my comment was a bit tongue-in-cheek. TioZed deserves some credit for his answer, given the question has now morphed into something more specific.

            – eric99
            1 hour ago










            SmaGal is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded


















            SmaGal is a new contributor. Be nice, and check out our Code of Conduct.













            SmaGal is a new contributor. Be nice, and check out our Code of Conduct.












            SmaGal is a new contributor. Be nice, and check out our Code of Conduct.
















            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54527480%2fis-there-any-way-to-turn-an-existing-javascript-object-into-an-array-without-cre%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Knooppunt Holsloot

            Altaar (religie)

            Gregoriusmis