什么是原型(函数.prototype)

我心飞翔 分类:javascript

什么是原型(神秘对象就是函数.prototype)

  1. 原型能存储一些方法,构造函数创建的对象能够访问这些方法,原型能实现继承
  2. 在创建一个函数时候,会同时创建一个特殊的神秘对象,该对象使用函数.prototype引用,称其为函数的原型属性
  3. 创建出来的神秘对象针对于构造函数,称为构造函数的原型属性
  4. 创建出来的神秘对象针对于构造函数创建出来的实例对象,称为构造函数的原型对象
  5. 构造函数创建的实例对象直接'含有'神秘对象的方法,即原型继承
  6. 实例对象在调用当前对象的属性和方法的时候,如果当前对象中没有这些属性和方法,那么就会到原型对象中去找

proto

  • 以前要访问原型,必须使用构造函数来实现,无法直接使用实例对象来访问原型
  • 火狐最早引入属性'proto'表示使用实例对象引用原型,但是早期是非标准的
  • 通过该属性可以允许使用实例对象直接访问原型
  • 可以使用实例对象.__proto__也可以直接访问神秘对象
  • 实例对象.proto == 构造函数.prototype

什么对象的结构

  • 神秘对象中默认都有一个熟悉'constructor',翻译为构造器,表示该原型是与什么构造函数联系起来的。

'proto'有什么用?

  • 可以访问原型* 在开发中除非特殊要求,不要使用实例去修改原型的成员,因此该属性开发时使用较少
  • 但是在调试的过程中会非常方便,可以轻易的访问原型进行查看成员

在早期的浏览器中使用实例需要访问原型如何处理?

  • 可以使用实例对象访问构造器,然后使用构造器访问原型o.constructor.prototype

如果给实例继承自原型的属性赋值

  • 会给自己添加属性 不会改变原型中的属性
  • 如果访问数据,当前对象中如果没有该数据就到构造函数的原型属性中去找

原型链属性搜索原则

  • 所谓的属性搜索原则,就是对象在访问属性和方法的时候,首先在当前对象中查找
  • 如果当前对象中存在该属性或方法,停止查找,直接使用该属性与方法
  • 如果对象没有该成员,那么在其原型对象中查找
  • 如果原型对象含有该成员,那么停止查找,直接使用
  • 如果原型还没有,就到原型的原型中查找
  • 如此往复,指导找到Object.prototype还没有 就返回undefined
  • 如果是调用方法就报错,该方法不是一个函数

原型的概念

  1. 关于面向对象的概念
    • 类 class:在js中就是构造函数
    • 在传统的面向对象语言中,使用一个叫做类的东西定义模板,然后使用模板创建对象
    • 在构造方法中也具有类似的功能,因此称其为类
    • 实例(instance)与对象(Object)
    • 实例一般是指某一个构造函数创建出来的对象,我就称为某构造函数的实例
    • 实例就是对象,对象是一个泛称
    • 实例与对象是一个近义词
    • 键值对与属性和方法
    • 在js中键值对的集合称为对象
    • 如果值为数据(非函数),就称该键值对为属性
    • 如果值为函数(方法),就成该键值对为方法

    父类与子类

    • 传统的面向对象语言中使用类来实现继承,那么就有父类,子类的概念
    • 父类又称为基类,子类又称为派生类
    • 在js中常常称为父对象 子对象 即基对象 派生对象

    原型相关的概念

    • 神秘对象针对构造函数称为 “原型属性" (神秘对象与构造函数的关系)
    • 神秘对象就是构造函数的原型属性* 简称原型
    • 神秘对象与构造函数所创建出来的对象也有一定关系 (神秘对象与构造函数创建的对象的关系)

    关系是什么

    • 在该对象访问某一个方法或属性的时候,如果该对象中没有,就会到这个神秘对象中查找
    • 神秘对象针对构造函数创建出来的对象称为原型对象 简称原型

    对象继承自其原型(什么是原型继承)

    • 构造函数创建的对象继承自构造函数的原型属性
    • 构造函数创建的对象 继承自该对象的原型对象
    • 构成函数所创建出来的对象,与构造函数的原型属性表示的对象,是两个不同的对象
    • 原型中的成员(无论方法和属性),可以直接被实例对象所使用
    • 也就是说实例对象直接'含有' 原型中的成员
    • 因此实例对象继承自原型
    • 这样的继承就是‘原型继承

    JS的对象比较由于js是解释执行的语言,那么在代码中出现函数与对象如果重复执行,会创建多个副本

    1. 由于js是解释执行的语言,
    2. 传统的构造方法的定义方式会影响性能,容易造成多个对象有多个方法副本,应该将方法单独抽取出来。
    3. 可以考虑将方法全部放到外面,但是有安全隐患
      • 在开发中会引入多个框架或库,自定义成员越多,出现命名冲突的几率越大
      • 可能在开发中会有多个构造函数,每一个构造函数应该有多个方法,那么就hi变得不容易维护
    4. 任意一个对象都会默认的链接到它的原型中
      • 创建一个函数,会附带的创建一个特殊的对象,该对象使用函数.prototype引用,称其为函数的原型属性
      • 每一个由该函数作为构造函数

回复

我来回复
  • 暂无回复内容