从新看红皮书,以为不少知识多看几遍确实是能看的更明白些。今天重温了一下对象建立和继承,就稍微记下来,巩固一下。编程
js是面向对象的编程语言,ECMA-262吧对象定义为:“无序属性的集合,其属性能够包含基本值,对象或者函数”。每一个对象都是基于一个引用类型建立的,这个引用类型能够是原生类型,也能够是自定义的。编程语言
一,讲讲建立对象的几个方法函数
1. var person = new Object(); 优化
2. var person = {};this
3. 工厂模式prototype
4. 构造函数模式指针
5. 原型模式对象
6. 组合使用构造函数模式和冤案型模式blog
7. 动态原型模式继承
8.等等......
这里着重记一下构造模式和原型模式,毕竟以后的模式和继承方法都是因为这两个的优缺点借鉴而来。
4.构造函数模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
console.log(this.name);
};
}
var person1 = new Person('niko','19','FE');
这种方式建立对象,能够将它的实例化标识为一中特定类型。及实例能够经过 instanceof 或者constructor 来检测对象的类型。缺点是没法完成方法的复用,即每一个方法都须要在实例化上从新建立。
5.原型模式
咱们天然是但愿建立对象时能够共享某些属性和方法,搞这个原型模式挺拿手的~~~来露个脸。简单的说,咱们建立的每一个函数都有一个prototype属性,这个prototype属性是一个指针,指向一个对象,这个对象里面放着建立的这个对象实例的原型对象。原型对象,便是包含全部实例都共享的属性和方法。默认状况下,全部原型对象都自动得到一个constructor属性,这个属性包含一个指向prototype属性所在函数的指针。绕来绕去估计就晕了,来个图解释一下。
经过原型模式建立对象以后,是能够顺顺利利的完成属性和方法的共享,可是也是有弊端的若是包含引用类型的值,那么实例化的某一个对象对这个值进行操做,就会修改原型里的值,这样问题就比较麻烦了。因此组合模式就出现了,及用构造函数来建立属性,用原型模式来建立共享方法。
7.动态原型模式,就是把全部信息封装到函数里看着会简洁好多,也是组合了构造函数和原型模式的优势,在函数内部初始化原型(仅仅在第一次运行时初始化)。
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
if(typeof this.sayName!= "function"){
Person.prototype.sayName = function(){
console.log(this.name);
};
}
}
var person1 = new Person('niko','19','FE');
跟组合模式不一样的是,初始化原型在函数内部,而且若是有多个共享函数时,只判断一个就好~~看着简洁那么一小丢~~对象建立就写到这,接下来写一下继承啦啦啦啦~
二,常见的继承方式
1.原型链
2.借用构造函数
3.组合继承
4.组合寄生式继承
5.原型式,寄生式..
挑几个重要的讲吧,重要的就是掌握原型链的原理,以及构造函数继承方式,组合是采起了这两个优缺点进行优化,组合寄生则是针对组合继承进行的优化。原型、寄生式是对一个相对的对象来建立另外一个,没怎么碰到就不讲了。
1.原型链
原型链的主要思想就是让一个引用类型继承另外一个引用类型的实例。原型对象将包含一个指向另外一个原型的指针,另外一个原型中也包含指向另外一个构造函数的指针。层层递进以后,造成原型链。
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
};
function Subtype(){
this.subproperty = false;
}
Subtype.prototype.getSubValue = function(){
return this.subproperty;
}
Subtype.prototype.getSubValue = function(){
return this.subproperty;
};
var instance = new Subtype();
啊,写到一半忽然要闭馆了闭馆了闭馆了=.=泪奔一下 ,中间详细就不解释了,看懂这个图就没啥大问题了~原型链的问题就是,共享引用类型值的时候,修改一个实例就会修改原型。
2.借用构造函数
这个方法就是在子类构造函数中调用超类的构造函数。
function SuperType(name){
this.name = name;
}
function SubType(){
SuperType.call(this,'niko'); //在this的做用域中调用SuperType()
}
var instance = new SubType();
这种方式不像原型继承,至关于在子类的做用域中吧超类的属性完彻底全复制了一份。由于不是引用的指针,因此,即便是引用类型的属性值,每一个实例都会复制一份属性值,因此不会有什么问题哒~~~并且借用构造函数模式能够在子类中传参。
3.组合继承就是兼顾了原型模式和借用构造函数模式的优缺点。既能够共享方法,也可让不一样的实例分别有本身的属性。
function SuperType(name){
this.name = name;
this.colors = ['red','blue','orange'];
}
SuperType.prototype.sayName = function(){
console.log(this.name);
}
function SubType(name,age){
//继承属性
SuperType.call(this,name); //第二次调用SuperType()
this.age = age;
}
SubType.prototype.sayAge = function(){
console.log(this.age);
}
//继承方法
SubType.prototype = new SuprType(); //第一次调用SuperType();
var instance = new Subtype('niko',34);
如图所示,第一次调超类的时候,SubType.prototype获得两个属性:name,colors。调用Subtype构造函数时,第二次调用超类,在新对象上建立实例属性:name,colors。这两个实例属性屏蔽了原型中的属性。
这种方法能够达到既能够共享方法,也能够有本身的实例属性,可是调用两次超类的构造函数。
4.寄生组合式继承
为了解决组合式的缺点,寄生组合式这个超级大Boss上场了。
大致思路仍是借用构造函数来继承属性,用原型链的混成方法机场方法。与组合 方式不一样的是,没有在子类中调用超类,而是取得了一个超类的副本。
function inhertiPrototype(subType,superType){ var prototype = object(superType.prototype); //建立对象 prototype.constructor = subType; //加强对象 subType.prototype = prototype; //指定对象 }