JavaScript 是一门集成了函数编程和面向对象编程的动态语言。它的对象是一个容器,封装了属性(property)和方法(method)。JavaScript的面向对象实现不是基于类,而是基于构造函数(constructor)和原型链(prototype)实现的。
一.继承概述
- 本文主要介绍了原型对象,prototype 属性,原型链,constructor 属性。
- 原型对象介绍? 使用构造函数创建对象实例的时候,系统会维护一个原型对象,构造函数的
prototype
属性指向此对象,此对象的所有属性和方法都会被所有实例共享。实例无prototype
属性,打印出是undefined
。具体见: 原型对象概述 - 原型链介绍? 构造函数中的
prototype
属性原型对象指向自己,若无其它继承关系其的原型对象就指向Object
,Object
原型对象指向null
。具体见: 原型链 - constructor属性定义在哪里?有什么作用? constructor属性定义在prototype对象中,默认指向prototype对象所在的构造函数。其的作用是标明某个实例对象,是哪一个构造函数产生的。
二.原型对象的概述
1.原型对象概述
- 使用构造函数创建的实例之间是无法共享属性的,所以需要
JavaScript
的原型对象(prototype)来共享实例。 - 原型对象,就是定义所有实例对象共享的属性和方法。而实例对象可以视作从原型对象衍生出来的子对象。使用这种方式实现继承。
2.prototype 属性的作用
-
设计思想:JavaScript 继承机制的设计思想就是,原型对象的所有属性和方法,都能被实例对象共享。
function f() {} typeof f.prototype // "object"
-
定义:JavaScript 规定,每个函数都有一个prototype属性,指向一个对象。 对于普通函数来说,该属性基本无用。但是,对于构造函数来说,生成实例的时候,该属性会自动成为实例对象的原型。
//为原型对象添加一个color,所有实例共享此属性 function Animal(name) { this.name = name; } Animal.prototype.color = 'white'; var cat1 = new Animal('lip'); var cat2 = new Animal('tom'); cat1.color // 'white' cat2.color // 'white'
-
特性:
①
原型对象的属性不是实例对象自身的属性。只要修改原型对象,变动就立刻会体现在所有实例对象上。②
读取对象的某个属性时,JavaScript 引擎先寻找对象本身的属性,如果找不到,就到它的原型去找,如果还是找不到,就到原型的原型去找。如果直到最顶层的Object.prototype还是找不到,则返回undefined。③
如果对象自身和它的原型,都定义了一个同名属性,那么优先读取对象自身的属性,这叫做“覆盖”(overriding)。//一. 属性共享 //原型定义属性 Animal.prototype.color = 'yellow'; cat1.color // "yellow" cat2.color // "yellow" //原型定义方法 Animal.prototype.walk = function () { console.log(this.name + ' is walking'); }; //二. 实例中定义相同属性,将不再获取原型中的属性 cat1.color = 'black'; cat1.color // 'black' cat2.color // 'yellow' Animal.prototype.color // 'yellow';
三.原型链
1.原型链概述
- JavaScript 规定,所有对象都有自己的原型对象(prototype)。相应的原型对象也将有自己的原型对象,这样就形成了“原型链”(prototype chain)。
2.原型链的继承关系
-
构造函数
prototype
指向的对象原型是本身对象,若无其他继承关系,则对象的顶层原型是Object.prototype
,所有对象都继承了Object中的valueOf
和toString
方法。Object.prototype
的原型是null
,其没有任何属性和方法,原型链的尽头就是null
。//一. Animal的原型对象是Animal Animal.prototype//Animal //二. 返回Animal原型对象的原型对象是Object var pr = Object.getPrototypeOf(Animal.prototype);//Object //三. Object.prototype对象的原型是null,由于null没有任何属性,所以原型链到此为止。Object.getPrototypeOf方法返回参数对象的原型 Object.getPrototypeOf(Object.prototype) // null
四.prototype对象的constructor 属性
1.constructor介绍
-
prototype
对象有一个constructor
属性,默认指向prototype
对象所在的构造函数。constructor
属性,可以被此原型对象的所有子类继承。//一. 原型对象中的prototype函数指向构造函数 function P() {} P.prototype.constructor === P // true //二. 可被所有实例继承 function P() {} var p = new P(); p.constructor === P // true p.constructor === P.prototype.constructor // true p.hasOwnProperty('constructor') // false
2.constructor
作用
-
constructor
作用是标明实例生成的构造函数。描述了原型对象与构造函数之间的关联关系function F() {}; var f = new F(); f.constructor === F // true f.constructor === RegExp // false
-
获取构造函数的名称
function Foo() {} var f = new Foo(); f.constructor.name // "Foo"