什么是原型(函数.prototype)

694 阅读9分钟
什么是原型(神秘对象就是函数.prototype)
1\. 原型能存储一些方法,构造函数创建的对象能够访问这些方法,原型能实现继承
2\. 在创建一个函数时候,会同时创建一个特殊的神秘对象,该对象使用函数.prototype引用,称其为函数的原型属性
3\. 创建出来的神秘对象针对于构造函数,称为构造函数的原型属性
4\. 创建出来的神秘对象针对于构造函数创建出来的实例对象,称为构造函数的原型对象
5\. 构造函数创建的实例对象直接'含有'神秘对象的方法,即原型继承
6\. 实例对象在调用当前对象的属性和方法的时候,如果当前对象中没有这些属性和方法,那么就会到原型对象中去找
# __proto__
* 以前要访问原型,必须使用构造函数来实现,无法直接使用实例对象来访问原型
* 火狐最早引入属性'__proto__'表示使用实例对象引用原型,但是早期是非标准的
* 通过该属性可以允许使用实例对象直接访问原型
* 可以使用实例对象.__proto__也可以直接访问神秘对象
* 实例对象.__proto__ == 构造函数.prototype
# 什么对象的结构
1\. 神秘对象中默认都有一个熟悉'constructor',翻译为构造器,表示该原型是与什么构造函数联系起来的。
2\. '__proto__'有什么用?
* 可以访问原型
* 在开发中除非特殊要求,不要使用实例去修改原型的成员,因此该属性开发时使用较少
* 但是在调试的过程中会非常方便,可以轻易的访问原型进行查看成员
3\. 在早期的浏览器中使用实例需要访问原型如何处理?
* 可以使用实例对象访问构造器,然后使用构造器访问原型
o.constructor.prototype
4\. 如果给实例继承自原型的属性赋值
* 会给自己添加属性 不会改变原型中的属性
* 如果访问数据,当前对象中如果没有该数据就到构造函数的原型属性中去找
#属性搜索原则
1\. 原型链
2\. 属性搜索原则
* 所谓的属性搜索原则,就是对象在访问属性和方法的时候,首先在当前对象中查找
* 如果当前对象中存在该属性或方法,停止查找,直接使用该属性与方法
* 如果对象没有该成员,那么在其原型对象中查找
* 如果原型对象含有该成员,那么停止查找,直接使用
* 如果原型还没有,就到原型的原型中查找
* 如此往复,指导找到Object.prototype还没有 就返回undefined
* 如果是调用方法就报错,该方法不是一个函数
# 原型的概念
1\. 关于面向对象的概念
* 类 class:在js中就是构造函数
* 在传统的面向对象语言中,使用一个叫做类的东西定义模板,然后使用模板创建对象
* 在构造方法中也具有类似的功能,因此称其为类
* 实例(instance)与对象(Object)
* 实例一般是指某一个构造函数创建出来的对象,我就称为某构造函数的实例
* 实例就是对象,对象是一个泛称
* 实例与对象是一个近义词
* 键值对与属性和方法
* 在js中键值对的集合称为对象
* 如果值为数据(非函数),就称该键值对为属性
* 如果值为函数(方法),就成该键值对为方法
* 父类与子类
* 传统的面向对象语言中使用类来实现继承,那么就有父类,子类的概念
* 父类又称为基类,子类又称为派生类
* 在js中常常称为父对象 子对象 即基对象 派生对象
2\. 原型相关的概念
* 神秘对象针对构造函数称为 “原型属性" (神秘对象与构造函数的关系)
* 神秘对象就是构造函数的原型属性
* 简称原型
* 神秘对象与构造函数所创建出来的对象也有一定关系 (神秘对象与构造函数创建的对象的关系)
* 关系是什么
* 在该对象访问某一个方法或属性的时候,如果该对象中没有,就会到这个神秘对象中查找
* 神秘对象针对构造函数创建出来的对象称为原型对象
* 简称原型
* 对象继承自其原型(什么是原型继承)
* 构造函数创建的对象继承自构造函数的原型属性
* 构造函数创建的对象 继承自该对象的原型对象
* 构成函数所创建出来的对象,与构造函数的原型属性表示的对象,是两个不同的对象
* 原型中的成员(无论方法和属性),可以直接被实例对象所使用
* 也就是说实例对象直接'含有' 原型中的成员
* 因此实例对象继承自原型
* 这样的继承就是‘原型继承
## JS的对象比较
由于js是解释执行的语言,那么在代码中出现函数与对象如果重复执行,会创建多个副本
1\. 由于js是解释执行的语言,
4\. 传统的构造方法的定义方式会影响性能,容易造成多个对象有多个方法副本,应该将方法单独抽取出来。
5.可以考虑将方法全部放到外面,但是有安全隐患
* 在开发中会引入多个框架或库,自定义成员越多,出现命名冲突的几率越大
* 可能在开发中会有多个构造函数,每一个构造函数应该有多个方法,那么就hi变得不容易维护
6\. 任意一个对象都会默认的链接到它的原型中
* 创建一个函数,会附带的创建一个特殊的对象,该对象使用函数.prototype引用,称其为函数的原型属性
* 每一个由该函数作为构造函数创建的对象,都会默认的链接到该对象上
* 在该对象访问某一个方法或属性的时候,如果该对象中没有,就会到这个神秘对象中查找
* 如果访问数据,当前对象中如果没有该数据就到构造函数的原型属性中去找
* 如果写数据,当对象中有该数据的时候,就是修改值。如果对象没有该数据,那么就添加值
#对象的原型链
1\. 凡是对象就有原型
2\. 原型也是对象
3\. 凡是对象向就有原型,原型又是对象,因此凡是给定义一个对象,那么就可以找到他的原型,原型还有原型,那么如此下去,就构成一个对象的序列,称该结构为原型链
#原型链结构
1\. 凡是使用构造函数,创建出对象,并且没有利用赋值的方式修改原型,就说该对象保留默认的原型链
2.默认原型链的机构
当前对象 →构造函数.prototype→Object.prototype→null
3\. 实现继承的时候,有时会利用替换原型链结构的方式实现原型继承,那么原型链结构就会发生改变
#原型式继承
1\. 所谓的原型式继承就是利用修改原型链的结构(增加一个节点,删除一个节点,修改节点中的成员)来使得实例对象可以使用整条原型链中的所有成员
2\. 使用规则必须满足属性搜索原则
#函数的构造函数Function
1\. 在js中使用Function可以实例化函数对象,在js中函数与普通对象一个也是一个对象类型,函数是js中的一等公民
2\. 函数是对象,就可以使用对象的动态特性
3\. 函数是对象,就有构造函数创建函数
4\. 函数是函数,可以创建其他对象
5\. 函数是唯一可以限定变量作用域的结构
##函数Function的实例
new Function();
1\. Function中的参数全是字符串
2\. 该构造函数的作用是将参数链接起来组成函数
* 如果参数只有一个,那么表示函数体
* 如果参数有多个,那么最后一个参数表示新函数体,前面的所有参数表示函数的新参数
* 如果没有参数,表示创建一个空函数
#arguments对象 argument(参数)
1\. arguments是一个伪数组对象,表示在函数调用的过程中传入的所有参数的集合
* 在函数调用的过程中没有规定参数的个数与类型,因此函数调用就具有灵活的特性,那么为了方便使用,
* 在每一个函数调用的过称重,函数代码体内有一个默认的对象arguments,它存储着实际传入的所有参数
* 在代码设计中,如果需要函数带有任意个参数的时候,一般就不带任何参数,所有的参数利用arguments来获取
2\. js中函数并没有规定必须如何传参,定义函数的不写参数一样可以调用时传递参数
3\. 定义的时候写了参数,调用的时候也可以不传参
4\. 定义的时候写了一个参数,调用的时候可以随意的传递多个参数
#this 指向
. 在js中使用Function可以实例化函数对象,在js中函数与普通对象一个也是一个对象类型,函数是js中的一等公民
2\. 函数是对象,就可以使用对象的动态特性
3\. 函数是对象,就有构造函数创建函数
4\. 函数是函数,可以创建其他对象
5\. 函数是唯一可以限定变量作用域的结构
#函数的原型链
1\. 任意一个函数,都是相当于Function的实例 类似于{}与new Object()的关系
2\. 函数的当成对象的时候,他的属性为__proto__
3\. 函数的构造函数是什么?Function
4\. 函数应该继承自'Function.prototype'
5\. Function.prototype 继承自 Object.prototype
6\. Object函数是大写Function的实例
7\. Object作为对象 是继承自Function.prototype的,Function.prototype继承自Object.prototype
8.Function是自己的构造函数
#对象原型
1\. 在js中任何对象的源点就是Object.prototype
2\. 在js中任何函数的源点就是Function.prototype