• BFE——JS题库刷题经历


    我原先以为我的js虽然学的不算好,但也绝对还行。直到我在这个题库里写了两道题。。。

    怎么说呢,这个题库里的题是真的好,可以让我们以刷题的方式掌握很多js平时注意不到的知识点,下面是我这段时间刷题的经历,这篇博客只是为了记录一下学习经历,绝对不是为了国庆勋章水博客,嗯,绝对不是。
     题库链接JavaScript quizzes | BFE.dev - prepare for Front-End job interviews.

    97. `this` V

    1. const obj = {
    2. prefix: 'BFE',
    3. list: ['1', '2', '3'],
    4. log() {
    5. this.list.forEach(function (item) {
    6. console.log(this.prefix + item);
    7. });
    8. },
    9. };
    10. obj.log();
    11. //"undefined1"
    12. //"undefined2"
    13. //"undefined3"

     

    这里log函数内部的this指向obj,this.list.forEach内部的匿名函数中的this指向log函数,因此找不到prefix,输出为undefined。

    96. comparison

    1. console.log(10 > 9)
    2. console.log(10 > '9')
    3. console.log('10' > 9)
    4. console.log('10' > '9')
    5. //true
    6. //true
    7. //true
    8. //false

    js在使用>号进行判断时,如果两边有一边是字符一边是数字,会将字符转换为数字进行比较。要是两边都是字符,通过字典顺序进行比较,‘10’第一个字是‘1’比‘9’小,因此‘10’<'9'

    95. number format

    1. console.log(017 - 011)
    2. console.log(018 - 011)
    3. console.log(019 - 011)
    4. //6
    5. //9
    6. //10

    因为前导0存在,默认表示八进制,因此第一个为15-9 = 6.  但是第二行中,出现了8,因此第二行前面的数被认为是正常的十进制,后面是八进制,18-9 = 9

    最后一行同理,19-9 = 10

    94. emoji

    1. console.log('👍'.length)
    2. //2

    JavaScript字符串使用UTF-16代码单元表示。每个代码单元都可以用来表示[U+0000, U+ FFFF]范围内的一个代码点——也称为“ 基本多语言平面”(BMP)。

    对于U+ FFFF以外的代码点,可以将它们表示为代理对。也就是说,两个连续的代码单元。

    字符串的.length属性返回字符串中代码单元的数量。虽然这通常与字符长度相同,但使用BMP([U+0000,U+FFFF]范围外的字符会返回不同的长度。

    93. string

    1. let a = 'bfe.dev'
    2. a[0] = 'c'
    3. console.log(a)
    4. //"bfe.dev"

    从ES5开始,可以将字符串视为类似数组的对象,其中字符对应于一个数字索引。但是,当使用括号符号进行字符访问时,尝试删除或赋值。这些属性不会成功。所涉及的属性既不能写,也不能配置。

    92. NaN

    1. console.log(NaN == NaN)
    2. console.log(NaN === NaN)
    3. console.log(Object.is(NaN, NaN))
    4. console.log([NaN].indexOf(NaN))
    5. console.log([NaN].includes(NaN))
    6. console.log(Math.max(NaN, 1))
    7. console.log(Math.min(NaN, 1))
    8. console.log(Math.min(NaN, Infinity))
    9. //false
    10. //false
    11. //true
    12. //-1
    13. //true
    14. //NaN
    15. //NaN
    16. //NaN

    因为NaN与任何元素使用== 和===相比较都为false,哪怕另一个元素也是NaN.因此前两行输出都是NaN

    Object.is()用来确定两个数是否值是一样的,并且当我们比较两个NaN的时候,Object.is()会返回true,因此第三行输出true

    第四行使用indexOf(),而indexOf(NaN)===-1,第五行array.includes使用了SameValueZero比较算法,从而使includes(NaN)为true

    Math.max(),Math.min()如果任何一个参数不是数字,就会返回NaN。

    91. largest Array index

    1. const arr = []
    2. arr[(2 ** 32) - 2] = 1
    3. arr[(2 ** 32) - 1] = 2
    4. console.log(arr.at(-1))
    5. //1

    at()方法接受一个整数值并返回该索引处的项,这个整数值可以是正的也可以是负的,如果是负整数,从数组中的最后一项开始倒数。

    例:对于最后一项array[array.length-1]也通过可以调用array.at(-1)来访问

    JavaScript数组是从零开始的,使用32位索引:第一个元素的索引是0,最高的索引是4294967294(2^32−2),我们将其赋值为1

    访问时,arr.at(-1)返回最后一个元素。

    另外,请注意arr[2^32 - 1] = 2确实将2存储在该索引上,但是因为它超过了at所能访问的最大长度,所以访问不到这个索引。

    90. array keys

    1. console.log(Reflect.ownKeys([]))
    2. console.log(Reflect.ownKeys([,]))
    3. console.log(Reflect.ownKeys([1,,2]))
    4. console.log(Reflect.ownKeys([...[1,,2]]))
    5. // ["length"]
    6. // ["length"]
    7. // ["0","2","length"]
    8. // ["0","1","2","length"]

    静态的Reflect.ownKeys()方法返回目标对象自身属性键的数组。

    JavaScript中底层的数组是对象。它们的键是数字,值是元素。默认情况下,所有数组都有一个反映数组中元素数量的属性长度。在稀疏数组的情况下,孔不会将相应的键添加到数组中。

    此外,扩展运算符会将这些孔转换为undefined

    在第一个输出中,它是一个空数组,所以answer只包含长度

    在第二个输出中,数组[,]也是一个空的稀疏数组,因此孔被忽略,返回["length"]

    在第三个数组中,[1,,2]在索引0和2处定义值,因此输出["0","2","length"]

    在最后一个数组中,使用扩展运算符将输入数组更改为[1,undefined,2],因此所有键都给出以下输出["0","1","2","length"]

    89. let

    1. let a = 1;
    2. (function() {
    3. let foo = () => a
    4. let a = 2;
    5. console.log(foo())
    6. }())
    7. //2

    在这个立即执行函数里面,函数foo()只执行一个操作,就是返回a,返回调用这个函数时所在作用域的a。因此输出是2.

    88. try...catch

    1. var a = 'a'
    2. try {
    3. throw new Error('BFE.dev')
    4. } catch {
    5. var a = 'a1'
    6. }
    7. console.log(a)
    8. var b = 'b'
    9. try {
    10. throw new Error('BFE.dev')
    11. } catch (b) {
    12. var b = 'b1'
    13. }
    14. console.log(b)
    15. var c = 'c'
    16. try {
    17. throw new Error('BFE.dev')
    18. } catch (error) {
    19. var c = 'c1'
    20. }
    21. console.log(c)

    try-catch 语句,作为 JavaScript 中处理异常的一种标准方式。基本的语法如下所示:

    1. try{
    2. // 可能会导致错误的代码
    3. } catch(error){
    4. // 在错误发生时怎么处理
    5. }
    1. var a = 'a'
    2. try {
    3. throw new Error('BFE.dev')
    4. } catch { // 没有本地变量被使用
    5. var a = 'a1' // 重写外部变量a,重新声明全局变量a
    6. }
    7. console.log(a) // a1
    8. var b = 'b'
    9. try {
    10. throw new Error('BFE.dev')
    11. } catch (b) { // 局部变量b被引用
    12. var b = 'b1' // 不再指向全局变量,它只是一个局部作用域变量
    13. }
    14. console.log(b) // b
    15. var c = 'c'
    16. try {
    17. throw new Error('BFE.dev')
    18. } catch (error) { // 引用局部变量error传递错误
    19. var c = 'c1' // 重写外部变量c,重新声明全局变量c
    20. }
    21. console.log(c) // c1

    87. instanceOf 2

    1. console.log(Function instanceof Object)
    2. console.log(Object instanceof Function)
    3. console.log(Function instanceof Function)
    4. console.log(Object instanceof Object)
    5. //true
    6. //true
    7. //true
    8. //true

    instanceof 判断的原理是:通过左侧对象的隐式原型属性 __ proto __ 在原型链上向上一层层查找,找到右侧构造函数的原型对象属性 prototype 就返回 true。

    86. setTimeout III

    1. let func = () => {
    2. console.log(1)
    3. }
    4. setTimeout(() => {
    5. func = () => {
    6. console.log(2)
    7. }
    8. }, 0)
    9. setTimeout(func, 100)
    10. //1

    由于js执行遵循事件循环机制,因此先执行同步任务,再执行异步任务。当第一个异步函数改变func函数的时候,setTimeout(func, 100)早已被放入执行队列,因此在setTimeout(func, 100)中的func仍是一开始定义的func函数,所以输出为1.

    85. String.raw()

    1. console.log(String.raw`BFE\n.${'dev'}`) // "BFE\n.dev"
    2. console.log(String.raw({raw: 'BFE'}, 'd', 'e','v')); // "BdFeE"

    静态的String.raw()方法是模板字面量的标记函数。它用于获取模板字面量的原始字符串形式,也就是说,替换(例如${foo})会被处理,但转义(例如\n)不会被处理。注意,它的工作原理与默认模板函数类似,并执行字符串拼接。重要的区别是它不会转义字符。

    1. console.log("BFE\ndev") // \n会被转义
    2. // BFE
    3. // dev
    4. console.log(String.raw`BFE\ndev`) // 这里的\n会保持原样
    5. // BFE\ndev

    String.raw()的工作原理类似于一个交织函数。第一个参数是一个具有原始属性的对象,其值是一个可迭代对象(可以是字符串或数组),表示模板字面量中分离的字符串。剩下的参数是替换。额外的替换被忽略

    1. // 使用数组
    2. String.raw({ raw: [0,2,4] }, 1, 3, 5, 6, 7) // "01234"
    3. // 使用字符串
    4. String.raw({ raw: '024' }, 1, 3, 5, 6, 7) // "01234"

    84. Array.prototype.sort()

    1. const a = [999, 1111, 111, 2, 0]
    2. const b = a.sort()
    3. console.log(a)
    4. console.log(b)
    5. // [0,111,1111,2,999]
    6. // [0,111,1111,2,999]

    sort()函数将a进行了原地排序,因为里面没有写排序方式,因此是将每个元素根据Unicode编码进行排序。

    如果想要顺序排序

    const b = a.sort((x,y)=>x-y);

    83. Plus Plus

    1. console.log(1 + 1) // 2
    2. console.log(1 + + 1) // 1 + (+1) = 1 + 1 = 2
    3. console.log(1 + + 1 + 1) // 1 + (+1) + 1 = 1 + 1 + 1 = 3
    4. console.log(1 + + 1 + + 1) // 1 + (+1) + (+1) = 1 + 1 + 1 = 3
    5. console.log(1 + + + 1) // 1 + (+(+1)) = 1 + (+1) = 1 + 1 = 2
    6. console.log(1 + + '1' + + '1') // 1 + (+'1') + (+'1') = 1 + 1 + 1 = 3
    7. console.log('1' + + '1' + + '1') // "1" + (+'1') + (+'1') = "1" + 1 + 1 = "1" + "1" + "1" = "111"
    8. console.log('a' + + 'b') // "a" + (+'b') = a + "NaN" = "aNaN"
    9. console.log('a' + + 'b' + 'c') // "a" + (+'b') +'c' = a + "NaN" + "c" = "aNaNc"
    10. console.log('a' + + 'b' + + 'c') // "a" + (+'b') + (+'c') = a + "NaN" + "NaN" = "aNaNNaN"

    82. Proxy II

    1. class Dev {
    2. #name
    3. constructor(name) {
    4. this.#name = name
    5. }
    6. get name() {
    7. return this.#name;
    8. }
    9. }
    10. const dev = new Dev('BFE')
    11. console.log(dev.name) // "BFE"
    12. const proxyDev = new Proxy(dev, {})
    13. console.log(proxyDev.name) // Error

    私有类成员可以通过使用hash#前缀来创建。私有字段可以在类构造函数上从类声明本身内部访问,而不能从派生子类访问。

    代理无法从dev对象读取私有成员#name。

    81. setTimeout II

    1. let num
    2. for (let i = 0; i < 5; i++) {
    3. num = i
    4. setTimeout(() => {
    5. console.log(num)
    6. }, 100)
    7. }
    8. //4
    9. //4
    10. //4
    11. //4
    12. //4

     

    由于setTimeout()是异步的,因此当他执行的时候,for循环已经执行完毕,此时打印出来的num都是4

    80. Proxy I

    1. const obj = new Map()
    2. const map = new Map()
    3. obj.foo = 1
    4. map.set('foo', 2)
    5. console.log(obj.foo) //1
    6. console.log(map.get('foo')) //2
    7. const proxyObj = new Proxy(obj, {})
    8. const proxyMap = new Proxy(map, {})
    9. console.log(proxyObj.foo) //1
    10. console.log(proxyMap.get('foo')) //Error

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

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

    如果目标没有[[MapData]]内部插槽,则抛出TypeError异常。这里也对此进行了解释

    79. Equal III

    1. console.log(2.0 == "2" == new Boolean(true) == "1")
    2. // 2 == 2 == true == "1"
    3. // true == true == "1"
    4. // true == "1"
    5. // 1 == 1
    6. // true
  • 相关阅读:
    关于mpy电压采集模块的那些事儿(ads1256 ads8688 ad7606)
    3.Redis的5种数据结构
    【Linux】进程控制 (万字详解)—— 进程创建 | 进程退出 | 进程等待 | 程序替换 | 实现简易shell
    如何使用前端表格控件实现数据更新?
    常见的屏幕接口
    Express:CORS 跨域资源共享
    数据库简介
    力扣每日一题每天自动邮件提醒
    Android Studio下载安装
    NewStarCTF2023week2-include 0。0
  • 原文地址:https://blog.csdn.net/mhc20201554114/article/details/127131548