A walk through, Reflection and tests for different kinds of functions in JavaScript till ES2015 spec.
npm test
cd src
/path/to/d8 test.js
(or) if you have d8
in your $PATH
,
npm run v8
The idea is to detect from a reference the type of function - arrow, class or a normal function. And to detect before instantiating if the reference is instantiable.
This repository is about defining the function getFunctionType
which returns the type of function input -
- arrow
- class
- method
- generator
- function
- generator-method
Source: http://stackoverflow.com/a/31947622/556124
- arrow functions are functions that cannot be used as constructors, and don't have a .prototype property. However, methods don't either. They inherit from Function.prototype.
- classes are functions that can be called without new, and that have a .prototype object which is normally not empty. If extend was used, they don't inherit from Function.prototype.
- functions are functions that can be called either way, and do have a .prototype that is normally empty. They inherit from Function.prototype.
- generator functions are functions that do have a .prototype which inherits from the intrinsic GeneratorPrototype object, and they inherit from the intrinsic Generator object.
let A = () => {};
let B = {
x: () => {}
};
class A {}
function B() {}
B.prototype.x = function() {};
class A {
method() {}
}
let B = {
method() {}
};
function *A() {}
let B = {
x: function *() {}
};
function A() {}
let B = {
x: function() {}
};
let A = {
*x() {}
};
class B {
*x() {}
}
- Don't transpile this using babel or traceur. It will give your absolutely wrong results.
- arrows
- generators
- classes
- enhanced object literals
- let, const
- Map
- Array.prototype.startsWith
- etc...
// this will be treated as a class
function x() {}
x.prototype.a = function() {}
// this is a simple function
function y() {}
// either via enhanced object literals
let x = {
method() {}
};
// or via class
class x {
method() {}
}
I don't know anyway to detect the following as methods yet.
function y() {}
y.prototype.method = function() {};
y.prototype.genmethod = function*() {};
let x = {
a() {}
*method() {}
};
// x.a.prototype does NOT exist
// x.method.prototype exists
class y {
a() {}
*method() {}
}
// new y().a.prototype does NOT exist
// new y().method.prototype exists