<html>
<head>
<title>面向对象</title>
<meta charset="utf-8">
<style>
</style>
</head>
<body>
</body>
</html>
<script src="../js/jquery.min.js"></script>
<script>
// es5中类的声明
function Animal(){
this.name='name';//this 把这个函数变成构造函数
}
// es6中类的声明方式
class Animal2{
constructor(){
this.name=name
}
}
//实例化
console.log(new Animal(),new Animal2())
//第一种 借助构造函数实现继承 缺点不能继承parent1的原型上的属性
function Parent1(){
this.name='parent'
}
Parent1.prototype.say=function(){}
function child1(){
Parent1.call(this) //apply 实现继承的代码 但是不能继承parent1的原型上的属性
this.type='child1'
}
console.log(new child1())
//console.log(new child1().say()) say is not a function
//第二种 借助原型链实现继承 实例的原型指向同一个地址
function Parent2(){
this.name='parent2'
this.play=[1,2,3]
}
function Child2(){
this.type='child2'
}
Child2.prototype=new Parent2(); //实现继承的代码 缺点原型的改变会影响所有实例
console.log(new Child2())
var s1=new Child2();
var s2=new Child2();
s1.play.push(4)
console.log(s1.play,s2.play) //[1,2,3,4],[1,2,3,4]、
//第三种 组合方式 结合构造函数和原型链的方式 缺点 父级的构造函数执行了两次
function Parent3(){
this.name='parent3'
this.play=[1,2,3]
}
function Child3(){
Parent3.call(this)
this.type='child3'
}
Child3.prototype=new Parent3();
var s3=new Child3();
var s4=new Child3();
console.log(s3.play,s4.play)
s3.play.push(4)
console.log(s3.play,s4.play)
//第四种 组合方式 优化1 缺点实例不能通过constructor 判断从哪个构造函数直接实例化
function Parent4(){
this.name='parent4'
this.play=[1,2,3]
}
function Child4(){
Parent4.call(this)
this.type='child4'
}
Child4.prototype=Parent4.prototype; //有确定 不能通过constructor 判断从哪个构造函数直接实例化 默认都是父
var s5=new Child4();
var s6=new Child4();
console.log(s5.play,s6.play)
s5.play.push(4)
console.log(s5.play,s6.play)
//第四种 组合方式 优化2 完美解决
function Parent5(){
this.name='parent5'
this.play=[1,2,3]
}
function Child5(){
Parent5.call(this)
this.type='child5'
}
Child5.prototype=Object.create(Parent5.prototype)
Child5.prototype.constructor=Child5
</script>