以下内容均基于本人对《JavaScript高等程序设计》第三版6.3小节的明白
先看一下父类
function Animal(name) {
var name = name; //'私有(受庇护)'成员,只允许在父类的组织函数中赋值
this.food = undefined; //'公有'成员
//援用范例的成员
this.birthday = {
year: undefined
};
//组织函数中的要领,打印一些基本信息
this.greeting = function() {
console.log('Hi, my name is {' + name + '} I like eat {' + this.food + '} and my birth year is {' + this.birthday.year + '}');
};
//原型中的要领,将组织函数中的非函数成员以JSON花样打印
Animal.prototype.briefInfo = function() {
var brief = {
name: name,
food: this.food,
birthday: this.birthday
};
console.log(JSON.stringify(brief));
};
}
体式格局一:原型链继续
完成体式格局:子类的原型指向父类的实例
子类:
function Dog() {}
Dog.prototype = new Animal(); //原型指向父类的实例
测试:
var dog1 = new Dog();
dog1.food = 'shit';
dog1.birthday.year = 2015;
var dog2 = new Dog();
dog2.food = 'bones';
dog2.birthday.year = 2016;
dog1.greeting(); //console: Hi, my name is {undefined} I like eat {shit} and my birth year is {2016}
dog2.greeting(); //console: Hi, my name is {undefined} I like eat {bones} and my birth year is {2016}
dog1.briefInfo(); //console: {"food":"shit","birthday":{"year":2016}}
dog2.briefInfo(); //console: {"food":"bones","birthday":{"year":2016}}
//以上,
//birthday是援用范例的属性,所以dog1的birthday.year被dog2覆蓋了;
//没法给dog1和dog2的name赋值
存在的题目:
援用范例的对象会被子类的一切实例同享
(1.1)
没法在建立子类的实例时,给父类的组织函数通报参数
(1.2)
体式格局二:借用组织函数(捏造对象、典范继续)
完成体式格局:在子类的组织函数中应用call(或许apply)要领实行父类组织函数(题目1.2处理)
,将实行对象设为子类的this,相当于把父类组织函数中的成员拷贝了一份到子类(题目1.1处理)
子类
function Dog(name) {
Animal.call(this, name);
}
测试
var dog1 = new Dog('tom');
dog1.food = 'shit';
dog1.birthday.year = 2015;
var dog2 = new Dog('mike');
dog2.food = 'bones';
dog2.birthday.year = 2016;
dog1.greeting(); //console: Hi, my name is {tom} I like eat {shit} and my birth year is {2015}
dog2.greeting(); //console: Hi, my name is {mike} I like eat {bones} and my birth year is {2016}
//briefInfo是父类原型中的属性,并没有被继续,以下语句会报错
dog1.briefInfo(); //error: dog1.briefInfo is not a function
dog2.briefInfo(); //error: dog2.briefInfo is not a function
存在的题目:
父类原型中定义的属性没法被继续
综合体式格局一体式格局二,一种很明显的体式格局呼之欲出了:
体式格局三:组合继续
完成体式格局:连系原型链继续和典范继续
子类
function Dog(name) {
Animal.call(this, name); //典范继续
}
Dog.prototype = new Animal(); //原型链继续
测试
var dog1 = new Dog('tom');
dog1.food = 'shit';
dog1.birthday.year = 2015;
var dog2 = new Dog('mike');
dog2.food = 'bones';
dog2.birthday.year = 2016;
dog1.greeting(); //console: Hi, my name is {tom} I like eat {shit} and my birth year is {2015}
dog2.greeting(); //console: Hi, my name is {mike} I like eat {bones} and my birth year is {2016}
dog1.briefInfo(); //console: {"name":"tom","food":"shit","birthday":{"year":2015}}
dog2.briefInfo(); //console: {"name":"mike","food":"bones","birthday":{"year":2016}}
//终究得到了预期的效果,算是较好的完成了继续。
//然则,并不圆满
存在的题目
父类的组织函数被调用了两次
为了引出下一个继续体式格局,先将函数的继续放在一边,看一下js中对象的继续
(摘抄原文)
1. 原型式继续
var person = { name: 'martin' firend: ['bob', 'steven'] }; function object(o) { function F() {}; F.prototype = o; return new F(); } var anotherPerson = object(person); //antherPerson继续了person
2. 寄生式继续
function createAnother(original) { var clone = object(original); //原型式继续定义的要领 //扩大对象 clone.sayHi = function() { console.log('hi'); } return clone; }
回到正题,接下来引见一颗 “银弹”
体式格局四:寄生组合式继续
完成体式格局:
应用典范继续拷贝父类组织中的属性到子类
应用原型式继续建立一个继续父类原型的对象
将该对象的constructor属性指向子类的组织函数
(寄生式继续:扩大对象)
将子类的prototype指向该对象
子类
function Dog(name) {
Animal.call(this, name);
}
function F() {}
var supProto = Animal.prototype;
F.prototype = supProto;
var subProto = new F();
subProto.constructor = Dog;
Dog.prototype = subProto;
测试
var dog1 = new Dog('tom');
dog1.food = 'shit';
dog1.birthday.year = 2015;
var dog2 = new Dog('mike');
dog2.food = 'bones';
dog2.birthday.year = 2016;
dog1.greeting(); //console: Hi, my name is {tom} I like eat {shit} and my birth year is {2015}
dog2.greeting(); //console: Hi, my name is {mike} I like eat {bones} and my birth year is {2016}
dog1.briefInfo(); //console: {"name":"tom","food":"shit","birthday":{"year":2015}}
dog2.briefInfo(); //console: {"name":"mike","food":"bones","birthday":{"year":2016}}