2015-08-11 3 views
4

Как я могу различать эти три вещи в ES6, используя его ссылку?Как я могу различать функцию стрелки, класс и нормальную функцию?

let x = i => i+1; 

class y { constructor(i) { this._i=i+1; } get i(){ return this._i;} } 

function z(i) { return i+1; } 

Пример:

test(x) //=> 'arrow' 
test(y) //=> 'class' 
test(z) //=> 'function' 

И как я могу различать эти вещи в transpilers - Traceur/Babel?

+1

Какая у вас просьба? Я бы попытался вызвать func.toString() и посмотреть, что я получаю и, возможно, проанализировать. – Bnaya

+0

Я бы настоятельно рекомендовал, чтобы имена классов соответствовали давней традиции конструкторов, имеющих первую букву в верхнем регистре. Таким образом, с первого взгляда легко понять, что 'Function()' является либо классом, либо конструктором, а 'function()' является функцией. – slebetman

ответ

7

Как я могу различать эти вещи в ES6?

  • стрелками функции являются функциями, которые не могут быть использованы в качестве конструкторов, и не имеют .prototype собственности. Однако методы тоже не существуют. Они наследуют от Function.prototype.
  • классы - это функции, которые нельзя вызвать без new, и которые имеют объект .prototype, который обычно не пуст. Если использовалось ключевое слово extends, они не наследуются от Function.prototype.
  • функции - это функции, которые можно назвать в любом случае, и имеют .prototype, то есть normally empty. Они наследуют от Function.prototype.
  • функция генератора являются функциями, которые делают имеют .prototype, который наследуется от внутреннего GeneratorPrototype объекта, и они наследуют от собственного объекта Генератора.

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

Итак, ваш лучший выбор может быть Function.prototype.toString, чтобы посмотреть, как выглядит источник. Если ваша реализация ES поддерживает это.

И как я могу различать эти вещи в транспилерах?

Я не думаю, что какой-либо транспилер не использует стрелки и методы прототипа. Создается ли конструктор классов при вызове, зависит от слабости транспиляции, но в любом случае это не очень хороший способ разграничения.
toString не работает ни afaik.

+1

Спасибо !. Я просто попробовал это на v8, и все работает отлично. https://gist.github.com/boopathi/7c4adc4f4790f432838d. Это терпит неудачу, когда я пытаюсь это на методах хотя. –

+1

Обновлено содержание. Теперь поддерживает обнаружение генераторов и методов. Надеюсь, мои предположения верны. Упомянули их в комментариях кодов. –

1

Вы не можете первые два случая получить transpiled в этом:

var x = function x(i) { 
    return i + 1; 
}; 

function z(i) { 
    return i + 1; 
} 

Для последнего можно проверить, если он жалуется, если это класс, когда вы называете его:

function isClass(instance){ 
    try{ 
    instance() 
    }catch(e){ 
    return e.message === "Cannot call a class as a function"; 
    } 
    return false; 
} 

Но это, очевидно, вызовет побочные эффекты его вызова, поэтому в общем случае это не работает.

+0

Err, почему это проголосовало? Он напрямую отвечает на вопрос. Это довольно грубо, чтобы проголосовать за что-то без объяснения причин. –

+1

Я думаю, потому что вы не получите transpiled, пока не будете использовать транспилер, иначе в родных браузерах этот случай не будет применен. –

+0

@BarbuBarbu. Последняя часть вопроса специально спрашивает о дифференцировании после транспиляции. –

Смежные вопросы