为什么我们需要原型对象?大家有没有想过

246 阅读2分钟

不知道大家有没有想过原型对象的由来,相信大部分小伙伴都是知其然不知道其所以然,知道原型对象是用来存方法的,然后,没了,一起来研究一下js中为啥要有这种东西吧😂


1. 构造函数内部存在方法(方法为实例成员)

缺点:构造函数内部存在方法,创建多个实例对象时,会创建多个堆空间,出现内存浪费

   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)

思考: p1和p2都有eat方法,而是函数体相同。但是他们是同一个函数吗?

答案:不是同一个, 因为每一次调用构造函数, 内部都会执行一次function,就会在堆中开辟一个新的空间。虽然代码是一样的,但是地址不同。 就会导致每调用一次构造函数,多出一个函数堆空间。导致内存资源浪费

2. 方法放在全局中

缺点:第一步中的构造函数可以使用全局函数来代替。解决了内存浪费的问题,但是又导致了新的问题:全局变量污染

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, p2)

思考题:p1 的 eat 和 p2 的 eat 是不是同一个

答案:是的 因为构造函数内部并没有重新 function 创建一个函数,而是拷贝eat的地址赋值。 无论你调用构造函数多少次,都是拷贝eat的地址

3. 使用对象将多个方法存在一个对象中

缺点:使用对象将多个方法存在一个对象中(块级), 解决内存浪费 + 变量污染,但是这个对象它本身又成为了一个污染

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)

4. 原型对象诞生

这时就诞生了原型对象,任何函数在声明的时候,系统会自动帮你创建一个对象,称之为原型对象(由内置构造函数 Object 构建),这个对象属于构造函数的成员,不会造成变量污染和内存浪费,nice!

举个栗子(原型对象中常用来存一些所有实例都可以访问的公共方法):