Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как опознать RegExp. (https://javascript.ru/forum/misc/4224-kak-opoznat-regexp.html)

Kolyaj 03.07.2009 14:06

Как опознать RegExp.
 
Что-то затишье на форуме, нужно подразбавить.

Вопрос: Как в JavaScript опознать объект типа RegExp? Т.е. нужна функция isRegExp.

Я знаю только один надежный вариант, может узнаю еще парочку :)

Octane 03.07.2009 14:17

alert(Object.prototype.toString.call(/./) == "[object RegExp]");

Riim 03.07.2009 14:17

1. instanceof
2. constructor
3. наличие методов которые есть только у RegExp

Riim 03.07.2009 14:20

Цитата:

Сообщение от Octane
alert(Object.prototype.toString.call(/./) == "[object RegExp]");

Последняя версия PrototypeJs таким же способом определяет оперу:
var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';


Видно просто !!window.opera уже не модно.

Kolyaj 03.07.2009 14:27

Octane,
ну хоть бы дал подумать :)

Цитата:

Сообщение от Riim
1. instanceof
2. constructor
3. наличие методов которые есть только у RegExp

Все плохо и не во всех случаях работает.

Цитата:

Сообщение от Riim
Видно просто !!window.opera уже не модно.

!!window.opera не защищено от var opera = true;

Riim 03.07.2009 14:36

Цитата:

Сообщение от Kolyaj
Все плохо и не во всех случаях работает.

Цитата:

Сообщение от Kolyaj
!!window.opera не защищено от var opera = true;

Я где то читал обсуждение правильного способа определения массива. Так там, в конечном счете, лучшим признали вариант, состоящий примерно из !50! строк кода (представьте, если какой-нибудь, PrototypeJs например, так написать). Каких только проверок на дурака там не было (в конечном счете, все равно можно было обмануть). И оно надо? Если я точно знаю все минусы instanceof, то почему мне его не применять там, где эти минусы не проявляются?

Kolyaj 03.07.2009 14:46

Цитата:

Сообщение от Riim
в конечном счете, все равно можно было обмануть

function isArray(obj) {
    return Object.prototype.toString.call(obj) == '[object Array]';
}

Это не обмануть.

Riim 03.07.2009 14:49

Цитата:

Сообщение от Kolyaj
Это не обмануть.

Легко:
function isArray(obj) {
    return Object.prototype.toString.call(obj) == '[object Array]';
}
Object.prototype.toString = function() {return ''};
var a = [];
alert(isArray(a));

Kolyaj 03.07.2009 15:05

Поправлюсь: не обмануть псевдо-массивом. А после финта
Цитата:

Сообщение от Riim
Object.prototype.toString = function() {return ''};

что угодно может сломаться в самых неожиданных местах.

Riim 03.07.2009 15:36

Цитата:

Сообщение от Kolyaj
А после финта

Цитата:

Сообщение от Kolyaj
что угодно может сломаться в самых неожиданных местах.

Только в том случае если Object#toString применять для подобных целей. И если так делать, то нужно брать на себя обязательства: не применять этот финт (а необходимость в нем вполне может возникнуть). В случае с определением массива по свойствам/методам, программист берет на себя обязательства следить за тем, что бы у других объектов не появился весь проверяемый набор свойств/методов. Так чем эти способы принципиально отличаются?

Kolyaj 03.07.2009 15:42

А вы уверены, что Object.prototype.toString не используется нигде в нативных объектах/функциях? Просто таким финтом вы не обманули какую-то конкретную функцию, а потенциально сломали все. Сломать и обмануть -- разные вещи. Проще было написать
var isArray = function() { return false; };

Riim 03.07.2009 15:46

Цитата:

Сообщение от Kolyaj
А вы уверены, что Object.prototype.toString не используется нигде в нативных объектах/функциях?

А что используется?

Dmitry A. Soshnikov 03.07.2009 16:11

Цитата:

Сообщение от Kolyaj
Это не обмануть.

формально, [[Class]] host-объектов может быть и "RegExp", в таком случае - обмануть, практически же - не знаю, какая из реализаций такое может сделать, но стандарт не запрещает.

Octane 03.07.2009 16:12

