JS第二十次笔记

114 阅读4分钟

1.编程思想

image.png

1.1 面向过程

image.png

image.png

1.2 面向对象

image.png

image.png

2 构造函数

image.png

image.png

3 原型

image.png

3.1 原型对象

每一个构造函数都有一个原型对象叫prototype,公共属性和方法写在原型对象上,节约内存 image.png

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    //1.创建构造函数
    function Person(uname, age) {
      this.uname = uname;
      this.age = age;
    }
    //构造函数中的公共方法可以挂载在构造函数得原型对象上(函数.prototype.原型名称)
    Person.prototype.sayHi = function () {
      console.log('hi');
    }
    Person.prototype.num = 10
    //2.生成实例对象
    const obj1 = new Person('张三', 18);
    const obj2 = new Person('李四', 20);
    console.log('obj1.num, obj2.num:');
    console.log(obj1.num, obj2.num);
    console.log('obj1.sayHi(), obj2.sayHi():');
    obj1.sayHi();
    obj2.sayHi();
    console.log('obj1.sayHi === obj2.sayHi:(返回布尔值)');
    console.log(obj1.sayHi === obj2.sayHi);
  </script>

</body>

</html>

结果:

image.png

3.1.1 原型对象-this指向

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    //1.创建构造函数
    function Person(uname, age) {
      this.uname = uname;
      this.age = age;

    }
    //构造函数中的公共方法可以挂载在构造函数得原型对象上(函数.prototype.原型名称)
    Person.prototype.sayHi = function () {
      //构造函数中原型对象中的this指向了实例对象
      console.log(this === obj1);//返回Trure
    }

    //2.生成实例对象
    const obj1 = new Person('张三', 18);
    const obj2 = new Person('李四', 20);
    obj1.sayHi()

  </script>

</body>

</html>

3.1.2 案例——(给数组做原型方法)

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    const arr = [1, 8, 3]
    //需求: 给数组拓展方法最大值方法,求和方法
    //需求:给数组拓展方法,放在原型对象上(节省内存)
    // console.log(Array.prototype
    Array.prototype.max = function () {
      //构造函数的原型对象 中的this指向实例对象
      console.log('调用了', this)//this==arr 输出[1,2,3]
      return Math.max(...this)
    }
    console.log(arr.max())

![image.png](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/3890bd2cf0b24b43b2f7bcd8490fe256~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg54ix5rOh6ISa55qE6bih6IW_:q75.awebp?rk3s=f64ab15b&x-expires=1771661834&x-signature=9wz4k8B4tLagko5LPYo7%2FULsP70%3D)
    Array.prototype.sum = function () {
      return this.reduce((prev, item) => {
        return prev + item
      })

    }
    console.log(arr.sum())

  </script>
</body>

</html>

结果:

image.png

3.2 constructor属性

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    function Person(uname) {
      this.name = 'zhangsan';
    }
    //位置:
    console.log(Person.prototype.constructor === Person)//TURUE
    console.log(Person.prototype)

    //作用:constructor 属性指向构造函数
    //场景:
    //Person.prototype.fn1=function(){}
    //Person.prototype.fn2=function(){}
    //Person.prototype.fn3=function(){}

    //等价于以下:
    Person.prototype = {
      constructor: Person,
      fn1: function () { },
      fn2: function () { },
      fn3: function () { }

    }
    console.log(Person.prototype)
    const mc = new Person('mc')
  </script>


</body>

</html>

3.3 原型

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    function Person(uname) {
      this.uname = uname;
    }
    const mc = new Person('mc');
    //每一个对象都有自己的__proto__(原型),指向构造函数的原型对象(prototype)
    console.log(Person.prototype)
    console.log(mc.__proto__)//ECMAscript2015将__proto__改成了prototype(规范化)
    console.log(mc.__proto__ === Person.prototype)//true
  </script>
</body>

</html>

image.png

3.4 (构造函数-原型对象-实例对象)三者的关系

image.png

image.png

image.png

image.png 示例代码:

function Person(name, age) {
    this.name = name;
    this.age = age;
}

// 添加一个方法到原型对象
Person.prototype.sayHello = function() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

// 创建实例对象
const person1 = new Person("Alice", 25);
const person2 = new Person("Bob", 30);

