当前位置:Gxlcms > JavaScript > Underscore.js1.3.3中文注释翻译说明_基础知识

Underscore.js1.3.3中文注释翻译说明_基础知识

时间:2021-07-01 10:21:17 帮助过:12人阅读

输出变量的界定符 interpolate : /<%=([\s\S]+?)%>/g, // 需要将HTML输出为字符串(将特殊符号转换为字符串形式)的界定符 escape : /<%-([\s\S]+?)%>/g }; var noMatch = /.^/; // escapes对象记录了需要进行相互换转的特殊符号与字符串形式的对应关系, 在两者进行相互转换时作为索引使用 // 首先根据字符串形式定义特殊字符 var escapes = { '\\' : '\\', "'" : "'", 'r' : '\r', 'n' : '\n', 't' : '\t', 'u2028' : '\u2028', 'u2029' : '\u2029' }; // 遍历所有特殊字符字符串, 并以特殊字符作为key记录字符串形式 for(var p in escapes) escapes[escapes[p]] = p; // 定义模板中需要替换的特殊符号, 包含反斜杠, 单引号, 回车符, 换行符, 制表符, 行分隔符, 段落分隔符 // 在将字符串中的特殊符号转换为字符串形式时使用 var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; // 在将字符串形式的特殊符号进行反转(替换)时使用 var unescaper = /\\(\\|'|r|n|t|u2028|u2029)/g; // 反转字符串中的特殊符号 // 在模板中涉及到需要执行的JavaScript源码, 需要进行特殊符号反转, 否则如果以HTML实体或字符串形式出现, 会抛出语法错误 var unescape = function(code) { return code.replace(unescaper, function(match, escape) { return escapes[escape]; }); }; // Underscore模板解析方法, 用于将数据填充到一个模板字符串中 // 模板解析流程: // 1. 将模板中的特殊符号转换为字符串 // 2. 解析escape形式标签, 将内容解析为HTML实体 // 3. 解析interpolate形式标签, 输出变量 // 4. 解析evaluate形式标签, 创建可执行的JavaScript代码 // 5. 生成一个处理函数, 该函数在得到数据后可直接填充到模板并返回填充后的字符串 // 6. 根据参数返回填充后的字符串或处理函数的句柄 // ------------------- // 在模板体内, 可通过argments获取2个参数, 分别为填充数据(名称为obj)和Underscore对象(名称为_) _.template = function(text, data, settings) { // 模板配置, 如果没有指定配置项, 则使用templateSettings中指定的配置项 settings = _.defaults(settings || {}, _.templateSettings); // 开始将模板解析为可执行源码 var source = "__p+='" + text.replace(escaper, function(match) { // 将特殊符号转移为字符串形式 return '\\' + escapes[match]; }).replace(settings.escape || noMatch, function(match, code) { // 解析escape形式标签 <%- %>, 将变量中包含的HTML通过_.escape函数转换为HTML实体 return "'+\n_.escape(" + unescape(code) + ")+\n'"; }).replace(settings.interpolate || noMatch, function(match, code) { // 解析interpolate形式标签 <%= %>, 将模板内容作为一个变量与其它字符串连接起来, 则会作为一个变量输出 return "'+\n(" + unescape(code) + ")+\n'"; }).replace(settings.evaluate || noMatch, function(match, code) { // 解析evaluate形式标签 <% %>, evaluate标签中存储了需要执行的JavaScript代码, 这里结束当前的字符串拼接, 并在新的一行作为JavaScript语法执行, 并将后面的内容再次作为字符串的开始, 因此evaluate标签内的JavaScript代码就能被正常执行 return "';\n" + unescape(code) + "\n;__p+='"; }) + "';\n"; if(!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; source = "var __p='';" + "var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n" + source + "return __p;\n"; // 创建一个函数, 将源码作为函数执行体, 将obj和Underscore作为参数传递给该函数 var render = new Function(settings.variable || 'obj', '_', source); // 如果指定了模板的填充数据, 则替换模板内容, 并返回替换后的结果 if(data) return render(data, _); // 如果没有指定填充数据, 则返回一个函数, 该函数用于将接收到的数据替换到模板 // 如果在程序中会多次填充相同模板, 那么在第一次调用时建议不指定填充数据, 在获得处理函数的引用后, 再直接调用会提高运行效率 var template = function(data) { return render.call(this, data, _); }; // 将创建的源码字符串添加到函数对象中, 一般用于调试和测试 template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; // 没有指定填充数据的情况下, 返回处理函数句柄 return template; }; // 支持Underscore对象的方法链操作, 可参考 wrapper.prototype.chain _.chain = function(obj) { return _(obj).chain(); }; // Underscore对象封装相关方法 // --------------- // 创建一个包装器, 将一些原始数据进行包装 // 所有的undersocre对象, 内部均通过wrapper函数进行构造和封装 // Underscore与wrapper的内部关系: // -内部定义变量_, 将Underscore相关的方法添加到_, 这样就可以支持函数式的调用, 如_.bind() // -内部定义wrapper类, 将_的原型对象指向wrapper类的原型 // -将Underscore相关的方法添加到wrapper原型, 创建的_对象就具备了Underscore的方法 // -将Array.prototype相关方法添加到wrapper原型, 创建的_对象就具备了Array.prototype中的方法 // -new _()时实际创建并返回了一个wrapper()对象, 并将原始数组存储到_wrapped变量, 并将原始值作为第一个参数调用对应方法 var wrapper = function(obj) { // 原始数据存放在包装对象的_wrapped属性中 this._wrapped = obj; }; // 将Underscore的原型对象指向wrapper的原型, 因此通过像wrapper原型中添加方法, Underscore对象也会具备同样的方法 _.prototype = wrapper.prototype; // 返回一个对象, 如果当前Underscore调用了chain()方法(即_chain属性为true), 则返回一个被包装的Underscore对象, 否则返回对象本身 // result函数