一、JavaScript 原型
原型的概念
- 在JavaScript中,函数本身也是一个包含了方法和属性的对象
- 每个函数中都有一个prototype属性,该属性引用的就是原型对象
- 原型对象是保存共享属性值和共享方法的对象
为对象扩展属性
- 扩展单个对象的成员
- 扩展共享的属性值
- 内存图描述
删除属性
- 可以使用delete关键字删除对象的属性
自由属性与原型属性
- 自有属性:通过对象的引用添加的属性;其它对象可能无此属性;即使有,也是彼此独立的属性
emp1.job = ‘Coder‘;
- 原型属性:从原型对象中继承来的属性,一旦原型对象中属性值改变,所有继承自该原型的对象属性均改变
Emp.prototype.dept = ‘研发部‘;
- 自有属性重写原型属性
- 使用hasOwnProperty()检测对象是否具备指定自有属性:
- 使用in检测对象及其原型链中是否具备指定属性:
对象的prototype属性
- 自定义对象的prototype属性
- new 创建的对象使用构造函数的 prototype 作为原型
- 对象直接量的原型为 Object.prototype
- 内置对象的prototype属性
- Array 对象
- Boolean 对象
- Date 对象
- Number 对象
- String 对象
获取原型
- 可通过两种方式获得对象的原型,进而设置共享属性
- 使用构造函数的prototype属性
比如: Emp.prototype
- 使用专门的getPrototypeOf方法
比如: Object.getPrototypeOf(obj)
- 例如:为两个Emp对象指定相同的部门属性值
原型链
- 其实,JavaScript中,原型对象本身也有原型
- 构造函数的原型对象中也有一个__proto__属性
- 原型对象中的__proto__属性,默认指向Object类型的原型对象----Object.prototype
- Object.prototype是所有对象的原型。其中包含了所有对象所共有的属性和方法。比如:toString方法
- 事实上,所有对象通过__proto__属性的引用关系,都可以直接或间接的引用到Object.prototype对象
- 我们将使用对象的__proto__属性,形成的逐级引用的关系,称为原型链
- 内存图描述
二、JavaScript 继承
继承的几种实现方式
- JavaScript中主要通过原型实现继承
- 通过原型实现继承主要有以下两种方式:
- 修改构造函数的原型,为该构造函数创建的对象指定统一的父级对象
语法: 构造函数.prototype = 父级对象;
- 单独修改一个对象的原型,而不影响其他对象的原型
语法: Object.setPrototypeOf(子类,父级对象);
如何实现继承
- 修改构造函数的原型,为该构造函数创建的对象指定统一的父级对象
- 注意:
- 凡修改原型后,用此构造函数创建的新对象,均引用新原型
- 修改原型之前,用此构造函数创建的对象,将无法使用新的原型,而依然使用旧的原型。因此被孤立
- 也可以修改单个对象的原型,而不影响其他对象的原型
- 仅影响当前对象的继承关系。不影响其它对象
检查对象的原型isPrototypeOf()
- isPrototypeOf()方法用于判定一个prototype对象是否存在于另一个对象的原型链中。如果是,返回true,否则返回false
只继承于原型
- 出于效率考虑,尽可能地将可重用的属性和方法添加到原型中去。
- 不要单独为继承关系创建新对象
- 尽量减少运行时方法搜素,例如toString()方法
继承于扩展
- JavaScript 是面向对象的语言,但与Java、C#等面向对象的语言不通,ECMAScript5中没有定义类(class)的语法,也不会通过类来创建对象
- JavaScript中的继承基于prototype,而不是是基于类
总结:本章内容主要介绍了 JavaScript 原型与继承