Riim, твой пример равносилен следующему:
Object = null;
alert(Object);

Все в пределах разумного же должно быть. Вот пример c opera, ведь никто не застрахован от того, что его скрипт не подключется после того, как в глобальном пространстве имен будет создана переменная opera? А если еще вспомнить, что IE добавляет глобальные ссылки на DOM-элементы по именам идентификаторов…

Цитата:

Сообщение от Kolyaj
ну хоть бы дал подумать

:D ладно в следующий раз не буду спешить)

Dmitry A. Soshnikov 03.07.2009 16:14

Цитата:

Сообщение от Kolyaj
ну хоть бы дал подумать

какой тут подумать, тут чисто - получить соответсвующую инфу (либо знаешь, либо не знаешь), вопрос не "на подумать" ;)

Kolyaj 03.07.2009 16:21

Dmitry A. Soshnikov,
я ж специально не isArray выбрал :). На regexp'ы в фреймворках проверки обычно нет. Так что тут задача была скорее в проведении аналогии. С чем, к сожалению, у многих проблемы.

Riim 03.07.2009 16:24

Я так и не понял, почему заменять методы в prototype конструкторов - плохо. Вроде это стандартная практика.

Dmitry A. Soshnikov 03.07.2009 16:26

Kolyaj, да какая разница "Array" или "RegExp"; по стандарту, host-объекты могут иметь в качестве [[Class]] любое значение, включая, используемые стандартными объектами ECMA (я, кстати, подправил коммент, где "Array" написал).

Dmitry A. Soshnikov 03.07.2009 16:28

Цитата:

Сообщение от Riim
Я так и не понял, почему заменять методы в prototype конструкторов - плохо. Вроде это стандартная практика.

Пока нельзя выставлять {DontEnum} свойствам, плохо (с практической точки зрения) добавлять свойства в Object.prototype, в остальных случаях - если идеология позволяет - почему нет?

Riim 03.07.2009 16:35

Цитата:

Сообщение от Dmitry A. Soshnikov
добавлять свойства в Object.prototype

Да, кстати даже при замене (не добавлении) в for-in попадает.

Kolyaj 03.07.2009 16:36

Dmitry A. Soshnikov,
я прекрасно знаю, что для тебя это все очевидно, задача-то и не для тебя была :)

Цитата:

Сообщение от Riim
Я так и не понял, почему заменять методы в prototype конструкторов - плохо.

Да нормально, просто приведенный пример обмана функции некорректен.

Riim 03.07.2009 16:45

Цитата:

Сообщение от Kolyaj
приведенный пример обмана функции некорректен.

Да, есть что-то такое.

Все же я не понимаю, чем instanceof не устраивает? Да есть некоторые моменты, которые нужно принимать во внимание, но если их знать, то все отлично работает. К тому же это самый быстрый способ (в 99.9% случаев за исключением как раз тех самых моментов) и самое главное: он не заставляет брать на себя какие либо обязательства.

Kolyaj 03.07.2009 16:48

Цитата:

Сообщение от Riim
Все же я не понимаю, чем instanceof не устраивает?

Приход объекта из другого окна/фрейма -- это не некоторый момент, а вполне реальная ситуация.

Riim 03.07.2009 16:52

Цитата:

Сообщение от Kolyaj
Приход объекта из другого окна/фрейма -- это не некоторый момент, а вполне реальная ситуация

Так ее же совсем не сложно учитывать.

x-yuri 04.07.2009 01:36

Цитата:

Сообщение от Dmitry A. Soshnikov
Пока нельзя выставлять {DontEnum} свойствам, плохо (с практической точки зрения) добавлять свойства в Object.prototype, в остальных случаях - если идеология позволяет - почему нет?

в принципе, добавлять в Array.prototype тоже не стоит

Цитата:

Сообщение от Riim
Так ее же совсем не сложно учитывать.

как? не пользоваться этой функцией для внешних объектов?

Цитата:

Все же я не понимаю, чем instanceof не устраивает?
еще этот момент актуален при написании public-фреймворков

Riim 04.07.2009 01:41

Цитата:

Сообщение от x-yuri
как? не пользоваться этой функцией для внешних объектов?

Вручную.


Часовой пояс GMT +3, время: 13:10.