javaScript原型

JavaScript原型

1.前言

  1. 构造函数的执行

    • 构造函数通过new关键字调用的执行过程;
      • new关键字调用构造函数后会创建一个空对象;
      • 同时将这个空对象赋值给this(即:this指向该空对象);
      • this追加属性;
      • Fn.prototype赋值给p1.__proto__;

对象是引用数据类型,赋值只能将地址赋值给另一个变量,即:将对象的地址赋值给this

let isThis = undefined;
function Fn(age) {
this.age = age;
isThis = this;
}

const p1 = new Fn(15);// p1接收空对象
console.log('isThis:', isThis === p1);// => true
console.log('proto1:', Fn.prototype === p1.__proto__);// =>true
console.log('proto2:', Fn.prototype === Object.getPrototypeOf(p1));// =>true
console.log('proto2:', p1.__proto__ === Object.getPrototypeOf(p1))// =>true
  1. 什么是原型

    1. 几乎每个JavaScript 对象都有另一个与之关联的对象。另一个对象被称为原型(prototype)
    2. 函数的原型称为显示原型(prototype)
    3. 简单对象的原型称为隐式原型(__proto__)
    1. 所有引用类型数据都称之为对象(函数,数组,对象)
    2. 原型(prototype)是一个对象
    3. Object不具有Object.prototype属性
    4. 函数名为Fn获取原型的方法为 Fn.prototype
    5. 对象p1获取原型的方法:
      1. 非标准(浏览器自带): P1.__proto__
      2. 标准:Object.getPrototypeOf(p1)
  2. 为什么需要原型?

    1. 当想要调用某个对象身上的方法或属性时,如果该对象身上没有该方法和属性,就会去原型身上查找;
  3. 节约内存(下文有体现)

  4. constructor

    1. constructor是原型上的一个属性,它的值指向原型的创建对象

      constructor是一个对象,存放的是Fn函数的地址

      let isThis = undefined;
      function Fn(age) {
          this.age = age;
          isThis = this;
      }
      console.log('constructor:', Fn.prototype.constructor)// =>
      /* 
      constructor: ƒ Fn(age) {
          this.age = age;
          isThis = this;
      }
      */
      console.log('constructor:', Fn.prototype.constructor === Fn)// =>true
      

2.原型的内存表现

  1. 定义一个构造函数

    复杂数据类型是存储在堆内存中(引用数据类型,引用内存地址)

    示例代码:

    function Fn() {
    
    }
    

    因为Fn是一个对象,所有它有prototype属性,又因prototype存放的是一个对象的地址,所以Fn.prototype指向该对象,又因为constructor指向Fn,所以存放的是Fn的地址

    内存表现:
    在这里插入图片描述

  2. 使用 new关键字创建实例对象 p1,p2

    示例代码:

    function Fn(name, age) {
        this.name = name;
        this.age = age;
    }
    p1 = new Fn('why', 18);
    p2 = new Fn('ty', 20);
    
    • 当使用new关键字调用Fn创建p1p2时,就会如前言(构造函数的执行)进行执行

    • Fn.prototype === p1.__proto__是因为他们指向同一个内存空间

    内存表现:
    在这里插入图片描述

  3. 给构造函数Fn的原型上添加方法

    示例代码:

    function Fn(name, age) {
        this.name = name;
        this.age = age;
    }
    //添加方法   
    Fn.prototype.vue = function () {
        console.log('computed')
    }
    
    p1 = new Fn('why', 18);
    p2 = new Fn('ty', 20);
    p1.vue()// => computed
    p2.vue()// => computed
    

    如果将vue方法放在Fn对象身上(this.vue===function(){console.log(‘computed’)});

    1. 即每一个new出来的对象都会拥有该方法,就会浪费内存和影响性能
    2. 如果某一些对象不需要该方法也会强制进行添加该方法

    外什么要将方法添加到原型上?

    1. 可知,Fn.prototype是一片公共空间,而p1,p2都可以通过__proto__进行访问,
    2. 如果p1想要使用vue方法,可直接通过p1.vue()进行调用,如果p1身上没有vue方法就会去p1.__proto__上去查找

    内存表现:
    在这里插入图片描述

  4. 在原型和实例上分别添加属性:

    示例代码:

    function Fn(name, age) {
        this.name = name;
        this.age = age;
    }
    Fn.prototype.vue = function () {
        console.log('computed');
    }
    Fn.prototype.state = 'China';
    
    p1 = new Fn('why', 18);
    p2 = new Fn('ty', 20);
    
    p1.__proto__.info = 'Chinese'//等价于 Fn.prototype.info
    p1.height = 1.88;
    p2.isAdmin = true;
    
    p1.vue()// => computed
    p2.vue()// => computed
    

    内存表现:

    在这里插入图片描述

注:
上图有误p1和p2长度因该为3;

  1. 查看属性:

    示例代码:

    function Fn(name, age) {
        this.name = name;
        this.age = age;
    }
    Fn.prototype.vue = function () {
        console.log('computed');
    }
    Fn.prototype.state = 'China';
    
    p1 = new Fn('why', 18);
    p2 = new Fn('ty', 20);
    
    p1.__proto__.info = 'Chinese'
    p1.height = 1.88;
    p2.isAdmin = true;
    
    p1.vue()// => computed
    p2.vue()// => computed
    
    console.log(p1.state = '中国');
    console.log('p1:', p1)
    console.log(p2.state)// => 'China'
    
    
    console.log(p1.state = '中国');//
    console.log('p1:', p1)
    

    原本p1是没有state属性的,只有原型上有,所以执行p1.state = '中国'并不是对p1的属性进行修改,而是在给p1对象添加state属性并赋值为’中国’

    console.log(p2.state)
    

    因为p2对象本身是没有state属性的,所有p2.state访问的是原型身上的state属性()

    当想要调用某个对象身上的方法或属性时,如果该对象身上没有该方法和属性,就会去原型身上查找

    内存表现:

在这里插入图片描述

注:
上图有误p1长度为4,p2长度为3;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值