发表于: 2016-09-12 00:07:19
0 1989
今天完成的事情:重构代码、整理继承知识点、学习项目代码
明天计划的事情:优化重构代码,(想要合理的将功能模块化好难,,,,,在考虑到要添加游戏版本时,发现之前代码还需要进一步的修改),项目代码
遇到的问题:
收获:
继承的目的:
在创建一些实例对象,他们不但具有一些相同的方法和属性,同时还有着自己私有的方法和属性,传统做法是
function Employee(name){
this.name =name ;
this.company= 'PuTaoTeng';
}
var employee1=new Employee('KeJi');
var employee2=new Employee('DongXiaoJie');
这里有一个Employee公司职员的构造函数,里面给通过这个构造函数给每个员工创建一个实例,实例中有姓名和公司两个属性,这样的话对于数据的更新共享,同时也造成了很大的资源浪费,比如后来公司改名了,这时如果要更改员工数据的话需要给每个员工实例出的对象中的company分别进行更新,所以针对这种情况就需要采用一种方法,让company属性能够被Employee实例所共享,这就用到了继承。
实现原理:
思想为通过原型链,在原型中存放用来共享的属性和方法,在实例中存放私有属性和方法
继承的具体实现方法:
1、原型链继承:
function A(){
this.property = true;
}
A.prototype.getSuperValue = function(){
return this.property;
};
A.prototype.nameA='A';
function B(){
this.nameB='B';
this.subproperty = false;
}
B.prototype = new A();
B.prototype.getSubValue = function (){return this.subproperty;};
B.prototype.nameBB='C';
B.log=function () {
console.log(this.prototype);
};
var instance = new B();
console.log(instance.nameBB);
有一个超类型构造函数A,和一个子类型构造函数B,首先A的实例中有一个属性property 在A的原型中有一个属性nameA和一个方法getSuperValue 子类型构造函数B的实例中有属性nameB,子类型构造函数B的原型是A的实例,这样在创建B的实例时,每个B实例的属性nameB都是私有的,而由于B的类型等于A的实例,所以A实例出的property 属性和A原型中的nameA都会被在B的实例中被共享到
存在的问题:
①原本构造函数A所定义的属性property 对于A的实例都是私有的,但是当A的实例变为B的原型之后,则该属性就会被B的所有实例所共享。
②创建子类型的时候不能像超类型的构造函数中传递参数(但一直没理解这个有什么用。(☄⊙ω⊙)☄))
2、借用构造函数:原型链继承是将超类型A的实例赋值给子类型B的原型以达到继承效果,而借用构造函数则是在子类型构造函数B的内部调用超类型构造函数A,通过apply(),call()改变A的this指向,借用A的方法,这样每个B的实例都会获得一份A的属性。
function B(){
A.call(this)
this.subproperty = false;
}
存在的问题:
如果单纯的使用借用构造函数方法,那么超类型原型中定义的方法对于子类型是不可见的
所以借用构造函数方法一般大多是和原型链继承的方法结合起来这就是组合继承
3、组合继承:
function A(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
A.prototype.sayName = function(){
alert(this.name);
};
function B(name, age){
A.call(this, name);
- this.age = age;
}
B.prototype = new A();
B.prototype.constructor=B;
B.prototype.sayAge = function(){
alert(this.age);
};
var instance1 = new B("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
组合继承就是在子类型构造函数B中借调超类型构造函数A,同时在B中定义用来拓展的属性,
并且同时将超类型构造函数A的实例赋值给子类型构造函数B的原型;这样B的实例中中既有通过借用构造函数方式创建的name,colors属性,和B中拓展的age属性,而且还可以通过原型链访问到A原型中的的sayName 方法。
4、原型式继承:
有这样一种情形,现在有一个对象person ,现在想创建一批新的对象,令这些新的创建的对象都获得的person 的属性
这就是原型式继承
function object(o){
function F(){}
F.prototype = o;
return new F();
}
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
原型式继承的过程是:总结的来说是在创建新对象的时候通过object方法将要继承的person 对象赋值给创建的对象原型中
存在的问题:由于是引用类型,所以在在新对象中修改friends的时候会影响到原有的person 中的friends属性;
5、寄生式继承:
我对寄生式继承的理解就是在原型式继承的基础上加了一个creatAnother函数,它将继承过程和给新创建对象添加方法的代码都封装在其中;这种继承方式和原型式继承都不重要,理解原理就好,只是用来引出寄生组合式继承的;
function object(o){
function F(){}
F.prototype = o;
return new F();
}
function creatAnother(original){
var clone=object(original);
clone.sayHi=function(){
alert('hi');
}
}
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
6、寄生组合式继承:
由于组合继承在使用时会调用两次超类型构造函数(两次调用分别是在上方3、组合继承的示例代码的第10行、第14行,即一次是给将超类型构造函数的实例赋给子类型的原型时,一次是在子类型构造函数实例化过程中借用超类型构造函数时)这样会产生两组name和color属性,为了解决这个问题,寄生组合继承就诞生了
实例代码如下:
function object(o){
function F(){}
F.prototype = o;
return new F();
}
function inheritPrototype(subType, superType){
var prototype = object(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}
function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
SuperType.call(this, name);
- this.age = age;
}
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function(){
alert(this.age);
};
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
console.log(instance1);
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27
console.log(instance2);
寄生式组合继承本质上就是讲超类型构造函数的原型通过寄生继承的方式赋给子类型构造函数的原型,而创建私有属性的时候则依旧是通过借用构造函数的方式创建的,
评论