我开始使用facebook javscript SDK,当我阅读源代码时,我发现了一件有趣的事情。
代码示例如下:
/**
* Annotates a function with a meta object
*/
function annotate(fn, meta) {
meta.superClass = fn.__superConstructor__;
fn.__TCmeta = meta;
return fn;
}
// export to global
__w = annotate;
/**
* when using the annotate function
*/
function sprintf(format) {
// function body
}
__w(sprintf, {"signature":"function(string)"}); // <-- what is the purpose of doing this?
所以,我的问题是用于什么?什么是好处这样做?
仅供参考,整个源代码在这里,你可以看到很多annotate()被使用
答案 0 :(得分:3)
这似乎是一个本土强大的打字设置:
/**
* A recursive descent analyzer which takes a value and a typehint, validating
* whether or not the value matches the typehint.
* The function will call it self as long as both the value and the typehint
* yields a nested component. This means that we will never recurse deeper
* than needed, and also that we automatically get support for
* > equals([], 'array<string>') // true
* > equals(['string'], 'array') // true
*/
function equals(value, node) {
var type = typeof value;
var subType;
var nextNode;
var nextValue;
//: Nullable types are delimited with a leading ?
//: ?string, ?boolean, etc.
var nullable = /^\?/.test(node);
if (nullable) {
node = node.substring(1);
}
//: snip ...
switch (type) {
// start by testing the most common types
case 'boolean':
case 'number':
case 'string':
case 'undefined':
break;
default:
//: snip ...
// let functions with signatures also match 'function'
type = value.__TCmeta && node !== 'function'
? value.__TCmeta.signature
: 'function';
} else if (type === 'object' || type === 'function') {
// HTMLObjectElements has a typeof function in FF
var constructor = value.constructor;
if (constructor && constructor.__TCmeta) {
// The value is a custom type
//: snip ...
while (constructor && constructor.__TCmeta) {
if (constructor.__TCmeta.type == node) {
type = node;
break;
}
constructor = constructor.__TCmeta.superClass;
}
//: snip ...
}
}
}
}
if (nullable && /undefined|null/.test(type)) {
return true;
}
if (type in typeInterfaces) {
var interfaces = typeInterfaces[type], i = interfaces.length;
while (i--) {
if (interfaces[i] === node) {
type = node;
break;
}
}
}
currentType.push(type);
return nextValue && nextNode
? node === type && equals(nextValue, nextNode)
: subType && nextNode
? node === type && subType === nextNode
: node === type;
}
/**
* Given a value and a typehint (can be a union type), this will return
* whether or not the passed in value matches the typehint.
*/
function matches(value, node) {
var nodes = node.split('|'), i = nodes.length;
while (i--) {
currentType = [];
if (equals(value, nodes[i])) {
return true;
}
}
return false;
}
他们使用annotate
函数的原因是允许自定义类型和函数签名的类型提示。如果没有annotate
,您只能matches(someVar, "function")
。使用annotate
,您可以执行matches(someVar, "function(string, ?int)|function(string)")
并且只接受带有字符串和可空integer
的函数或只接受字符串的函数。