前端“冷门”知识点备忘

在这篇博客中不定期连载比较“冷门”(其实就是自己用的比较少)的前端技术备忘,用作日后打脸

逗号运算符

逗号运算符是诸如此类的的运算符:

1, 2, 3, 4
var a = (1, 2)	// a=2
var a, b
for (var i = 0, j = 10; i < j; i++){} 
(1, g_t=44, 3+4, 4)
(1, eval)('2')	// 2

这个运算符的作用是将表达式连接起来,里面的各个表达式都会独自计算,返回最后一个表达式的运算结果。优先级处于最低,运算方向是从左到右,常常会和括号()连用,以提高运算符等级。

需要注意的是,以下的表达式是错的

var test = 1, 4

因为=的优先级先于,,赋值先于逗号执行,然而左边赋值又不是一个正规的赋值表达式,因此会抛出Uncaught SyntaxError: Unexpected number的错误。改法如下

var test = (1, 4)

需要注意的是,以上的,不能当做人类语法中的逗号使用,要看做一个程序上的运算符,和^&|这些类似。

另外不是所有在js中的逗号都是逗号运算符,比如函数参数add(1, 2, 3, 4, 5)

连等

连等可读性不太好,不过经常在一些框架中看到有人使用

a = b = {foo: 4}

=运算符是从右至左,因此拆开后就是

b = {foo: 4}
a = b

即a和b的内存地址相同,共同指向{foo: 4}

CSP

CSP(Content Security Policy),内容安全策略,可以在http头中的Content-Security-Policy或者html中的meta标签中定义。

 <meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">

以上标签可以阻止在设置之外的脚本运行,有效的防止xss。

其中有个配置名为script-src字段有个值为unsafe-eval,设置后不允许将字符串当做代码执行。比如不能使用evalsetTimeoutsetIntervalFunction等函数。
禁止以上函数可能会影响基于字符串模板的一些框架,本人在阅读vue源码的过程中发现如下代码,可以在脚本中检测是否开启了CSP的unsafe-eval,并给予友好提示:

// detect possible CSP restriction
try {
  new Function('return 1');
} catch (e) {
  if (e.toString().match(/unsafe-eval|CSP/)) {
    warn$$1(
      'It seems you are using the standalone build of Vue.js in an ' +
      'environment with Content Security Policy that prohibits unsafe-eval. ' +
      'The template compiler cannot work in this environment. Consider ' +
      'relaxing the policy to allow unsafe-eval or pre-compiling your ' +
      'templates into render functions.'
    );
  }
}

new Function和eval

这两个函数共同点就是可以执行字符串代码,区别在于作用域的不同。
另外,new Function的语法如下

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

eval的作用域在于当前上下文, new Funciton是在自己的匿名函数中的作用域,即私有作用域

var a,b,c;
(function(){
  eval('var b = 2');
  (1, eval)('var c = 3');
  (new Function('var a = 4'))();
  document.write('<br>a: ' + a);	// a: undefined
  document.write('<br>b: ' + b);	// b: 2
  document.write('<br>c: ' + c);	// c: 3
})()
document.write('<br>a: ' + a);		// a: undefined
document.write('<br>b: ' + b);		// b: undefined
document.write('<br>c: ' + c);		// c: 3

另外值得一提的是,eval通过不同的调用方式可以灵活的改变其作用域

eval('...')	// 当前作用域
window.eval('...')	// window作用域
eval.call(vm, '...')	// 'vm作用域'
(1, eval)(...)	// window作用域

Object.create(null)

同样在vue框架中看到大量使用的一种对象声明方式。

区别于直接{},这样生成的对象没有上级作用域,因此没有Object原型上的toString,valueOf等方法。在框架中使用的好处是减少可能的全局污染带来的影响,因为作者会实现自己的toString这些方法。

void 0

在控制台中敲进void 0 === undefined,会显示true,因为void多少都返回的是undefined。
在es5之前undefined是可以被重写的,因此用void 0指代undefined会更准确

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值