В первом случае user.toString
вызывается неявно, потому что alert
ожидает строку, а user
не является строкой. Когда вызывается user.toString()
и возвращаемое значение не является строкой, выдается ошибка.
Во втором случае user.toString
вызывается явно вами, не имеет значения, если его имя toString
или нет, потому что он возвращает внутренний объект, как и любой другой метод (здесь не ожидается примитивного значения). Затем внутренний объект передается в alert
, и его toString
вызывается неявно, что возвращает строку, потому что она не переопределена. Второй случай для ясности можно разбить на две части:
let obj = user.toString(); // first user.toString gets called, it will return the inner object
alert(obj); // obj.toString will implicitly gets called and since that will return a string everthing will be fine
Если внутренний объект имеет toString
, который возвращает объект, то второй случай тоже не будет работать:
let user = {
name: "John",
money: 1000,
toString() {
return {
name: 'Bong',
toString() { // toString of the inner object is overridden
return {}; // ... and it returns an object
}
};
}
};
alert(user.toString()); // now even the second case won't work because when toString of the inner object is called, a string is expected, but instead an object is returned which is a no no