合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
[TOC] <br> <br> # 函数表达式的命名只能在内部访问,且不能被覆盖 ``` var q = function test() { test = 233 console.log(test) // ƒ test() } q() test // undefined ``` <br> <br> # 方法简写不能执行 new ``` var o = { foo: function () { console.log(123) }, bar() { console.log(456) } } o.bar() var f = o.foo.bind({}) new f() var p = o.bar.bind({}) new p() //报错 ``` # {} + [] 与 console.log({} + []) {} + [],前面视为代码块,执行后面的 + [],[]转化为0 console.log({} + []) 把整体作为语句 ``` {} + [] // 0 console.log({} + []) // [object Object] ``` <br> <br> # 如何让 (a == 1 && a == 2 && a == 3) 的值为true ## 重写对象的 valueOf 方法 如果a是一个对象Object,那在执行a`==`的时候首先会去先执行`valueOf`方法,如果没有`valueOf`方法,就会去执行`toString`方法。(`toString`方法与`valueOf`类似,这里不再重复) ~~~ const a = { value: 0 } a.valueOf = function () { return this.value += 1 } console.log( a == 1 && a == 2 && a == 3 ); ~~~ <br> ## 重写数组的 join 方法 如果a是一个数组Array,在数组转换成字符串的时候,数组`toString`会隐含调用`join()`方法 ~~~ let a = [1, 2, 3] a.join = a.shift console.log( a == 1 && a == 2 && a == 3 ); ~~~ <br> ## Proxy ~~~ let a = new Proxy({}, { i: 1, get: function() { return () => this.i++ } }) console.log( a == 1 && a == 2 && a == 3 ); ~~~ <br> ## Symbol.toPrimitive Object 转换为原始类型会调用什么方法? * 如果部署了 `[Symbol.toPrimitive]` 接口,那么调用此接口,若返回的不是基本数据类型,抛出错误。 * 如果没有部署 `[Symbol.toPrimitive]` 接口,那么根据要转换的类型,先调用 `valueOf` / `toString` 1. 非Date类型对象,`hint` 是 `default` 时,调用顺序为:`valueOf` >>> `toString`,即`valueOf` 返回的不是基本数据类型,才会继续调用 `valueOf`,如果`toString` 返回的还不是基本数据类型,那么抛出错误。 2. 如果 `hint` 是 `string`(Date对象的hint默认是string) ,调用顺序为:`toString` >>> `valueOf`,即`toString` 返回的不是基本数据类型,才会继续调用 `valueOf`,如果`valueOf` 返回的还不是基本数据类型,那么抛出错误。 3. 如果 `hint` 是 `number`,调用顺序为: `valueOf` >>> `toString` ~~~ // 部署 [Symbol.toPrimitive] / valueOf / toString 都可以 // 一次返回 1 2 3 即可 let a = { [Symbol.toPrimitive]: (function(hint) { let i = 1 return function() { return i++ } })() } console.log( a == 1 && a == 2 && a == 3 ); ~~~ ## 字符编码 ~~~ var aᅠ = 1; var a = 2; var ᅠa = 3; console.log(aᅠ === 1 && a === 2 && ᅠa=== 3 ); ~~~ <br> ## Object.definedProperty(使用===也返回true) ~~~ var value = 0; //window.value Object.defineProperty(window, "a", { get: function () { return this.value += 1 } }) console.log( a === 1 && a === 2 && a === 3 ); ~~~ <br> <br> # try中有return,finally还会执行吗 ~~~ function test() { let x = 1 try { ++x; return x; } catch (e) { } finally { ++x; // 3 } return x; // 2 } test() ~~~ ## finally 语句块还会执行吗 在**try执行完成之后,finally是一定会执行的**。这种特性可以让程序员避免在`try`语句中使用了`return`,`continue`或者`break`关键字 <br> ## try { return } finally{}? try中返回了`x=2`, finally语句又重新设置了`x=3`,为什么返回给主程序的结果是2呢? 如果在try中return的情况下,先把try中将要return的值先存到一个本地变量中,即本例中的x=2将会被保存下来。接下来去执行finally语句,最后返回的是存在本地变量中的值,即返回x=2. <br> Notes:还有一点要注意的,如果你在finally里也用了return语句,比如return ++x。那么程序返回值会是3。因为规范规定了,当try和finally里都有return时,会忽略try的return,而使用finally的return。