JS总结笔记(@神三元灵魂之问上)

1,220 阅读5分钟

1.基本包装类型(问:为什么'1'.toString()可以被调用)

基本类型和引用类型的值:

  • ES6变量中包含两种不同的数据类型:基本类型值和引用类型值;
    • 基本类型值:Null、Undefined、Boolean、Number、String、BigInt、Symbol;
    • 引用类型值:Object(普通对象-Object,数组对象-Array,正则对象-RegExp,日期对象-Date,数字函数-Math,函数对象-Function);
    • 注: 引用类型的值是保存在内存中的对象。与其他语言不同,JavaScript 不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。为此,引用类型的值是按引用访问的。

基本包装类型(答):

  • 为了便于操作基本类型值,ECMAScript 还提供了3个特殊的引用类型Boolean、Number、String.这些类型与本章介绍的其他引用类型相似,但同时也具有与各自的基本类型相应的特殊行为。实际上,每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据。
var s1 = 'hello world';
s2 = s1.toString();
  • 代码解析:

    • 1.创建String类型的实例;
    • 2.调用该实例的方法;
    • 3.离开销毁实例;

基本包装类型与引用类型的区别:

  • 对象的生命期不同:

    • 自动创建出来的基本包装对象的只存在于执行代码的那一行,即执行结束后离开销毁
    • new操作符创建的引用类型,在执行流离开当前作用域之前一直被保存在内存中

2. 如何理解BigInt

  • 什么是BigInt?

    -当整数值大于Number数据类型支持的范围时。这种数据类型允许我们安全的对大整数进行算术操作。

  • 为什么需要BigInt?

    • 在JS中,所有数字都以精度64位浮点格式表示非常;
  • 如何创建并使用BigInt?

      1. 在数字末尾加n;
        console.log(999999999997867667657578n);
      1. 用BigInt()构造函数;
        BigInt('8789658787767565678765'); //8789658787767565678765n
  • 注:
    +10n; //TyperError: Cannot convert a BigInt value to a number;

  1. 不支持一元加号运算符;
  2. 不允许BigInt和Number之间进行混合操作,因为隐式类型转换可能丢失信息;
  3. 不能将BigInt传递给Web api和内置的JS函数;(这些函数需要Number类型的数字);
  4.  if(0n){//判断条件为:false
     .....
     };
     if(3n){//判断条件为:true
         ....
     } 
    
  5. 元素都为BigInt的数组可以sort;
  6. 可以正常运算;

3.手写instanceof

4. Object.is 和 === 有什么区别?

5. 如何让if(a == 1 && a == 2)条件成立

5.1对象转原始类型的流程

  • 如果Symbol.toPrimitive()方法,优先调用
  • 调用valueOf()【效果相当于返回原数据】,转化为原始类型,则返回。
  • 调用toString()【效果相当于数据类型转换,将原类型转化为字符串】,转化类型为原始类型,则返回。
  1. valueOf()、toString()都是Object原型链上的方法,被每个对象继承;
  2. 对象的Symbol.toPrimitive属性。指向一个方法。该对象被转化为原始类型的值时,会调用这个办法,返回该对象对应的原始类型值;
  3. Symbol.toPrimitive()的优先级最高;

5.2 应用(答)

6. 闭包

  1. 闭包:有权访问另一个函数作用域的函数;(高程P178)
  2. 闭包产生的原因:
  • 作用域链:ES5中存在两种作用域:全局作用域和函数作用域;当访问一个变量时,解释器会在当前作用域中查找标识符,若没有,则向上查找(父级->祖父级->……);值得注意的是:每个子作用域都会拷贝上级的作用域,形成作用域链条。
  1. 闭包的本质:在当前环境存在指向父级作用域的引用,即让父级作用域的引用存在

4. 闭包的表现形式:

  • 返回一个函数;
  • 作为函数的参数传递;
  • 在定时器、事件监听、Ajax请求、跨窗口通信、Web Workers或者任何异步中,只要使用了回调函数,实际上就在使用闭包;
  • IIFE(立即执行函数表达式)创建闭包,保存了当前函数作用域和全局作用域window,因此可以访问全局作用域;
  1. 解决以下问题:
  • 补充:JS单线程eventLoop机制,当主线程中的同步任务执行结束后,才会执行异步任务(宏任务--setTimeout,微任务--Promise)
  • 方法一:(IIFE--当每次for循环时,把此时的变量i传递到定时器中)
  • 方法二:(给定时器传第三个参数,作为timer函数的第一个函数参数)

  • 方法三:(使用let声明变量,变为块级作用域)

7. 原型链

  1. 原型对象和构造函数的关系
  • 每当定义一个函数数据类型(普通函数、类)时候,都会天生自带一个prototype属性,这个属性指向函数的原型对象;
  • 当函数经过new调用时,这个函数就成为了构造函数,返回一个全新的实例对象,这个实例对象有一个 proto 属性,指向构造函数的原型对象;

  1. 描述原型链
  • JS对象通过prototype指向父类对象,直到指向Object对象为止,这像就形成了一个原型指向的链条,即原型链。

8. 实现继承

  1. call实现(改变this的指向,并执行函数)
  • 原理:将函数作为对象的属性,由对象进行调用。(apply同理,只需要改变参数即可)
  • 弊端:一旦父类原型对象中存在方法,那么子类无法继承;
  1. 借助原型链

  1. 寄生组合继承(最优)