What is the purpose of function annotation method in JavaScript JavaScript SDK?

I am starting to use the javscript SDK on facebook and I found an interesting thing when I read the source code.

An example code looks like this:

/** * 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? 

So my question is what is being used? What is the advantage ?

FYI, all source code is here, where you can see a lot of annotate () is used

http://connect.facebook.net/en_US/all/debug.js

+8
javascript annotations facebook-javascript-sdk
source share
1 answer

This is apparently a homely strong typing setting:

 /** * 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; } 

The reason they use the annotate function is because of type resolution for custom types and function signatures. Without annotate you can only do matches(someVar, "function") . With annotate you can make matches(someVar, "function(string, ?int)|function(string)") and accept only functions that accept a string and a NULL integer value or functions that accept only a string.

+3
source share

All Articles