86.setTimeout III
let func = () => {
console.log(1)
}
setTimeout(() => {
func = () => {
console.log(2)
}
}, 0)
setTimeout(func, 100) // 1
setTimeout()方法设置一个计时器,在计时器过期后执行函数或指定的代码段。
在这里,func是在第一个setimeout内更改的,但由于这是回调的一部分,它在第一个setTimeout被调用之前不会执行。这就是为什么,原始func作为第二个超时的引用被传递,这个超时最终在100ms日志记录1之后被调用
85.String.raw()
// 这是一个来自BFE.dev的JavaScript测试
console.log(String.raw`BFE\n.${'dev'}`)
console.log(String.raw({raw: 'BFE'}, 'd', 'e','v'));
// 当您在下面的文本框中输入您的输入时
// 记住它被视为原始字符串并将被转义
static String.raw()方法是模板字面量的标记函数。它用于获取模板字面量的原始字符串形式,也就是说,替换(例如${foo})会被处理,但转义(例如\n)不会被处理。注意,它的工作原理与默认模板函数类似,并执行字符串拼接。重要的区别是它不会转义字符。
例子:
console.log("BFE\ndev") // \n gets escaped
// BFE
// dev
console.log(`BFE\ndev`) // \n gets escaped
// BFE
// dev
console.log(String.raw`BFE\ndev`) // \n remains as it is
// BFE\ndev
raw()的工作原理类似于一个交织函数。第一个参数是一个具有原始属性的对象,其值是一个可迭代对象(可以是字符串或数组),表示模板字面量中分离的字符串。剩下的参数是替换。额外的替换被忽略
例子:
// using array
String.raw({ raw: [0,2,4] }, 1, 3, 5, 6, 7) // "01234"
// using string
String.raw({ raw: '024' }, 1, 3, 5, 6, 7) // "01234"
84.Array.prototype.sort()
const a = [999, 1111, 111, 2, 0]
const b = a.sort()
console.log(a) // [0,111,1111,2,999]
console.log(b) // [0,111,1111,2,999]
sort()方法对数组的元素进行原地排序并返回排序后的数组
注意,数组是原地排序的,没有复制。
这解释了为什么a和b都被排序了。A被原地排序,而这个排序后的数组被赋值给b。
至于为什么数字没有按顺序出现,请记住sort需要一个定义排序顺序的比较函数。如果省略,则将数组元素转换为字符串,然后根据每个字符的Unicode编码点值进行排序。
当在字符串中比较时,"111" <“2”,“1111”& lt;“999”等。
83.Plus plus
console.log(1 + 1) // 2
console.log(1 + + 1) // 1 + (+1) = 1 + 1 = 2
console.log(1 + + 1 + 1) // 1 + (+1) + 1 = 1 + 1 + 1 = 3
console.log(1 + + 1 + + 1) // 1 + (+1) + (+1) = 1 + 1 + 1 = 3
console.log(1 + + + 1) // 1 + (+(+1)) = 1 + (+1) = 1 + 1 = 2
console.log(1 + + '1' + + '1') // 1 + (+'1') + (+'1') = 1 + 1 + 1 = 3
console.log('1' + + '1' + + '1') // "1" + (+'1') + (+'1') = "1" + 1 + 1 = "1" + "1" + "1" = "111"
console.log('a' + + 'b') // "a" + (+'b') = a + "NaN" = "aNaN"
console.log('a' + + 'b' + 'c') // "a" + (+'b') +'c' = a + "NaN" + "c" = "aNaNc"
console.log('a' + + 'b' + + 'c') // "a" + (+'b') + (+'c') = a + "NaN" + "NaN" = "aNaNNaN"
一元加号运算符(+)位于它的操作数前面,如果操作数还没有转换成数字,则尝试将其转换为数字。如果不可能,则返回NaN
在数学运算符中,+既适用于数字也适用于字符串(用于字符串连接)。因此,如果任何操作数不是数字,则使用+将所有操作数/s转换为字符串并进行连接。
一元运算符的优先级高于加法运算符。
82. Proxy II
class Dev {
#name
constructor(name) {
this.#name = name
}
get name() {
return this.#name;
}
}
const dev = new Dev('BFE')
console.log(dev.name) // "BFE"
const proxyDev = new Proxy(dev, {})
console.log(proxyDev.name) // Error
私有类成员可以通过使用哈希#前缀来创建。私有字段可以在类构造函数上从类声明本身内部访问,而不能从派生子类访问。
代理无法从dev对象读取私有成员#name。
81.setTimeOut II
let num
for (let i = 0; i < 5; i++) {
num = i
setTimeout(() => {
console.log(num)
}, 100)
}
// 4
// 4
// 4
// 4
// 4
在这里,num的行为类似于var。变量num实际上是在for循环中声明的,setTimeout的内部函数访问它。因此,当for循环运行完成时,每个内部函数都引用相同的变量num,该变量在循环结束时等于4
80,Proxy I 需要重新看看
const obj = new Map()
const map = new Map()
obj.foo = 1
map.set('foo', 2)
console.log(obj.foo) // 1
console.log(map.get('foo')) // 2
const proxyObj = new Proxy(obj, {})
const proxyMap = new Proxy(map, {})
console.log(proxyObj.foo) // 1
console.log(proxyMap.get('foo')) // Error
Proxy对象允许您创建一个可用于代替原始对象的对象,但它可能重新定义基本的对象操作,如获取、设置和定义属性。
如果没有定义处理程序,则默认行为是将操作转发到目标,但这只适用于诸如属性访问等标准行为,而不适用于外来对象的内部插槽。