code: function checkAndInitVars(doc, src, $dataKeys, $optsKeys){
  	let scope;
  	try{
  		scope = acornGlobals(src);
  		if ( !scope.length ) return src; // 正常，直接返回
  	}catch(e){
  		throw Err.cat('source syntax error', '\n-----------------', src, '\n-----------------', 'file='+ doc.file, e); // 多数表达式中有语法错误导致
  	}
  
  	// 函数内部添加变量声明赋值后返回
  	let vars = [];
  
  	for ( let i=0, v; i<scope.length; i++ ) {
  		v = scope[i];
  		let inc$data = $dataKeys.includes(v.name);
  		let inc$opts = $optsKeys.includes(v.name);
  		let incJsVars = JS_VARS.includes(v.name);
  		if ( !inc$data && !inc$opts && !incJsVars) {
  			let msg = 'template variable undefined: ' + v.name;
  			throw Err.cat(MODULE + doc.file, $dataKeys, new Err(msg));		// 变量不在$state或$options的属性范围内
  		}
  		if ( inc$data && inc$opts ) {
  			let msg = 'template variable uncertainty: ' + v.name;
  			throw Err.cat(MODULE + doc.file, new Err(msg));					// 变量同时存在于$state和$options，无法自动识别来源，需指定
  		}
  
  
  		if ( inc$data ) {
  			vars.push(`let ${v.name} = $state.${v.name};`)
  		}else if ( inc$opts ) {
  			vars.push(`let ${v.name} = $options.${v.name};`)
  		}
  	}
  
  	return FN_TMPL_DEF + vars.join('\n') + src.substring(FN_TMPL_DEF.length);
  }
docs: 检查是否有变量缩写，有则补足。 以支持{$state.abcd}简写为{abcd} TODO 检查$state、$options为null时是否正确使用参数