JavaScript 面向对象 - 继承
1. 继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>继承</title>
</head>
<body>
<script type="text/javascript">
(function(){
/**
* 继承
* 什么叫继承
* 就是一个对象想用另一对象中的方法,借用了这种方法就是继承
*
* 继承的几种方式
* for...in继承
* 原型继承
* 经典继承
*/
})()
</script>
</body>
</html>
方式1 for in 继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>for...in继承</title>
</head>
<body>
<script type="text/javascript">
(function(){
/**
* for...in继承
*/
var obj = {
name : "jianyan",
age : 24,
sex : "male"
};
var o = {};
for(var k in obj){
o[k] = obj[k]
}
console.log(o.name); // jianyan
})()
</script>
</body>
</html>
方式2 原型继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>原型继承</title>
</head>
<body>
<script type="text/javascript">
(function(){
/**
* 原型继承
* 1.直接给原型对象中(利用对象的动态特性)
* 2.直接替换原型对象
* 导致之前原型中的方法失效
*/
// 1.直接给原型对象中(利用对象的动态特性)
function Animate(name,age){
this.name = name;
this.age = age;
this.say = function(){
console.log(this.name);
}
}
Animate.prototype.sayHello = function(){
console.log("我是sayHello方法");
}
var pandon = new Animate("dog",3);
console.log(pandon.name); // dog
console.log(pandon.age); // 3
pandon.say(); // dog
pandon.sayHello(); // 我是sayHello方法
/*// 2.直接替换原型对象
function Animate(name,age){
this.name = name;
this.age = age;
}
Animate.prototype.say = function(){
console.log(this.name);
}
var newAnimate = {
sayHello : function(){
console.log("我是sayHello方法");
}
}
Animate.prototype = newAnimate;
// newAnimate.constructor = Animate;
var pandon = new Animate("dog",3);
console.log(pandon.name); // dog
console.log(pandon.age); // 3
// pandon.say(); // pandon.say is not a function
pandon.sayHello(); // 我是sayHello方法
// 显而易见,当原型对象修改后,之前的原型对象方法失效*/
// 混入的方式
/*function Animate(name,age){
this.name = name;
this.age = age;
}
Animate.prototype.say = function(){
console.log(this.name);
}
var newAnimate = {
sayHello : function(){
console.log("我是sayHello方法");
}
}
for(var k in newAnimate){
Animate.prototype[k] = newAnimate[k];
}
var pandon = new Animate("dog",3);
console.log(pandon.name); // dog
console.log(pandon.age); // 3
pandon.say(); // dog
pandon.sayHello(); // 我是sayHello方法*/
})()
</script>
</body>
</html>
方式3 经典继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>经典继承</title>
</head>
<body>
<script type="text/javascript">
/**
* 经典继承
* 语法
* Object.create(obj);
* 例 var o1 = Object.create(o2) o1继承o2
* 兼容解决
*
*
*/
/*var o = {
name : "jianyan"
}
var obj = Object.create(o);
console.log(obj.name); // jianyan*/
// 兼容解决****************************************
/*if(Object.create){
var o = Object.create(obj);
}else{
Object.create = function(){
function F(){
}
F.prototype = obj;
var o = new F()
}
var o = Object.create(obj);
}*/
var Animate = {
getName : function(){
return this.name;
},
getAge : function(){
return this.age;
}
}
var pandon = Object.create(Animate,{
name:{value:"ajian"},
age:{value:2}
})
console.log(pandon.name); // ajian
console.log(pandon.age); // 2
</script>
</body>
</html>
方式4 构造函数继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>构造函数继承</title>
</head>
<body>
<script type="text/javascript">
(function(){
/**
* 构造函数继承
* 父.call()
* 父类.call(obj,参数1,参数2)
* 父.apply()
* 父类.apply(obj,[参数1,参数2])
* 也可以写成, 父类.apply(obj,arguments)
* *** obj指当前的对象,可以使用this代替
*
* 两者优缺点
* 两者都可以继承
* 推荐apply,如果继承的参数较多的话,使用call,如果参数缺少,就会报错
*
*
* 缺点,子类只能继承父类内的属性和方法,但不能继承父类.prototype的方法
*/
/*// 父.call()
function Animate(name){
this.name = name;
}
Animate.prototype.say = function(){
console.log("这是Animate的say方法");
}
function Pandon(name,age){
this.age = age;
// Animate.call(Pandon,name,age); // undefined
Animate.call(this,name,age);
}
var newPandon = new Pandon("pandon",3);
console.log(newPandon.name); // pandon
console.log(newPandon.age); // 3
// newPandon.say(); // say is not a function*/
/*// 父.apply()
function Animate(name){
this.name = name;
}
Animate.prototype.say = function(){
console.log("这是Animate的say方法");
}
function Pandon(name,age){
Animate.apply(this,arguments);
this.age = age;
}
var newPandon = new Pandon("pandon",3);
console.log(newPandon.name); // pandon
console.log(newPandon.age); // 3
newPandon.say(); // say is not a function
// *** 显而易见,apply不能继承父类.prototype方法*/
})()
</script>
</body>
</html>
方式5 混合式继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>混合式继承</title>
</head>
<body>
<script type="text/javascript">
(function(){
/**
* 混合式继承
*
* 在说下构造函数的缺点
* 构造函数生成实例后,该实例只能继承该实例的构造函数内的属性和方法,
* 但不能访问到该实例的构造函数的prototype的方法
*
* 解决
* 混合式继承
*/
function Animate(name){
this.name = name;
}
Animate.prototype.say = function(){
console.log("我是Animate的say方法");
}
function Pandon(name,age){
// 利用apply继承父类
Animate.apply(this,arguments);
this.age = age;
}
// 子类的原型执行父类的实例
Pandon.prototype = new Animate(); // 该实例可以访问到实例的构造函数和对应的原型
// 实例化
var newPandon = new Pandon("pandon",3);
console.log(newPandon.name); // pandon
console.log(newPandon.age); // 3
newPandon.say(); // 我是Animate的say方法
})()
</script>
</body>
</html>