JavaScript для вызова typeof


Следующий код представляет собой JavaScript-функцию для вызова typeof. Мы здесь не для обсуждения конвенций кодирования или Ли или не расширяя собственный объект, как я-это кошерно или нет. Я хочу знать, в каких случаях это не удается правильно установить объект и, надеюсь, пути его коррекции. Или это достаточно для 99% случаев?

Также, если вы придумать способ, чтобы сделать это меньше, сохраняя при этом информацию нетронутым, я был бы рад услышать, что хорошо.

"use strict"
var FN = Function, 
    g = FN('return this')(); //jslint safe 'global' reference

Object.typeOf = (function (g) {
    return function (o) {
        var n = null,
            r = false,
            nodeType = {
                1:'element_node',
                2:'attribute_node',
                3:'text_node',
                4:'cdata_section_node',
                5:'entity_reference_node',
                6:'entity_node',
                7:'processing_instrction_node',
                8:'comment_node',
                9:'document_node',
                10:'document_type_node',
                11:'document_fragment_node1',
                12:'notation_node'
            },
            u;

        /*********
         *  Following if statements are direct comparisons
         *  because any additional checks on o if it equals
         *  either of these results in an error. So we check
         *  these first prior to proceeding.
         *********/

        if (o === u) {
            return 'undefined';
        }

        if (o === n) {
            return 'null';
        }

        /*********
         *  If we made it this far, just return the set the
         *  r variable and return at the end;
         *********/

        switch (o) {
        case g:
            r = 'global';
            break;
        case g.document:
            r = 'htmldocument';
            break;
        default:
            break;
        }

        /*********
         *  Originally a large switch statement changed 
         *  due to below comments.
         *********/

        if (o.nodeType && nodeType[o.nodeType]) {
            r = nodeType[o.nodeType];
        }

        /*********
         *  If r is still false, we do a standard check
         *  using the Object.toString.call method to determine
         *  its "correct" type;
         *********/

        return r || ({}).toString.call(o).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
    }
}(g));


382
4
задан 29 сентября 2011 в 04:09 Источник Поделиться
Комментарии
2 ответа

Прежде чем что-то оценивать, нужно сначала определить, какие критерии оценки. Поэтому необходимо сначала определить, что "правильно определить объект" означает.

В функции оператора typeof оператор возвращает значения, как указано в ECMA-262, к сожалению, они имеют разные значения для фактического типа , как это определено в спецификации. Не ценность имеют отношения к внутреннему класс собственность.

Далее, для размещения объектов может возвращать все, что угодно для вызова typeof и внутренние класса, они могут даже вызывать ошибки при попытке доступа к ним.

Это редко нужно знать, в общем смысле, что "типа" что-то есть, когда вы хотите знать, если значение удовлетворяет определенным критериям по целевому назначению. Например, передача объекта в DOM-элемент стиля, чтобы ваша функция возвращает в Firefox "объекта cssstyledeclaration", в т. е. она возвращает "объект".

Разве что удовлетворить ваши критерии "правильно определить" (какими бы они ни были)? Что вызывающему разных значений? Зачем это нужно знать?

Я не знаю ответы (или даже полный набор вопросов, который может быть задан), поэтому я не могу работать, если ваша функция делает правильно или нет.

Некоторые замечания по коду:

> var FN = Function, 
> g = FN('return this')(); //jslint safe 'global' reference

Не:

var g = this;

достаточно?

> Object.typeOf = (function (g) {
> return function (o) {

Какой смысл в жизни? Нет запуска кода в нем, все, что она делает, это добавить закрытие в пустую (более или менее) на объект переменных внешней функции.

>    }
> }(g));

Если единственной целью было передать ссылку на глобальный объект, то:

    }
}(this));

будет делать эту работу. Так как вы не в строгом режиме, можно использовать следующие в нормальное выражение функции:

var global = (function(){return this;})();

большой оператор switch может быть заменен на что-то вроде:

if (typeof o.nodeType == 'number') {
var nodeTypes = {1:'element_node',2:'attribute_node',3:'text_node',4:'cdata_section_node',
5:'entity_reference_node',6:'entity_node',7:'processing_instrction_node',
8:'comment_node',9:'document_node',10:'document_type_node',
11:'document_fragment_node1',12:'notation_node'};
r = nodeTypes[o.nodeType];
}

7
ответ дан 29 сентября 2011 в 04:09 Источник Поделиться

Чтобы не быть намеренно педантичный, но мы здесь обсуждаем такие вещи, как правила кодирования.

Я не нравится, как вы переключаться с одного стиля на другой в один и тот же метод.

    if (o === n) {
return 'null';
}

/*********
* If we made it this far, just return the set the
* r variable and return at the end;
*********/

switch (o) {
case g:
r = 'global';
break;
case g.document:
r = 'htmldocument';
break;
default:
break;
}

Этот переключатель заявление может быть написано (короче), а два если заявления (и комментариях ничего не добавляют к функции).

В р переменной ненужно (где он используется, можно заменить оператор return).

Остальные переменные в этой функции являются константами относительно его.

Я бы переписать все это дело вот так:

/*jslint maxerr: 50, indent: 4 */
(function (g, Object, n, u) {
"use strict";
var nodeType = {
1: 'element_node',
2: 'attribute_node',
3: 'text_node',
4: 'cdata_section_node',
5: 'entity_reference_node',
6: 'entity_node',
7: 'processing_instrction_node',
8: 'comment_node',
9: 'document_node',
10: 'document_type_node',
11: 'document_fragment_node1',
12: 'notation_node'
};
Object.typeOf = function (o) {
if (o === u) {
return 'undefined';
}

if (o === n) {
return 'null';
}

if (o === g) {
return 'global';
}

if (o === g.document) {
return 'htmldocument';
}

if (o.nodeType && nodeType[o.nodeType]) {
return nodeType[o.nodeType];
}

return ({}).toString.call(o).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
};
}(this, Object, null));

2
ответ дан 26 апреля 2012 в 06:04 Источник Поделиться