<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">-->
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>【第二章】寄生组合继承&多继承</title>
</head>
<body>
<script>
// 组合继承
/*
function Super(){
this.name = 'superName';
this.age = 'superAge';
}
Super.prototype.showName = function(){
return this.name;
};
function Sub(){
Super.call(this);
this.age = 'subAge';
}
Sub.prototype = new Super();
Sub.prototype.showAge = function(){ // 这里由于用了类继承,所以Sub.prototype不能写成 Sub.prototype = {}的形式了。
return this.age;
};
var sub01 = new Sub();
console.log(sub01.name); // superName
console.log(sub01.age); // subAge
console.log(sub01.showName()); // superName
console.log(sub01.showAge()); // subAge
console.log(sub01 instanceof Sub); // true
console.log(sub01 instanceof Super); // true
console.log(Sub.prototype instanceof Super); // true
*/
</script>
<script>
/*
// 原型式继承
function inheritObj(obj){
var F = function(){};
F.prototype = obj;
return new F();
}
function Super(){
this.name = 'superName';
this.age = 'superAge';
this.arr = ['super'];
}
Super.prototype.getAge = function(){
return this.age;
};
// var super01 = {
// name: 'super',
// };
var super01 = new Super();
// 寄生式继承
function inherit(obj){
// var _instance = new inheritObj(obj); // 这里返回的就是inheritObj执行后,返回的带有父级原型的一个函数,有没有new应该没区别。
var _instance = inheritObj(obj); // 这返回来的是一个原型是super的一个实例,但是return的F原型是Super 而_instance的原型不是
// console.log(_instance);
// console.log(_instance.__proto__);
_instance.name = 'subName';
_instance.getName = function(){
return this.name;
};
// _instance.prototype = obj;
return _instance;
}
var sub01 = inherit(super01);
sub01.arr.push('sub1Name');
console.log(sub01.getName());
console.log(sub01.getAge());
console.log(sub01.prototype instanceof Super);
console.log(sub01 instanceof Super);
var sub02 = inherit(super01);
sub02.arr.push('sub2Name');
console.log(super01.arr); // ["super", "sub1Name", "sub2Name"] 这个并不能解决共用问题。 只是解决了组合模式的重复new Super的问题。
*/
</script>
<script>
/*
// 寄生组合继承
function inheritObject(obj){
var F = function(){};
F.prototype = obj;
return new F();
}
function inheritPrototype(subClass,superClass){
var p = inheritObject(superClass.prototype);
p.constructor = subClass;
subClass.prototype = p;
}
function Super(){
this.name = 'superName';
this.age = 'superAge';
this.arr = ['super'];
}
Super.prototype.showName = function(){
return this.name;
};
Super.prototype.showAge = function(){
return this.age;
};
function Sub(){
Super.call(this);
this.age = 'subAge';
this.job = 'subJob';
}
// inheritPrototype(Sub, Super); // 这个方法必须执行到Sub.prototype绑定的前边
Sub.prototype.showJob = function(){
return this.job;
};
console.log(Sub.prototype);
inheritPrototype(Sub, Super); // 放在前边的原因: subClass.prototype = p; 覆盖掉了之前的 Sub.prototype
console.log(Sub.prototype);
var s1 = new Sub();
console.log(s1 instanceof Sub);
console.log(s1 instanceof Super);
console.log(s1.prototype instanceof Super);
console.log(s1.constructor);
console.log(s1.showName());
console.log(s1.showAge());
// console.log(s1.showJob());
var s2 = new Sub();
s2.arr.push('sub02');
s1.arr.push('sub01');
console.log(s1.arr);
console.log(s2.arr);
*/
</script>
<script>
// 判断是否是数组
function isArray(obj) {
return (Object.prototype.toString.call(obj).indexOf('Array') != -1) ? true : false;
}
// 判断是否是对象
function isObject(param){
return (param instanceof Object);
}
// 复制类数组
function copyArr(arr){
var tempArr = [];
for(var index in arr){
tempArr[index] = arr[index];
}
return tempArr;
}
// extend 单复制浅复制
Object.prototype.extend = function(sourceObj){
for(var key in sourceObj){
this[key] = sourceObj[key];
}
}
// extend 深复制(利用JSON.stringify和JSON.parse)
Object.prototype.extend = function(source, isCover){
// if(proxy.hasOwnProperty(key) && !this.hasOwnProperty(key)){ // 已经有同名属性则不复制
var coverConditionStr,
coverConditionArr = ['proxy.hasOwnProperty(key)', 'proxy.hasOwnProperty(key) && !this.hasOwnProperty(key)'],
effectIsCover = (typeof isCover == 'boolean') ? isCover : true ;
coverConditionStr = effectIsCover ? coverConditionArr[0] : coverConditionArr[1]; // 0: 覆盖, 1:不覆盖
var proxy = JSON.stringify(source);
proxy = JSON.parse(proxy);
for(var key in proxy){
// 这里的hasOwnProperty其实有一点问题,不能遍历出原型上的属性。但作为属性复制来讲,反而是个好处。
if(eval(coverConditionStr)){ // eval 有安全问题
this[key] = proxy[key];
}
}
proxy = null;
}
// 这里有一个问题涉及到依赖注入,如果想在extend里判断是否覆盖已有属性,就需要在extend方法添加一个flag参数,
// 这样如果extends里也需要判断就需要作依赖注入来判断flag参数值。
// 这里说的angular中的$score那种不根据参数顺序的依赖注入,具体实现不清楚,先用argument[length-1]的方法实现。
// extend 多复制
// extends(paramArray, [isCover]) || extends(param1, param2, ..., [isCover])
Object.prototype.extends = function(){
var tempArr = [];
try{
if(isObject(arguments[0])){
if(isArray(arguments[0])){
tempArr = copyArr(arguments[0]);
}else{
tempArr = copyArr(arguments);
}
}else{
throw 'params is must instanceof Object';
}
for(var i=0; i<tempArr.length; i++){
// 如果最后一个参数是boolean值,则传入到extend方法中
if(typeof tempArr[tempArr.length - 1] == 'boolean'){
this.extend(tempArr[i], tempArr[tempArr.length - 1]);
}else{
this.extend(tempArr[i]);
}
}
}catch(err){
console.log(err);
}
};
var a = {
name: 'a的名字',
arr: [
{
ele1: 'a的arr属性第一个元素',
ele2: function(){
return 'a的arr属性第二个元素';
}
},
'index=a'
],
obj: {
objName: 'a的obj_name',
objArr: [1,2,3,4,5]
}
};
var b = {
name: 'b的名字',
publicInfo: '公用信息'
};
// 验证是否深度复制
b.extend(a, false); // 验证是否覆盖对象已有属性, 传true或者不传则覆盖, 传false则不覆盖(b的name,还是b的名字)
b.arr[0].ele1 = 'b'; // 如果修改后不影响a,就是深度复制
console.log({'b': b}); // ele1 : 'b'
console.log({'a': a}); // ele1 : 'a的arr属性第一个元素'
// 验证多继承
// var c = {};
// c.extends(a, b);
// console.log(c);
</script>
</body>
</html>