原型与原型链

JavaScript函数高级

原型的概念

  1. 函数的prototype属性
    每个函数都有一个prototype属性,它默认指向一个Object空对象(即没有我们定义的属性或方法的对象,也称为原型对象)。
    原型对象中有一个constructor属性,指向该函数对象。
    函数的原型属性

  2. 给构造函数添加属性
    给构造函数的原型对象添加属性(一般是方法),实例对象可以访问到。

显示原型与隐式原型

  • 每个函数都有一个显式原型属性,即prototype属性
  • 每个实例对象都有一个隐式原型属性,即__proto__属性,实例对象包括:
    函数
    所有函数都是Function的实例,创建函数时执行语句:this.peototype={}
    对象
    创建对象时执行语句:this.proto=构造函数.protottype
  • 对象的隐式原型的值为其对应的构造函数的显式原型的值。
  • 内存结构
  1. 定义函数
    在堆内存,开辟两块内存空间:
    一块内存空间保存该函数对象,这个函数对象有一个默认的prototype属性,属性值是一个地址值,这个地址指向该函数对象的原型对象。
    一块内存空间保存一个空的Object对象,即原型对象。
    在栈内存,开辟一块内存空间:
    保存函数标识的变量,值是一个地址值,这个地址值指向堆内存中的函数对象。
  2. 创建实例
    在堆内存,开辟一块内存空间:
    保存该实例对象,该实例对象有一个隐含的__proto__属性,属性值是一个地址值,这个地址值指向其构造函数的原型对象。
    在栈内存,开辟一块内存空间:
    保存实例对象的标识的变量,值是一个地址值,这个地址值指向堆内存中的实例对象。
  3. 给原型添加方法
  4. 通过实例对象调用原型对象的方法
    内存结构图:
    内存结构图
  • 总结
    1、函数的prototype属性:
    是在定义函数时浏览器自动为其添加的,默认值是一个空的Object对象,即原型对象。
    浏览器的隐含操作:this.prototype={}
    2、对象的__proto__属性:
    是在创建对象时自动添加的,默认值为其构造函数的prototype属性值
    3、程序员(我们)可以直接操作显式原型,但不能操作隐式原型(ES6之前)

原型链

  • 原型链
    1. 原型对象的原型
      原型对象也有原型,可以通过__proto__属性访问。
      Object对象的原型对象的隐式原型属性__proto__的值是null。(原型链的尽头)
    2. 别名:
      隐式原型链
    3. 原型链的尽头:
      Object对象的原型对象
    4. 访问一个对象的属性时
      (1)先在对象自身的属性中查找,找到返回
      (2)如果没有,则沿着__proto__属性依次沿着原型对象的原型向外查找,找到返回
      (3)如果最终没找到,则返回undefined
    5. 原型链的作用:
      查找对象的属性和方法。
    6. 原型链的内存结构图
      原型链
  • 构造函数、原型、实例对象的关系
var o1 = new Object();
var o2 = {};

函数、原型、实例对象的关系

  • 函数、原型、实例对象的关系2
    1. 所有函数对象是Function对象的实例,所有函数都既有显式原型属性prototype又有隐式原型属性__proto__
    2. 构造函数的显式原型属性与隐式原型属性都指向它自己的原型对象。
    3. 所有函数的隐式原型属性都指向同一个对象,即Function对象的原型对象。(因为任何函数实质上都是通过new Function()的方式创建的)
function Foo(){  }

函数、原型、实例对象的关系2

  • 原型链补充
    1. 函数的显式原型指向的对象:默认是空的Object实例对象,也就是它自己的原型对象(但Object对象不满足)
      在这里插入图片描述

    2. 所有函数都是Function对象的实例,包括Function本身
      在这里插入图片描述

    3. Object对象的原型对象是原型链尽头,因为Object的原型对象的隐式原型__proto__的值是null
      在这里插入图片描述

    4. Object>Function>其他对象

  • 原型继承
    构造函数的实例对象自动拥有构造函数的原型对象的属性(方法)
  • 原型属性问题
    1. 读取对象的属性值时: 会自动到原型链中查找
    2. 设置对象的属性值时: 不会查找原型链, 如果当前对象中没有此属性, 直接添加此属性并设置其值
    3. 方法一般定义在原型中, 属性一般通过构造函数定义在对象本身上

探索instanceof

  • instanceof运算符用于判断一个对象是否是构造函数的实例。
  • 表达式:A instanceof B
    执行流程:通过__proto__属性查找A对象的原型链,如果B函数的显式原型对象在A对象的原型链上,则返回true。
  • 案例1:
    案例1
    查找流程
  • 案例2:
    案例2
    查找流程

面试题

  • 测试题1:
    测试题1
  • 测试题2:

测试题2

(完)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值