2023/2/23日笔记

31 阅读1分钟

Snipaste_2023-02-23_14-05-48.png

值类型与引用类型有什么区别?

哪些类型是值类型?哪些类型是引用类型

· 值类型:String、Number、Boolean、Symbol
· 引用类型:JSON、Array、null

演示值类型与引用类型的堆栈模型

image.png

image.png

变种提问

const a={x:100, y:200}
const b=a
let c=a.x
b.x=300
console.log(a) // x:300

演示代码

<html>
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@说人话的前端 - bilibili</title>
  </head>
  <body></body>
  <script>
    // 因为这时候的a1值为100:number值,所以更改b1的值互不影响
    let a1 = 100;
    let b1 = a1;
    b1 = 200;
    console.log(a1); // a1 = 100

    // 而这时的a2是引用类型,他们共用一个引用值,所以当b2值变化的时候,a2也同时发生变化
    let a2 = { age: 18 };
    let b2 = a2;
    b2.age = 20;
    console.log(a2); // { age: 20 }
    
    // 变种提问
        // const a={x:100, y:200}
        // const b=a
        // let c=a.x        // 这一行是误导的,忽略即可
        // b.x=300
        // console.log(a) // x:300        
  </script>
</html>

手写深拷贝

如何实现深拷贝

  • JSON.parse(JSON.stringify(obj))

    不能存放函数、时间对象、正则...

  • 递归

    没有考虑循环引用。。

  • lodash.cloneDeep 推荐,工作中没必要重复造轮子

演示代码

<html>
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@说人话的前端 - bilibili</title>
  </head>
  <body></body>
  <script>
    const obj1 = {
      name: "张三",
      age: 18,
      address: {
        city: "北京",
      },
      hobby: ["台球", "篮球"],
      fn: function () {
        console.log(123);
      },
    };

    const obj2 = deepClone(obj1);
    obj2.age = 20;
    obj2.address.city = "上海";
    console.log(obj1);
    console.log(obj2);

    // 此方法仅适用简单的深拷贝,因为该方法会把拷贝中的函数、正则、时间对象、错误对象等都干没了
    // function deepClone(obj) {
    //   return JSON.parse(JSON.stringify(obj));
    // }
    

    function deepClone(obj) {
      // 判断该类型是不是一个对象或这个obj是不是空的如果不是就没必要去递归,直接返回出来就可以了
      if (typeof obj !== "object" || obj == null) {
        return obj;
      }
        
      // 判断一下这个obj是数组还是对象,然后让这个res等于数组/对象
      let res = obj instanceof Array ? [] : {};

      // 遍历obj
      for (let key in obj) {
        // 为了让代码更健壮
        if (obj.hasOwnProperty(key)) {
          // 再引用一次deepClone是为了解决有多层引用关系的情况
          // name/age...    "张三"/18...      name:"张三"/age:18...
          res[key] = deepClone(obj[key]);
        }
      }

      return res;
    }
  </script>
</html>

何时使用==何时使用===

== 隐式类型转换

0 == ''
0 == false
false == ''
null == undefined

只有 obj == null 使用双等

if (obj === null || obj === undefined) {
    
}

演示代码

<html>
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@说人话的前端 - bilibili</title>
  </head>
  <body></body>
  <script>
    console.log(100 == "100");
    console.log(0 == "");
    console.log(0 == false);
    console.log("" == false);
    console.log(null == undefined);

    let obj = { age: 18 };
    if (obj == null) {
    }
    if (obj === null || obj === undefined) {
    }
  </script>
</html>

哪些是truly变量?哪些是falsely变量?

什么是truly变量?什么是falsely变量?

  • truly变量:!!val === true
  • falsely变量:!!val === false

除了falsely变量,都是truly变量

  • 数字0

  • NaN

  • 空字符串

  • null

  • undefined

演示代码

<html>
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@说人话的前端 - bilibili</title>
  </head>
  <body></body>
  <script>
    // ==会涉及到隐式类型转换
    console.log(!!"" === false);
    console.log(!!NaN === false);
    console.log(!!0 === false);
    console.log(!!null === false);
    console.log(!!undefined === false);
    
    // 只有 obj == null 使用双等,其他时候最好用全等===
    if (obj == null){

    }
    if (obj === null || obj === undefined) {
    
    }
  </script>
</html>

哪些是truly变量?哪些是falsely变量?

什么是truly变量?什么是falsely变量?

  • truly变量:!!val === true
  • falsely变量:!!val === false

除了falsely变量,都是truly变量

  • 数字0

  • NaN

  • 空字符串

  • null

  • undefined

演示代码

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // !!:两次取反
        console.log(!!"" === false);
        console.log(!!NaN === false);
        console.log(!!0 === false);
        console.log(!!null === false);
        console.log(!!undefined === false);
    </script>
</body>
</html>

说说原型和原型链是怎么回事

复习class基础语法

  • class
  • construct
  • extends
  • super
  • instanceof

什么是原型

image.png

什么是原型链

image.png

演示代码

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 父级
        // class:声明一个类    Person:类的名字,可以自定义,但是首字母最好大写
        class Person {
            // constructor:构造函数,声明类的时候必须要有
            constructor(name, age) {
                this.name = name;
                this.age = age;
            }

            sayHello() {
                // 这里括号的内容是用小点``包裹的,而不是用引号""
                // console.log("你好${this.name}");
                console.log(`${this.name} say hi`);
            }
        }

        // 子级继承
        // extends:继承
        class Student extends Person {
            constructor(name,age,sex) {
                // super() 是继承父级的属性,如果括号里没内容,那么将不会继承
                super(name,age);

                this.sex = sex;
            }
            
            learn() {
                console.log(
                    `我是${this.name},今年${this.age}岁,${this.sex},在学习英语`
                )
            }
        }

        // 实例化
        // let zhangsan = new Person("张三", 18);
        let zhangsan = new Student("张三", 18,"男");
        zhangsan.sayHello()
        zhangsan.learn()

        // instanceof:判断继承关系,结果是布尔值
        console.log(zhangsan instanceof Student);
        console.log(zhangsan instanceof Person);
        console.log(Person instanceof Object);
        console.log(zhangsan instanceof Object);
        console.log(zhangsan instanceof Array);

        // 原型,原型链
        console.log(zhangsan.__proto__);// 隐式原型 每个实例都有一个隐式原型
        console.log(Student.prototype);// 显式原型  每一个实例上面都有一个显式原型
        console.log(zhangsan.__proto__ === Student.prototype);
        
        // 复习class基础语法
            // ● class  // 在这里是声明一个类的作用
            // ● construct  // 构造函数,声明类的时候必须要有
            // ● extends // 继承
            // ● super   // 是继承父级的属性,如果括号里没内容,那么将不会继承
            // ● instanceof  // 判断继承关系,结果是布尔值
    </script>
</body>

</html>