构造函数,原型对象,实例对象的关系

构造函数,原型对象,实例对象的关系

1.首先声明多个对象

//声明三个对象
let p1={
name:'张三',
age:20,
sex:'男
}
let p2={
name:'李四',
age:25,
sex:'男'
}
let p3=[
name:'李华'
age:18,
sex:'女'
}

用以上方式一个个声明对象,代码过于冗余,所有我们需要用函数对他们进行封装,这样我们就引出了工厂函数

2.工厂函数:用于创建多个对象

 function createPerson(name,age,sex){
            //1.创建对象
            let p = {}
            //2.给对象赋值
            p.name = name
            p.age = age
            p.sex = sex
            //3. 返回对象
            return p
        }

        let p1 = createPerson('张三',20,'男')
        let p2 = createPerson('李四',22,'女')
        console.log(p1,p2)

封装一个函数后,这样不管我们以后要创建多少个对象,都只需要传入实参调用这个工厂函数,就可以创建很多的对象,可以把它看成一个加工厂,但是我们有更加简洁的方式来实现这个功能,那就是构造函数

3.构造函数:构造函数的作用和工厂函数一致,都是用来创建对象的,但是代码更加简洁,使用new关键字调用一个函数,这个函数称为构造函数

构造函数new工作原理(4个步骤)

(1)创建一个空对象
(2)this指向这个对象
(3)给这个对象赋值
(4)返回这个对象
 function Person(name,age,sex){
            //(1)创建空对象   {}
            //(2)this指向这个对象  this = {}
            //(3)对象赋值
            this.name = name
            this.age = age
            this.sex = sex
            //(4)返回这个对象 return this
        }

        let p1 = new Person('张三',20,'男')
        console.log(p1)

4.实例对象:用new关键字调用函数返回的对象称为实例对象

let p1 = new Person('张三',20,'男')

这个对象是用new关键字调用函数返回的对象,称为实例对象,被调用的函数称为构造函数,
我们已经知道实例对象和构造函数,接下来说明一下什么是原型对象

5.原型对象:任何函数在声明的时候,系统都会自动帮你创建一个对象,称为原型对象

那我们为什么要使用原型对象,原型对象的作用又是什么,
首先来解决一下构造函数在使用的时候存在的问题

  function Person(name,age){
            this.name = name
            this.age = age
            this.eat = function(){
                console.log('eat');

            }
        }

        let p1 = new Person('张三',18)
        let p2 = new Person('李四',20)
        console.log( p1,p2)
 console.log( p1.eat == p2.eat )//false

此时p1和p2都有eat方法,而且函数体相同.但是他们是同一个函数?
答案是否定的,因为每调用一次构造函数,内部都会执行一次function,函数的数据类型是引用类型,它会在堆地址中开辟一个新的空间,虽然代码是一样的,但是地址不同,就会导致每调用一次构造函数,就会多出一个函数堆空间,导致内存资源浪费,此时我们可以使用全局函数来解决内存资源浪费问题

  let eat = function() {
          console.log("吃东西")
        }

        let learn = function() {
          console.log("学习")
        }

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

        let p1 = new Person("张三", 18)
        let p2 = new Person("李四", 20)
 console.log( p1.eat == p2.eat )//true

此时p1和p2的eat方法是一样的,因为构造函数在调用的时候,构造函数内部并没有重新创建一个函数,而是拷贝eat的地址赋值,无论我们调用多少次,拷贝的都是地址,而不是在内存中重新开辟空间,这样就解决内存的浪费,但同时又会诞生一个新的问题,那就是在全局中声明太多的函数,变量名太多,可能会导致变量的全局污染,为了解决这个问题, 我们可以将这些函数加到一个新建的对象中

let obj = {
        eat: function() {
          console.log("吃东西")
        },
        learn: function() {
          console.log("学习")
        }
      }

      function Person(name, age) {
        this.name = name
        this.age = age
        this.eat = obj.eat
        this.learn = obj.learn
      }

      let p1 = new Person("张三", 18)
      let p2 = new Person("李四", 20)
      console.log(p1, p2)

这样我们就可以引出原型对象,而不需要我们自己去创建一个新对象来保护变量污染

5.1原型对象的作用:解决构造函数造成的内存浪费和变量污染


      //构造函数
      function Person(name, age) {
        this.name = name
        this.age = age
      }

      //原型对象
      console.log(Person.prototype)
      Person.prototype = {
        eat: function() {
          console.log("吃东西")
        },
        learn: function() {
          console.log("学习")
        }
      }

      //实例对象 
      let p1 = new Person('张三',20)
      console.log( p1 )

      let p2 = new Person('李四',22)
      console.log( p1.eat == p2.eat )//true
      p1.eat()//p1.__proto__.eat()     控制台打印吃东西
      console.log(Person.prototype.constructor)//Person

构造函数在声明的时候,系统会帮我们自动创建一个对象,称为原型对象,构造函数中有一个prototype指向这个原型对象,
本来构造函数里面是没有eat这个方法的,但是p1却可以调用它,这是因为构造函数的原型有这个方法,所以p1可以调用,
实例对象中有一个隐式原型__proto__指向原型对象,而原型对象中有constructor属性指向构造函数,所以我们可以总结一下三者之间的关系
原型对象相关三个属性 : 描述 构造函数、原型对象、实例对象三者关系
prototype : 属于构造函数, 指向原型对象
proto : 属于实例对象,指向原型对象
constructor : 属于原型对象,指向构造函数

验证 构造函数、原型对象、实例对象三者关系

 console.log( p1.__proto__.constructor )//Person
 console.log( Person.prototype === p1.__proto__ )//true

在这里插入图片描述

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值