#javascript #instanceof
#javascript #instanceof
Вопрос:
Я поиграл с instanceof
в Chrome, но получил сообщение об ошибке. Я думаю, что знаю почему (вы должны указать функцию после instanceof
ключевого слова, которое является конструктором, с помощью которого был создан объект), но в сообщении об ошибке, похоже, указано что-то еще:
[1,2,3] instanceof Array
// true
[1,2,3] instanceof []
// TypeError: Expecting a function in instanceof check, but got 1,2,3
Означает ли это, что я должен заменить [1,2,3]
функцией? Я бы подумал, что это [1,2,3]
правильно, и в этом []
заключается проблема, и ее следует заменить функцией, но, похоже, сообщение об ошибке говорит об обратном.
Не мог бы кто-нибудь, пожалуйста, объяснить, как я неправильно интерпретирую сообщение об ошибке?
Ответ №1:
Объекты являются экземплярами функции-конструктора, поэтому тест заключается в том, чтобы увидеть, является ли левая рука экземпляром правой, поэтому правой должна быть функция (и это должен быть конструктор, который сконструировал объект для возврата true
).
[1,2,3] instanceof [].constructor; // true
Итак, чтобы ответить на вопрос более прямо, ваше первоначальное понимание правильное, и сообщение об ошибке кажется вводящим в заблуждение (по крайней мере, для меня).
Из спецификации:http://ecma262-5.com/ELS5_HTML.htm#Section_11.8.6
1.8.6 Оператор instanceof
Производственное выражение отношения: экземпляр выражения отношения ShiftExpression вычисляется следующим образом:
- Пусть lref будет результатом вычисления RelationalExpression .
- Пусть lvalбудет GetValue(lref).
- Пусть rref будет результатом вычисления ShiftExpression.
- Пусть rval будет GetValue(rref) .
- Если Type (rval) не является Object, создайте исключение TypeError.
- Если у rval нет внутреннего метода [[hasInstance]], создайте исключение TypeError.
- Возвращает результат вызова [[hasInstance]] внутреннего метода rval с аргументом lval.
и http://ecma262-5.com/ELS5_HTML.htm#Section_15.3.5
15.3.5 Свойства экземпляров функции
В дополнение к требуемым внутренним свойствам, каждый экземпляр функции имеет внутреннее свойство [[Call]] и в большинстве случаев использует другую версию внутреннего свойства [[Get]]. В зависимости от способа их создания (см. 8.6.2 , 13.2, 15 и 15.3.4.5) экземпляры функций могут иметь внутреннее свойство [[hasInstance]], внутреннее свойство [[Scope]], внутреннее свойство [[Construct]], внутреннее свойство[[FormalParameters]], внутреннее свойство[[Code]], внутреннее свойство[[TargetFunction]], внутреннее свойство [[BoundThis]] и внутреннее свойство [[BoundArgs ]] внутреннее свойство.
Таким образом, для этого требуется, TypeError
если правая рука не имеет внутреннего [[HasInstance]]
свойства, но не указывает формулировку.
Firefox 4 выдает мне гораздо более разумное сообщение об ошибке:
[1,2,3] instanceof [];
// TypeError: invalid 'instanceof' operand []
Комментарии:
1. Ах, хорошо, итак, сообщение об ошибке, в котором говорится, что оно ожидает функцию вместо того, что помещено слева, на самом деле не очень хорошо сформулировано, это правильно?
2. @pimvdb: Да, я не понимаю, почему это сформулировано таким образом.
3. «должно быть, это конструктор, который сконструировал объект для возврата true» Не совсем верно. Оператор instanceof проверяет, наследуется ли левый операнд от свойства prototype правого операнда. Итак, если объект создается конструктором, и этот конструктор ссылается на тот же объект в своем свойстве prototype, что и другой конструктор, instanceof вернет true, если этот объект протестирован против обоих:
var obj={x:1};var class_one=function(){};class_one.prototype=obj;var class_two=function(){};class_two.prototype = obj;var inst = new class_one;inst instanceof class_two;