组件中如何将html中的表达式变成代码执行

本文探讨了在Vue中如何将HTML中的表达式转换为代码执行,主要介绍了eval函数的工作原理及其潜在风险,以及Function构造函数的用法。文章通过示例解释了这两种方法如何将字符串形式的代码转换为可执行的JavaScript代码。

在vue的学习里面,我遇到了如下的一个指令:

<div>{{ ok ? true:false}}</div>

很神奇,他可以将div里面的text变成代码执行
他是如何实现的呢?
接下来我们就来聊一聊,简单的将html的表达式模版变成实际的代码执行

正文

1.eval函数

eval("ok?true:false");

以上很简单就可以实现了

eval() 是全局对象的一个函数属性。

eval() 的参数是一个字符串。如果字符串表示的是表达式,eval() 会对表达式进行求值。如果参数表示一个或多个 JavaScript 语句, 那么 eval() 就会执行这些语句。注意不要用 eval() 来执行一个算术表达式;因为 JavaScript 可以自动为算术表达式求值。

如果你以字符串的形式构造算术表达式,则可以用 eval() 在随后对其求值。例如,假设你有一个变量 x ,您可以通过将表达式的字符串值(例如3 * x + 2 )赋值给一个变量,然后在你的代码后面的其他地方调用 eval() ,来推迟涉及 x 的表达式的求值。

如果 eval() 的参数不是字符串, eval() 将会将参数原封不动的返回。在下面的例子中,String 构造器被指定, 而
eval() 返回了 String 对象而不是执行字符串。

eval(new String("2 + 2")); // 返回了包含"2 + 2"的字符串对象
eval("2 + 2");             // returns 4

如果你间接的使用 eval(),比如通过一个引用来调用它,而不是直接的调用 eval 。 从 ECMAScript 5
起,它工作在全局作用域下,而不是局部作用域中。例如:

function test() {
var x = 2, y = 4;
console.log(eval(“x + y”)); // 直接调用,使用本地作用域,结果是 6
var geval = eval; // 等价于在全局作用域调用
console.log(geval(“x + y”)); // 间接调用,使用全局作用域,throws ReferenceError 因为x未定义
(0, eval)(‘x + y’); // 另一间接调用的例子
​}

eval() 是一个危险的函数, 他执行的代码拥有着执行者的权利。如果你用 eval() 运行的字符串代码被恶意方(不怀好意的人)操控修改,您最终可能会在您的网页/扩展程序的权限下,在用户计算机上运行恶意代码。更重要的是,第三方代码可以看到某一个eval()被调用时的作用域,这也有可能导致一些不同方式的攻击。相似的 Function 就不容易被攻击。

eval() 通常比替代方法慢,因为它必须调用 JS 解释器,而许多其他结构则由现代 JS 引擎进行优化。

2.function的构造方式

new Function ([arg1[, arg2[, …argN]],] functionBody)

arg1, arg2, … argN
被函数使用的参数的名称必须是合法命名的。参数名称是一个有效的JavaScript标识符的字符串,或者一个用逗号分隔的有效字符串的列表;例如“×”,“theValue”,或“A,B”。

functionBody 一个含有包括函数定义的JavaScript语句的字符串。

使用Function构造器生成的Function对象是在函数创建时解析的。这比你使用函数声明或者函数表达式(function)并在你的代码中调用更为低效,因为使用后者创建的函数是跟其他代码一起解析的。

所有被传递到构造函数中的参数,都将被视为将被创建的函数的参数,并且是相同的标示符名称和传递顺序。

注意:
使用Function构造器生成的函数,并不会在创建它们的上下文中创建闭包;它们一般在全局作用域中被创建。当运行这些函数的时候,它们只能访问自己的本地变量和全局变量,不能访问Function构造器被调用生成的上下文的作用域。这和使用带有函数表达式代码的
eval 不同。

例子:
HTML:

 <div>  {{ok?true:false}}</div>

JS:

var ok = false;
var f = new Function('return ' + 'ok?true:false');
f()//false

以上就是简单的实现方法

附vue里面的方法:

function checkExpression (exp, text, warn, range) {
    try {
      new Function(("return " + exp));
    } catch (e) {
      var keywordMatch = exp.replace(stripStringRE, '').match(prohibitedKeywordRE);
      if (keywordMatch) {
        warn(
          "avoid using JavaScript keyword as property name: " +
          "\"" + (keywordMatch[0]) + "\"\n  Raw expression: " + (text.trim()),
          range
        );
      } else {
        warn(
          "invalid expression: " + (e.message) + " in\n\n" +
          "    " + exp + "\n\n" +
          "  Raw expression: " + (text.trim()) + "\n",
          range
        );
      }
    }
  }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值