// 访问实例对象的属性和方法
console.log(person1.name); // 输出:Alice
console.log(person2.age);  // 输出:30
person1.sayHello();        // 输出:Hello, my name is Alice and I am 25 years old.
person2.sayHello();        // 输出:Hello, my name is Bob and I am 30 years old.

// 检查原型链
console.log(person1.__proto__ === Person.prototype); // 输出:true
console.log(Person.prototype.constructor === Person); // 输出:true

3.5 原型链

image.png

image.png

3.6 原型链--instanceof运算符

作用:用来检测构造函数.prototype是否存在于实例对象的原型链上

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    function Person(uname) {
      this.uname = uname;
    }
    const mc = new Person('mc');
    console.log(mc instanceof Person);//True
    console.log(mc instanceof Object);//True
    console.log('======')
    arr = []
    console.log(arr instanceof Array);//True
    console.log(arr instanceof Object);//True
  </script>

</body>

</html>

3.7 原型继承

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    //需求:使用js完成继承功能
    //1.封装=>公共的对象,存储公共属性和方法
    const Person = {
      eyes: 'everyone has 2 eyes,either i',
      eat() {
        console.log('我会吃饭');
      }
    }
    function Man() {

    }
    function Woman() {

    }

    //2.继承=>让Man和Woman继承person的属性和方法
    Man.prototype = Person;
    Woman.prototype = Person;

    //3.验证 让Man和Woman的实例对象能不能访问eyes和eat方法
    const xm = new Man('小明');
    console.log(xm);
    console.log(xm.eyes);
    xm.eat();
    const xh = new Woman('小红');
    console.log(xh);
    console.log(xh.eyes);
    xh.eat();
  </script>
</body>

image.png

3.7.1 原型继承问题

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    //需求:使用js完成继承功能
    //1.封装=>公共的对象,存储公共属性和方法
    const Person = {
      eyes: 'everyone has 2 eyes,either i',
      eat() {
        console.log('我会吃饭');
      }
    }
    function Man() {

    }
    function Woman() {

    }

    //2.继承=>让Man和Woman继承person的属性和方法
    Man.prototype = Person;
    Woman.prototype = Person;


    //4. 问题:我们给man构造函数追加一个新方法=>hejiu
    Man.prototype.hejiu = function () {
      console.log('我会喝酒');
    }
    //原本只想追加给小明,但却给所有实例对象添加了=>hejiu这个方法
    //原因:小明和小红都同时使用了一个对象,根据引用类型的特点,他们指向同一个对象,修改一个就会都被影响到(对象不独立)
    //3.验证 让Man和Woman的实例对象能不能访问eyes和eat方法
    const xm = new Man('小明');
    const xh = new Woman('小红');
    xm.hejiu();//会
    xh.hejiu();//会
  </script>
</body>

</html>

3.7.2 原型继承问题的解决

image.png

image.png

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    //需求:使用js完成继承功能
    //1.封装=>公共的对象,存储公共属性和方法
    //解决1.封装=>公共属性和方法放在一个构造函数中
    //构造函数创建的对象是互不影响的
    function Person() {
      this.eyes = 'solve everyone has 2 eyes,either i'
    }
    Person.prototype.eat = function () {
      console.log(' solve everyone can eat')
    }

    //解决:创建构造函数
    function Man(uname) {
      this.uname = uname
    }
    function Woman(uname) {
      this.uname = uname
    }


    //2.继承=>让Man和Woman继承person的属性和方法
    //解决2.继承=>让Man和Woman继承person的属性和方法

    Man.prototype = new Person();
    Woman.prototype = new Person();
    console.log(Man.prototype === Woman.prototype);//False


    //4. 问题:我们给man构造函数追加一个新方法=>hejiu
    Man.prototype.hejiu = function () {
      console.log('我会喝酒');
    }
    //原本只想追加给小明,但却给所有实例对象添加了=>hejiu这个方法
    //原因:小明和小红都同时使用了一个对象,根据引用类型的特点,他们指向同一个对象,修改一个就会都被影响到(对象不独立)
    //3.验证 让Man和Woman的实例对象能不能访问eyes和eat方法
    const xm = new Man('小明');
    const xh = new Woman('小红');

    console.log(xm);
    console.log(xh);
  </script>
</body>

</html>

image.png

image.png