JavaScript一些常见语法

299 阅读3分钟

操作符

??

	a??b;
        //等同于
        (a!==null&&a!==undefined)?a:b;


void

void是一个操作符,该操作符指定要计算一个表达式但是返回值永远是undefined。 调用方法同时防止页面刷新 新浪微博,淘宝等大站的首页JS操作的href都是javascript:void(0) 既保证了返回值是undefined,又保证如果连接点击需要处理一些代码,随时将0替换掉就可以。

// 阻止链接跳转,URL不会有任何变化
<a href="javascript:void(0)" rel="nofollow ugc">点击此处</a>

// 虽然阻止了链接跳转,但URL尾部会多个#,改变了当前URL。(# 主要用于配合 location.hash)
<a href="#" rel="nofollow ugc">点击此处</a>

// 同理,# 可以的话,? 也能达到阻止页面跳转的效果,但也相同的改变了URL。(? 主要用于配合 location.search)
<a href="?" rel="nofollow ugc">点击此处</a>

// Chrome 中即使 javascript:0; 也没变化,firefox中会变成一个字符串0
<a href="javascript:0" rel="nofollow ugc">点击此处</a>

with语句

针对一个对象反复操作,严格模式不允许

let qs=location.search.substring(1);
let host=location.hostname;
//可替换为
with(location){
let qs=search.substring(1);
let host=hostname;
}

模板字面量

字面量:直接出现在程序中的数据值,包含整数字面量1、浮点字面量、字符串字面量等

模板字面量:允许嵌入表达式的字符串字面量,使用反引号 () 来代替普通字符串中的用双引号和单引号来定义字符串

字符串插值:模板字符串可以包含特定语法 ${expression} 的占位符。占位符中的表达式和周围的文本会一起传递给一个默认函数,该函数负责将所有的部分连接起来。

arr[part_key${i}]; //访问part_key*的属性

动态构建字符串时使用模板字符串而不是拼接

// bad
function sayHi(name) {
  return 'How are you, ' + name + '?';
}

// good
function sayHi(name) {
  return `How are you, ${name}?`;
}

标签函数

如果一个模板字符串由表达式开头,则该字符串被称为带标签的模板字符串,该表达式通常是一个函数,它会在模板字符串处理后被调用,在输出最终结果前,你都可以通过该函数来对模板字符串进行操作处理。

在模版字符串内使用反引号(`)时,需要在它前面加转义符(\)

// that ${ person } is a ${ age }调用标签函数,第一个参数是一个数组,对应模板中的字符串。变量对应形参
var person = 'Mike';
var age = 28;

function myTag(strings, personExp, ageExp) {

  var str0 = strings[0]; // "that "
  var str1 = strings[1]; // " is a "

  var ageStr;
  if (ageExp > 99){
    ageStr = 'centenarian';
  } else {
    ageStr = 'youngster';
  }

  return str0 + personExp + str1 + ageStr;

}

var output = myTag`that ${ person } is a ${ age }`;

console.log(output);
// that Mike is a youngster

注意 :如果标签函数传参首尾有变量会产生空元素,如下

myTag` ${ person } is a ${ age }`;
原理:标签函数拆分传参的方式是

args.split(/\$\{.*?\}/)
'|b|c'.split('|'); // [ ' ', 'b' , 'c' ]

应用

模板提供了插值语法,同时也引入了XSS的风险(当我们把插值的权力交给用户),所以这时候就需要标签函数来过滤、编码、组合。

eval()

一个危险的函数, 拥有与调用者相同的权限执行代码。再者第三方代码可以看到某一个 eval() 被调用时的作用域

eval() 通常比其他替代方法更慢,因为它必须调用 JS 解释器。现代JavaScript解释器将javascript转换为机器代码。 这意味着任何变量命名的概念都会被删除。 因此,任意一个eval的使用都会强制浏览器进行冗长的变量名称查找,以确定变量在机器代码中的位置并设置其值。 另外,新内容将会通过 eval() 引进给变量, 比如更改该变量的类型,因此会强制浏览器重新执行所有已经生成的机器代码以进行补偿。

一个非常好的eval替代方法:只需使用 window.Function

断言assert

断言是 调试技巧, 在大多编程语言中都支持断言这种机制来调式程序,JavaScript 借助浏览器提供的 console 方法 来实现的。

提前预判 程序的结果,如果之后执行的程序不符合我们的预判,那么则报错,例如下面这个例子。

function f(n) {
 console.assert(n !== 0, '零不能作为被除数') // 这里就是断言 | 提前预判
 return 10 / n
}

console.log(f(1)) // 10
console.log(f(2)) // 5
console.log(f(0)) // 报错 | Assertion failed: 零不能作为被除数