What's the purpose of Javascript's Array Method valueOf? - javascript

I may get hammered for asking something overly vague, so please interpret this as a meta-programming question, as it is meant to be, and not as some sort of indirect flame war.
In trying to understand Javascript's Array a bit deeper, I ran across this W3 reference for Array.valueOf.
It simply says:
The valueOf() method returns the array.
This method is the default method of the array object. Array.valueOf() will return the same as Array
Note: This method will not change the original array.
So, I ask: what's the point? Is there a reason to ever use the Array.valueOf() method? Is it useful in some more complicated constructs, such as when using call or apply? Does it help in piping together functions? Is this simply because it creates a standard method, compared to other objects where the associated valueOf is more useful, and therefore help to generalize Array to other objects?
As far as I can tell, it is exactly identical, so I don't see its value.

This method is inherited from Object.prototype; every object that descends from Object.prototype has it. Primitive wrappers override it to return the corresponding primitive, for example, converting new Number(5) to 5. The default implementation returns the object unchanged.
JavaScript calls the valueOf method to convert an object to a primitive value. You rarely need to invoke the valueOf method yourself; JavaScript automatically invokes it when encountering an object where a primitive value is expected.

Related

How to reliably detect exotic objects in JavaScript?

Is there any way to reliably whether a JavaScript object is an exotic object type, and if so what its type is?
By "exotic", I mean (for the purposes of this question) anything which is could not be created using Object.create. This includes everything the ES2016 spec defines as exotic (any "object that does not have the default behaviour for one or more of the essential internal methods") plus anything created by the ObjectCreate specification method with a non-empty internalSlotsList, plus any kind of host object.
By "reliable", I mean not subject to being tricked by adding / removing properties from the object, using Object.create or Object.setPrototypeOf to give the object an unexpected prototype, modifying the object's ##toStringTag, or a constructor's ##hasInstance. This is important for library functions that need to correctly handle arbitrary user data.
(This means, in particular, that instanceof and Object.prototype.isPrototypeOf() are not useful. For example: var a = Object.create(Array.prototype) makes a something that looks and smells like an array—a instanceof Array === true and a.push and a.pop work as expected—but lacks the magic behaviour .length and is easily shown not to be an actual array exotic: Array.isArray(a) === false.)
By "type", I mean roughly what the ECMAScript 5.1 language specification referred to as [[Class]] - i.e., that quality that separates an Array instance, with its special [[DefineOwnProperty]] behaviour, from an ordinary Object.
Examples
Some cases are pretty easy:
Array exotic objects can be reliably detected using Array.isArray(a).
Functions can be reliably detected using typeof f === 'function'.
But is there any way to detect if a function is a bound function, native function or closure?
Some other exotic objects can be reliably detected by careful application of methods from their prototype object, e.g.
Sets can be detected by calling Set.prototype.has.apply(s, undefined), and seeing whether it throws a TypeError or not.
Is there any general way to make such a detection?
In particular:
Is there any general way to determine whether an object is plain or exotic?
Is there any general way to determine the type of an exotic object?
I note that Object.toString.apply(o) used to work reasonably well for this purpose: although in many browsers it would lie about the type of host objects, for all the types defined in the ES 5.1 spec it could be counted on to reliably tell you whether the object was a plain [object Object] or an exotic [object <Type>]. In ES6 and later, however, modifying ##toStringTag will subvert this test.
A means of detection which works in any conformant JS implementation would be ideal, but a means that is specific to Node.js would still be useful.
But is there any way to detect if a function is a bound function, native function or closure?
No. They are all plain and simple functions.
Some other exotic objects can be reliably detected by careful application of methods from their prototype object, e.g.
Sets can be detected by calling Set.prototype.has.apply(s, undefined), and seeing whether it throws a TypeError or not.
You can use the instanceof operator to test if an object is an instance of a particular function constructor (or something up its prototype chain).
var mySet = new Set();
console.log(mySet instanceof Set);

