/**************
 * 继承 
 *************/  
console.log('*******************伪类');  
//当一个函数对象被创建时,Function构造器产生的函数对象会运行类似这样的一些代码:  
//         this.prototype = {constructor : this}  
//新函数对象被赋予一个prototype属性,它的值是一个包含constructor属性且属性值为该新函数的对象。  
//这个prototype对象是存放继承特性的地方,constructor属性没什么用,重要的是prototype对象。  
  
//采用
构造函数调用模式  
var Mammal = function(name){  
    this.name = name || '';  
};  
Mammal.prototype.get_name = function(){  
    console.log('ssss');  
    return this.name;  
};  
  
Mammal.prototype.says = function(){  
    return this.saying || '';  
};  
  
var myMammal = new Mammal("truth");  
console.log(myMammal.get_name());  
  
//构造另一个伪类来继承Mammal  
//var Cat = function(name){  
//  this.name = name;  
//  this.saying = 'meow';  
//};  
//替换Cat.prototype 为一个新的Mammal实例。  
//Cat.prototype = new Mammal();  
//伪类模式本意是想向
面向对象靠拢,但它看起来格格不入,我们可以隐藏一些丑陋的细节,  
//通过使用method方法来定义一个extend方法实现。  
  
Function.method('extend',function(Parent){  
    this.prototype = new Parent();  
    return this;  
});  
  
var Cat = function(name){  
    this.name = name;  
    this.saying = 'meow';  
};  
Cat.extend(Mammal)  
.method('get_name2',function(){  
    return this.name+':'+this.saying;  
});  
//这个get_name方法没有创建成功,因为在定义这个method方法体时,不允许创建同名的方法。  
//改成其他名称就好了  
var myCat = new Cat('Henrietta');  
console.log(myCat);  
console.log(myCat.says());  
console.log(myCat.get_name2());  
  
console.log('**************函数化');  
var mammal = function(spec){  
    var that = {};  
    that.get_name = function(){  
        return spec.name;  
    };  
    that.says = function(){  
        return spec.saying || '';  
    };  
    return that;  
};  
//个人理解:将变量放到spec中后变成私有变量,其他对象访问不到。  
//因为在mammal对象中没有name属性,所以只能通过get_name()方法获取。  
  
var cat = function(spec){  
    spec.saying = spec.saying || 'meow';  
    var that = mammal(spec);  
    that.get_name = function(){  
        return that.says() +' '+ spec.name +' '+ that.says();  
    };  
    return that;  
};  
var myCat2 = cat({name:'Henrietta'});  
console.log(myCat2.get_name());  
  
Object.method('superior',function(func_name){  
    console.log(this);  
    var that = this;  
    method = that[func_name];  
    return function(){  
        return method.apply(that,arguments);  
    };  
});  
var coolCat = function(spec){  
    var that = cat(spec);  
    //因为没有name属性,所以只能调用方法来获取name值。  
    super_get_name = that.superior('get_name');  
//  super_get_name = that.get_name();  
    that.get_name = function(){  
        return 'like ' + super_get_name + ' baby';  
    };  
    return that;  
};  
var myCoolCat = coolCat({name : 'Bix'});  
console.log(myCoolCat.get_name());