Зачем использовать toString() для проверки типов аргументов, которые можно проверить с помощью typeof?

Я понимаю, почему вам нужно использовать Object.prototype.toString() или String() для проверки типов массивов, но это не typeof достаточно для проверки типов функций и строк? Например, полифилл на MDN для Array.isArray использует:

Object.prototype.toString.call(arg) == '[object Array]';

Это довольно ясно в случае массивов, потому что вы не можете использовать typeof для проверки массивов. Валентина использует instanceof для этого:

ar instanceof Array

Но для строк/функций/логических значений/чисел почему бы не использовать typeof?

jQuery и Underscore используют что-то вроде этого для проверки функций:

Object.prototype.toString.call(obj) == '[object Function]';

Разве это не эквивалентно этому?

typeof obj === 'function'

или даже это?

obj instanceof Function

person ryanve    schedule 01.03.2012    source источник


Ответы (2)


Хорошо, кажется, я понял, почему вы видите использование toString. Учти это:

var toString = Object.prototype.toString;
var strLit = 'example';
var strStr = String('example')​;
var strObj = new String('example');

console.log(typeof strLit); // string    
console.log(typeof strStr); // string
console.log(typeof strObj); // object

console.log(strLit instanceof String); // false
console.log(strStr instanceof String); // false
console.log(strObj instanceof String); // true

console.log(toString.call(strLit)); // [object String]
console.log(toString.call(strStr)); // [object String]
console.log(toString.call(strObj)); // [object String]

person ryanve    schedule 18.05.2012
comment
Обратите внимание, что это не работает с промисами, по крайней мере, в Chrome в Firefox. typeof mypromise === 'object, toString.call(mypromise) === '[Object]', но mypromise instanceof Promise === true - person Hurelu; 29.05.2015
comment
@Hurelu Это имеет смысл, потому что Promise наследуется от Object. Я получаю "[object Object]", используя .call, но если вы делаете promise.toString, это дает "[object Promise]". См. stackoverflow.com/q/27746304/770127. - person ryanve; 31.05.2018

Первая причина, о которой я могу думать, заключается в том, что typeof null возвращает object, что обычно не то, что вам нужно (поскольку null — это не объект, а самостоятельный тип).

Однако Object.prototype.toString.call(null) возвращает [object Null].

Но, как вы предполагаете, если вы ожидаете, что что-то будет строкой или другим типом, который хорошо работает с typeof, я не вижу причин, по которым вы не можете использовать typeof (и я регулярно использую typeof в этом случае).

Другая причина, по которой библиотеки, такие как те, которые вы упомянули, используют выбранный ими метод, может быть просто для согласованности. Вы можете использовать typeof для проверки Array, поэтому используйте другой метод и придерживайтесь его во всем.

Для получения дополнительной информации У Ангуса Кролла есть отличная статья о оператор typeof.

person James Allardice    schedule 01.03.2012
comment
Я говорю о проверке вещей, которые, казалось бы, должны работать без сучка и задоринки, таких как строки/функции/логические значения/числа. - person ryanve; 01.03.2012
comment
Обратите внимание, что это не работает с промисами, по крайней мере, в Chrome в Firefox. typeof mypromise === 'object, toString.call(mypromise) === '[Object]', но mypromise instanceof Promise === true - person Hurelu; 29.05.2015
comment
@Hurelu - в последней стабильной версии Chrome я получаю "[object Promise]" за Object.prototype.toString.call(mypromise) - person James Allardice; 29.05.2015
comment
Забавный. Только что обновился до Chrome 43.0.2357.81, и я все еще получаю [object Object]. Проверял только через консоль. Я также снова проверил в Firefox, и теперь [object Promise] отображается правильно. Из-за этих неоднозначных результатов я бы все же предостерег от этого метода надежного обнаружения обещаний. - person Hurelu; 29.05.2015