叶落为重生每片落下的叶子都是为了下一次的涅槃...^_^

Sharp variables in JavaScript

    这也是之前自己遗漏的一个知识点,在最近的javascript词法分析里,一朋友指出我漏了一个点,就是sharp variables。
    我恨,mozilla难道也搞起特立独行了.....
    sharp variables 是moz独有的语法,按照mozilla的原话说:A sharp variable is a syntax in object initializers that allows serialization of objects that have cyclic references or multiple references to the same object.
     在构建对象时,可以以此语法表示对象间的循环引用或者多个引用同时指向同一对象...

     mozilla说,这是个不标准的语法,叫我们慎用...^_^ Sharp variables are a non-standard syntax for creating or serializing cyclic data graphs supported only by Mozilla's SpiderMonkey JS engine. Do not use them in non-Mozilla code, and even in Mozilla code consider the cleaner style of either multiple statements or a let-expression for constructing cyclic values. This feature is very likely to be removed at some point.

     来看看mozilla给的例子吧,其实还是很简单的:)

var a = {};
var b = {};
b.a1 
= a;
b.a2 
= a;
console.log(b.toSource());

在moz下面的结果为({a1:#1={}, a2:#1#}),a1,a2都指向了同一个空对象。
显而易见,这和b = {a1:{}, a2:{}},是有本质区别的。
不妨在moz下面尝试下面的例子:

//eg.1
var b = {a1:{}, a2:{}};
b.a1.test 
= 'me';
console.log(b)

//eg.2
var b = {a1:#1={}, a2:#1#};
b.a1.test 
= 'me';
console.log(b)

 

看了结果或许一切就明了了。sharp variables允许我们在创建对象直接量得时候创建出多引用同一指向的东东。
sharp variables 的使用方式也挺简单。‘#’后加上number,就组成一个sharp variable,(一定是number,不支持character)但是要注意的是这样的sharp variable 好像只能在Object的scope中才能使用(至少在我的测试中是这样)。
比如 {a: #1=[], b:#1#} 或者 [#2={}, #2#] 都是ok的。但是不能用直接量的形式给一个变量之类的(其实这样做也没意义...)

另外可以参考moz的js内核源码:http://mxr.mozilla.org/mozilla-central/source/js/src/jsscan.cpp?raw=1 大概在1812行:

#if JS_HAS_SHARP_VARS
      
case '#':
      {
        uint32 n;

        c 
= getChar();
        
if (!JS7_ISDEC(c)) {
            ungetChar(c);
            
goto badchar;
        }
        n 
= (uint32)JS7_UNDEC(c);
        
for (;;) {
            c 
= getChar();
            
if (!JS7_ISDEC(c))
                
break;
            n 
= 10 * n + JS7_UNDEC(c);
            
if (n >= UINT16_LIMIT) {
                ReportCompileErrorNumber(cx, 
this, NULL, JSREPORT_ERROR, JSMSG_SHARPVAR_TOO_BIG);
                
goto error;
            }
        }
        tp
->t_dval = (jsdouble) n;
        
if (cx->hasStrictOption() &&
            (c 
== '=' || c == '#')) {
            
char buf[20];
            JS_snprintf(buf, 
sizeof buf, "#%u%c", n, c);
            
if (!ReportCompileErrorNumber(cx, this, NULL, JSREPORT_WARNING | JSREPORT_STRICT,
                                          JSMSG_DEPRECATED_USAGE, buf)) {
                
goto error;
            }
        }
        
if (c == '=')
            tt 
= TOK_DEFSHARP;
        
else if (c == '#')
            tt 
= TOK_USESHARP;
        
else
            
goto badchar;
        
break;
      }
#endif /* JS_HAS_SHARP_VARS */

 

<!-- ============================================================ -->

好了,回到正题,我为什么会突然想起说这个东西呢,毕竟mozilla自己都说是个not-standard 的东东,花了这么大篇幅,有多大实用性呢?
恩恩,我也确实觉得只有moz支持的东东,要真的用它的时候不多,可是要做个简陋的js format 却不得不考虑它,你不用,不代表别人不用...所以只能怨叹一声...唉

既然sharp variables 只允许#后加数字,并且只有在Object和Array的scope中可用,那么,把它剃出来也不难了...

            var sharp = '#';
            
if (parser_pos < input_length && in_array(input.charAt(parser_pos), digits)) {
                
do {
                    c 
= input.charAt(parser_pos);
                    sharp 
+= c;
                    parser_pos 
+= 1;
                } 
while (parser_pos < input_length && c !== '#' && c !== '=');
                
if (c === '#') {
                    
//
                } else if (input.charAt(parser_pos) === '[' && input.charAt(parser_pos + 1=== ']') {
                    sharp 
+= '[]';
                    parser_pos 
+= 2;
                } 
else if (input.charAt(parser_pos) === '{' && input.charAt(parser_pos + 1=== '}') {
                    sharp 
+= '{}';
                    parser_pos 
+= 2;
                }
                
return [sharp, 'TK_SHARP_VAR'];

好了,说到这里,这边记录大概也达到我想记录的东西了...

革命尚未成功,偶还需继续努力... : ) 

posted on 2011-04-06 17:18  岑安  阅读(3697)  评论(4编辑  收藏  举报

导航