• 16-js面向对象


    面向对象

    面向对象是一种编程思想,相对于面向过程而言。

    面向过程关注的是每一个元素,元素之间的关系、顺序…

    面向对象关注是找到一个对象,直接完成效果。

    一、常见创建对象的方式

    1. 构造函数方式

    调用系统内置的构造函数创建对象,new Object()

    // 创建一个对象
    const obj = new Object();
    // 动态给对象添加键值对
    obj.name = "lucy";
    obj.age = 18;
    obj.gender = '女';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    2. 字面量方式

    直接使用字面量,也就是{}

    const obj2 = {
        name:'jack',
        age:12
    }
    obj2.gender = '男';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    3. 工厂函数方式

    写一个工厂函数(普通函数),创建一个对象,可以给对象添加一些属性,可return对象

    // 工厂函数
    function createObj(name,age,gender){
        // 手动创建对象
        const obj = new Object();
        // 手动添加属性
        obj.name = name;
        obj.age = age;
        obj.gender = gender;
        // 手动return 对象
        return obj;
    }
    // 使用工厂函数创建对象
    const zhangsan = createObj('张三',12,'女');
    const lisi = createObj('李四',13,'男');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    4. 自定义函数方式

    自动创建对象,手动添加属性,自动返回对象

    // 把函数Human当构造函数调用(和new一起使用)
    const h1 = new Human('lucy',12,'女');
    
    • 1
    • 2

    只要有new连用,在函数的开头自动添加const this = new Object();.在函数结尾自动添加return this;.

    构造函数里面的this是创建好的那个对象,也可以成为实例对象。

    function Human(name,age,gender){
        // 自动创建对象,赋值给this
        // const this = new Object();
        
        //手动添加属性
        this.name = name;
        this.age = age;
        this.gender = gender;
        
        // 自动return this
        // return this;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    二、构造函数的使用注意点

    1. 与new关键字连用
    const h1 = new Human('lucy',12,'女');
    
    • 1
    2. 首字母大写

    首字母不大写,只要与new连用,就是构造函数,有创建对象的能力。

    建议构造函数的首字母大写。

    3. 传参写进()

    调用时,如果不需要传参可以不写(),建议都写上

    4. this指向实例对象

    构造函数内部的this,由于与new连用,this指的是创建好的实例对象

    5. 构造函数内部不要写return

    因为构造函数内部会自动返回一个对象:

    如果return 一个复杂数据类型(return [12,34,56];),则构造函数返回是复杂数据类型

    如果return 一个基本数据类型(return 123;),则构造函数还是返回this的实例对象

    6. 构造函数内的方法

    构造函数内部可以赋值函数,写为构造函数里面的方法。

    function Person(){
        this.name = 'jack';
        this.age = 18;
        this.sayHi = function(){
            console.log("构造函数constructor")
        }
    }
    const o1 = new Person();
    const o2 = new Person();
    // 调用构造函数里的方法
    o1.sayHi();
    o2.sayHi();
    // 两个对象中的sayHi函数占用了两个不同的内存空间
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    复杂数据类型比较的是地址

    需要一个东西,使得同一个构造函数new出来的对象,可以共用,就是原型 prototype

    三、原型 prototype

    1. 概念

    每一个函数自身带有一个成员,prototype,是一个对象空间

    function fn(){}
    console.dir(fn)
    
    • 1
    • 2

    构造函数中的原型

    function Person(){} // Person = { prototype:{}}
    
    • 1

    给这个对象动态地添加一些东西

    Person.prototype.sayHi = function(){
        console.log('hi')
    }
    
    • 1
    • 2
    • 3

    重点:

    在函数prototype中存储的内容,不是给函数使用的(函数也能用),是给函数的每一个实例对象使用的。也就是给构造函数new出来的对象使用的。

    2. 使用方法

    __proto__

    每一个对象都自带一个成员,叫做__proto__,是一个对象空间

    const obj = {name:'lucy'};
    /*
    	在浏览器中输出
    	obj={
    		name:'lucy',
    		[[Prototype]]:{}
    	}
    	// [[Prototype]]的真实名字是__proto__,是浏览器自己使用的,不希望用户去使用
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    当访问一个对象中的成员时,

    • 如果对象本身有这个成员,就会直接给结果,
    • 如果没有,就会去__proto__对象空间中找,如果有就会给结果(找不到返回undefined,参见下一文原型链)
    function Person(){
        this.name='lucy';
    	this.age = 12
    }
    
    Person.prototype.sayHi = function(){
        console.log('hello world');
    }
    
    const p1 = new Person();
    console.log(p1);
    /*
    	P1 = {
    		name:'lucy',
    		age:12,
    		__proto__=Person.prototype:{
    			sayHi:function(){}
    		}
    	}
    */
    const p2 = new Person();
    console.log(p2);
    console.log(p1.sayHi() == p2.sayHi())//true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    此时,p1 p2 使用的都是原型中的函数,比较的内存空间地址一致

    总结:

    在书写构造函数时,

    属性写在构造函数里面,如this.name = 'lucy'

    方法写在原型对象里面,如Person.prototype.sayHi = function(){}

    3. 构造函数与实例对象
    1. 数组

      const arr = new Array(1,2,3);
      const arr2 = ['hello'];
      // 数组中的所有方法,如map,forEach,filter...
      console.log(Array.prototype)
      
      Array.prototype.abc = function(){
          console.log(this);
          console.log("新添加的abc方法");
      }
      // 数组调用abc方法
      arr.abc()
      arr2.abc()
      // 原型上的方法里面的this是实例对象
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    2. 函数

      const fn = function(){alert(1)};
      function fn2(){alert(2)};
      const fn3 = new Function('alert(3)');
      fn();
      fn2();
      fn3();
      // 所有的js函数都是Function构造new出来的
      //构造函数的prototype == 它的实例对象.__proto__
      console.log(fn.__proto__ == Function.prototype) //true
      console.log(Function.__proto__ == Function.prototype) // true
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

      js中的顶级构造函数是Object

  • 相关阅读:
    MIniIO Erasure Coding 应用案例
    从零开始Blazor Server(4)--登录系统
    【洛谷题解】P2670 [NOIP2015 普及组] 扫雷游戏
    Linux网络命令——tcpdump
    记录发生同一个实体用在多个不同的controller接口展示不同的字段报空指针的问题。
    深入剖析 | 近期法院判决是不是司法部门有意平衡 SEC 监管天平
    电动汽车有序无序充放电的优化调度(Matlab代码实现)
    4.Redis的Key的操作命令
    企业级BOM系统与外部系统集成的几种方案
    minio 单机版安装
  • 原文地址:https://blog.csdn.net/qq_41570386/article/details/127910559