JS题库中的题解以及知识点(二)

本文介绍了JavaScript中setTimeout的执行机制,模板字面量的原始字符串处理,Array.prototype.sort()的排序规则,以及一元加法运算符的细节。同时,讲解了私有类成员的访问限制和Proxy对象如何拦截对象操作。通过实例展示了这些特性的实际应用和潜在陷阱。
摘要由CSDN通过智能技术生成

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对象允许您创建一个可用于代替原始对象的对象,但它可能重新定义基本的对象操作,如获取、设置和定义属性。

如果没有定义处理程序,则默认行为是将操作转发到目标,但这只适用于诸如属性访问等标准行为,而不适用于外来对象的内部插槽。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值