Facebook JavaScript SDK中的函数注释方法的目的是什么?

8
我将开始使用Facebook JavaScript 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()被使用。 http://connect.facebook.net/en_US/all/debug.js

6
不确定为什么会有人给这个问题点踩和关闭投票,这是一个有趣的问题,也在SO的范围内。我也很好奇Facebook为什么要这样做。 - laurent
2
如果有人希望我对已经提到的内容进行扩展,我很乐意 :) - Sean Kinsey
1个回答

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)"),并且只接受需要一个字符串和可为空的整数或只接受一个字符串的函数。

谢谢。matches()函数(其别名为源代码中的__t)是用于执行函数参数类型检查的。但这个问题是要问__w的目的。@SeanVieira - user1481096
@user1481096 - 我已经对annotate进行了更多的解释。如果需要进一步帮助,请告诉我! - Sean Vieira
不是静态的(至少这部分不是),但是具有强大的动态类型。 - Sean Kinsey
感谢@SeanKinsey的澄清!从您的评论中可以得出结论,JS代码库中有一些部分是静态检查过的? - Sean Vieira

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接