In JavaScript if "Function" descends from "Object", then how was keyword function made available while defining the constructor of object?

I was recently reading some tutorials of JavaScript, and every article states that Functions descend from Objects.
The above statements leads to an understanding that Objects were created before Functions were available.
If it is so, then how can constructor of an Object be a function (As per my understanding object Function hasn't been created yet)?
Please help me out with this confusion.
Functions Descend from Objects
In JavaScript functions are basically objects.
They are what is called first class objects - meaning they can do anything that an object can and are basically interchangeable.
Therefore all properties and methods available on the object level are also available on the function level.
You might want to read this
How can constructor of an Object be a function
The short answer is that you are trying to understand something that is irrelevant to understand in order for you to use the Javascript language for coding.
The longer answer is that you must distinguish between built-in objects:
Object
Function
Array
and the objects you create yourself as part of your code.
The built-in objects are part of the Javascript language and are simply available to you out-of-the-box. Your question relates to the internal workings of the language as you are inquiring about how the built-in Object is constructed. This has little value to understand unless you are looking to become part of the team developing the Javascript language.
The objects you create yourself as part of your code is almost always linked to other objects via the objects internal [[Prototype]] property. So if you for example do:
var x = {"foo": "bar"};
you have now created your own object with the property foo and the value bar. You can then do:
console.log(x.hasOwnProperty("foo")); //true
even though x does not have a method called .hasOwnProperty() directly on it. The reason the above code works is, that x is linked to the built-in Object.prototype via x's internal [[Prototype]] property and via this link delegates to Object.prototype.hasOwnProperty(). So all the objects you create as part of your code has access to use the methods on Object.prototype.

When and what are the advantages of creating a javascript array-like object? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Array-like object in javascript
Javascript has native objects that are array-like objects (eg. arguments, NodeList).
I would like to know:
What are the advantages of creating an array-like object?
When should be a good idea to create an array-like object (rather than create a regular array object)?
You're looking at it from the wrong side: the early versions of Java(Live)Script didn't have arrays, only objects. An array, in fact, is an augmented objects (indeces are converted to strings internally!). So an Array is an Object, like arguments is an object... there are some overlaps, some differences...
To answer your question: you can never really make an arguments object, that's just inherent to functions and you should treat them as read-only objects.
NodeLists are objects, returned by stuff like document.getElementsByTagName('a');, the advantage of them is that (except for IE, of course) they come with a couple of neat methods:
var inputs = document.getElementsByTagName('input');
var userNameIn = inputs.namedItem('username');//Arrays don't have this
So when should you use what? Well, dealing with nodes: 9 times out of 10 you're best served with a nodes list, arguments objects are what you need inside functions. Since JS is a functional language, you need them a lot. That said, it really doesn't matter that much: chances are you've come across code like this:
var myArgs = Array.prototype.slice.apply(arguments,[0]);
This just borrows the slice method from the Array prototype and calls it as if it were a method of the arguments object.That's all there is to say, really. There is no definitive answer here, just that old mantra: go with your gut feeling. Try, fail, learn and try again.
Just know that, whatever you do, you can borrow prototype (or even instance) methods, and that everything traces back to the mother Object.prototype prototype.

JSON.parse, JS typecasting, and revivers

Sorry if this is a stupid question, this is my first JS project...
I'm trying to deserialize a custom object in JS using JSON. The problem is, JSON.parse() does not return the object as its original type. Since directly casting the returned object to the desired type doesn't seem possible, that leaves me with the 'reviver' option...
Am I missing something here? Wasn't the entire point of JSON to avoid having to write custom methods to serialize and deserialize objects? What's the point of using JSON if I have to write my own method 'revive' my object?
JSON is a format for raw data. It's very primitive. It supports dictionaries (aka. javascript objects, hashes, associative arrays), arrays, strings, numbers, booleans and null. That's it. The reason it doesn't do more is that those primitives are language agnostic, and nearly all programming language have built in tools to handle those types of data.
If you had other notation like "class" then suddenly it becomes very bound to specific languages or codeboases, and lose it's wide and generic applicability.
So think of JSON as simple raw data. JSON is not instance marshalling or complete object serialization. So yes you need to write "revivers" if you intend to serialize JS objects instantiated from constructors.
This is the approach things like backbone.js take:
new Book({
title: "One Thousand and One Nights",
author: "Scheherazade"
});
You simply pass your plain object of data (the result of your JSON.parse()) to the call to your constructor of choice. From there you can do any number of things to read it's values into your new object.
Javascript has no standard way of Marshalling whole objects like you can in ruby with Marhsal.dump(obj) for instance.
EDIT: One last major point...
Javascript objects don't have a "type" as you would think of it in other languages. A Javascript object is simply a a dictionary of key/value pairs. When you do something like new SomeClass() you get a new object, that has a special prototype property that points to the prototype property of the SomeClass function object. Wether an object is an instance of SomeClass is less of a clear cut question than you may think at first glance.
Instead you may ask "What is my constructor function object?" or "What objects are in my prototype chain?"
So if you wanted to convey "type" in JSON, which is stored as a string, then how would you store a reference to a prototype object? Maybe the prototype object is not named in the global scope at all, and only available via closure? Then when you write that out to string, you have no way of referencing that prototype object anymore at all.
The point is that javascripts prototypical approach to object instantiation, combined with it's closure based lexical scoping and the fact that objects hold their values more like C pointers than literal values, makes it very very hard to fully serialize an object out to a location external to the VM.

Why isn't a function's arguments object an array in Javascript?

Since it seems like the first thing people do is convert arguments into a real array, I'm interested in why the Javascript language authors and implementers decided, and continue to think, that arguments should not be a real Array. I don't mean this as flamebait, I'm sincerely interested in the thinking behind it. Since the function is naturally being called when you're in its body, I don't think it's because the objects arguments are referencing can change, like with some of the DOM results...
My conjecture:
The concept of the arguments object has been on the language since the very beginning, it's even described in the ECMAScript First Edition Standard(PDF).
In that version of ECMAScript, the Array.prototype was really basic, array objects contained only 4 methods!: toString, join, reverse and sort.
I think that's one of the major reasons about they make arguments to inherit from Object.prototype, at that time those Array methods didn't look too useful.
But the Array.prototype object was extended in the next versions of the standard, now on ES5, Array objects have methods such as map, reduce, every, some, etc, that are really powerful.
The last year, there was a proposal in ES5 to make arguments inherit from Array.prototype, in the draft stages of the standard, but was dropped off time later.
In those drafts, arguments inherited from Array.prototype, but for backwards compatibility with ES3, the arguments object had defined two own properties, toString and toLocaleString, both pointing to the same methods on Object.prototype, but finally, the committee decided to keep inheriting from Object.prototype.
The arguments object has the very unusual feature that its array-like elements are synonyms for the local variables that hold the function arguments. For example:
function f(x) {
console.log(arguments[0]); // Displays the initial value of the argument x
x = 5; // Changes the value of the local variable x
console.log(arguments[0]); // Now displays 5
}
I always had the impression that this "magical behaviour" is the reason why arguments is not an array.
It's important to note that without one of the designers present, we can only really conjecture why. But we can come up with some decent reasons... here's mine:
From the perspective of a function, one reason could be because you can't - obviously - actually change the arguments that were passed into you. You could change an array that represents the arguments passed into you, but the arguments as they were passed is set in stone before you ever receive execution scope.
You can splice, dice and pop arrays, and if you did that to the arguments object then you just ruined what is conceptually an immutable structure (sad face!). The design of the real arguments object is closer to a kind of immutability JavaScript can offer.
It is similar to querystring parameters. You get a collection handed to you by the client sending the request. It's part of the request information, which is already set and done.
arguments doesn't just return the arguments. It returns callee object, and the array of arguments. If it were just an array, the first element might be the callee object and be more confusing.

Categories