问题
I have gone through some materials and haven't completely grasped the concept when it comes to syntax such as the following :
var arrObj = [1,2,3];
Object.prototype.toString.call(arrObj); //Gives "[object Array]"
arrObj.toString(); // Gives "1,2,3"
How are the lines 2 and 3 different? As far as I understood, both call the toString method with current object being set to 'arrObj'.
回答1:
Since toString
is defined in Object.prototype
, whoever inherits Object
, will by default get the toString
method.
But, Array
objects, override the default toString
method to print the array elements as comma separated string.
Object.prototype.toString
doesn't know what type of Object it actually deals with. So, it is intentionally kept generic and it always prints the actual type of the Object. That is why
console.log(Object.prototype.toString.call(arrObj));
prints
[object Array]
which is the type of object passed. But, when you do arrObj.toString
, you are trying to represent the array in its String form, so toString
is overriden in Array
objects to print the array elements as comma separated string.
That is why both the calls are different.
But in case of other objects, the toString
is not overriden, so they will use the toString
from the Object.prototype.toString
. For example,
var obj = {
1: 2
};
console.log(obj.toString());
// [object Object]
Read the MDN's example of Overriding the default toString method
回答2:
toString
is overridden for Arrays; and
Object.prototype.toString
is different than Array.prototype.toString
.
To get the same result with the call
, use it on the 'correct' method:
Array.prototype.toString.call(arrObj); // Gives "1,2,3"
回答3:
These .call()
methods are hacky ways to treat one type as another. For example, NodeLists, as Arrays with Array.prototype.forEach
. When you call it as an Object it will "convert it" into an Object string
Array.prototype.toString.call(arrObj);
Works perfectly. Object.toString()
is treating kind of weirdly. Imagine the compiler doing something like:
[1, 2, 3] -> { 0: 1, 1: 2, 2: 3 }
That will return [Object object]
. JavaScript, unlike other languages, will always find a way out when they're type issues.
If you are writing a function, you could do something like:
function myFunction (input) {
window[input.constructor.name].prototype.toString.call(input);
}
来源:https://stackoverflow.com/questions/30010996/difference-between-object-prototype-tostring-callarrayobj-and-arrayobj-tostrin