每次遇到JS面对对象这个概念,关于继承及原型,脑海里大概有个知识框架,可是很不系统化,复习下,将其系统化,内容涉及到对象的建立,原型链,以及继承。框架
两种经常使用方式,其他的比较少见
工厂模式:函数
function createObject(){ var o = {} o.name = "Nico" o.age = 8 o.sayName = function(){ alert(this.name) } return o }
这种方式比较不开门见山,比较直接的事第二种,构造函数方式this
function Object(name, age){ this.name = name this.age = age this.sayName = function(){ alert(this.name) } }
一般使用第二种,比较直观
考虑到函数也是对象的一种,每次对象的实例化中其方法也会跟随着实例化一次,为了解决这个问题,所以出现了组合构造原型模式,这是最经常使用的一种方式。spa
组合构造原型模式prototype
function Object(name, age){ this.name = name this.age = age } Object.prototype.sayName = function(){ alert(this.name) }
将自身属性于构造函数中定义,公用的方法绑定至原型对象上指针
原型对象的解释
每个函数建立时自己内部会有一个固有的原型对象,能够经过 函数名.prototype 去访问,而其原型对象又有一个属性constructor指针指向该函数。
假设有一个构造函数code
function Person(){ this.name = "Nicholas" this.age = 29 this.job = "Software Engineer" } Person.prototype.sayName = function(){ alert(this.name) } var person1 = new Person() var person12 = new Person()
其原型对象、构造函数、实例之间的关系以下对象
构造函数能够经过Person.prototype来访问原型对象,可是实例是没有办法来访问原型对象的,可是在Firefox、Chrome、Safari的每个实例对象都有一个_proto_的属性进行访问其原型继承
原型链:
根据以上的原型关系能够发现,实例先从自身定义的属性及方法中取值,若没法寻找到,则向上一级即原型对象访问须要的属性及方法,若其原型对象是另外一个对象的实例,仍没法访问到属性与方法的话,再继续向该实例的原型对象访问,这样就构成了一个原型链,也是继承的实现方式。图片
有以下两个对象
function SuperType(){ this.property = true } SuperType.prototype.getSuperValue = function(){ return this.property } function SubType(){ this.subproperty = false } SubType.prototype = new SuperType() SubType.prototype.getSubValue = function(){ return this.subproperty } var instance = new SubType() alert(instance.getSubValue()) // false
这是一个简单的继承实现方式,子类SubType具备了父类的property属性,同时也具备getSubValue的方法。
其原型链以下:
可是这样作会将父类的属性绑定至子类的原型上,若是父类具备按引用访问的数据时,子类的某一个实例中该数据的变化会致使全部子类实例该数据的变化,所以改进为借用构造函数模式的继承
function SubType(){ SuperType.call(this) this.subproperty = false }
这样就解决了该问题,将property属性定义在了子类构造函数上,子类实例访问时先从该自己构造函数具备的属性中进行访问,且进行操做,至关于覆盖了原型上的该同名属性。
可是上述的方法又出现了一个别的问题,该问题也比较容易解决,比较少用到,笔记先到这,后续笔记将记录该问题及解决办法