JavaScript ES6中的简写语法总结与使用技巧(13)

既然可以转换输入为大写,那我们再进一步想想,如果提供合适的标记模板函数,使用标记模板,我们还可以对模板中的表达式进行各种过滤处理,比如有这么一个场景,假设表达式的值都来自用户输入,假设有一个名为sanitize的库可用于去除用户输入中的html标签,那通过使用标记模板,就可以有效的防止XSS攻击了,使用方法如下。

function sanitized(parts, ...values) {
 return parts.reduce((all, part, index) =>
  all + sanitize(values[index - 1]) + part
 )
}
var comment = 'Evil comment<iframe src="http://evil.corp">
  </iframe>'
var html = sanitized`<div>${ comment }</div>`
console.log(html)
// <- '<div>Evil comment</div>'

ES6中的另外一个大的改变是提供了新的变量声明方式:let和const声明,下面我们一起来学习。

let & const 声明

可能很早之前你就听说过 let 了,它用起来像 var 但是,却有不同的作用域规则。

JavaScript的作用域有一套复杂的规则,变量提升的存在常常让新手忐忑不安。变量提升,意味着无论你在那里声明的变量,在浏览器解析时,实际上都被提升到了当前作用域的顶部被声明。看下面的这个例子:

function isItTwo(value) {
 if (value === 2) {
  var two = true
 }
 return two
}
isItTwo(2)
// <- true
isItTwo('two')
// <- undefined

尽管two是在代码分支中被声明,之后被外部分支引用,上述的JS代码还是可以工作的。var 声明的变量two实际是在isItTwo顶部被声明的。由于声明提升的存在,上述代码其实和下面代码的效果是一样的

function isItTwo(value) {
 var two
 if (value === 2) {
  two = true
 }
 return two
}

带来了灵活性的同事,变量提升也带来了更大的迷惑性,还好ES6 为我们提供了块作用域。

块作用域和let 声明
相比函数作用域,块作用域允许我们通过if,for,while声明创建新作用域,甚至任意创建{}块也能创建新的作用域:

{{{{{ var deep = 'This is available from outer scope.'; }}}}}
console.log(deep)
// <- 'This is available from outer scope.'

由于这里使用的是var,考虑到变量提升的存在,我们在外部依旧可以读取到深层中的deep变量,这里并不会报错。不过在以下情况下,我们可能希望这里会报错:

访问内部变量会打破我们代码中的某种封装原则;
父块中已有有一个一个同名变量,但是内部也需要用同名变量;
使用let就可以解决这个问题,let 创建的变量在块作用域内有效,在ES6提出let以前,想要创建深层作用域的唯一办法就是再新建一个函数。使用let,你只需添加另外一对{}: