面试问题
- 类的声明
- 生成实例
- 如何实现继承
- 继承的几种方式
声明和生成实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>OOP</title>
</head>
<body>
</body>
<script>
function Animal() {
this.name = 'name'
}
class Animal2 {
constructor() {
this.name = 'name';
}
}
console.log(new Animal());
//Animal {name: "name"}
console.log(new Animal2());
//Animal2 {name: "name"}
</script>
</html>
继承的几种方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>inherit</title>
</head>
<body>
</body>
<script>
//借助构造函数实现继承
function Parent1(name, age) {
this.name = name;
this.age = age;
}
Parent1.prototype.say = function () {};
function Child1(name, age) {
Parent1.call(this, name, age);
}
var person = new Child1('zhangsan', 20);
console.log(person);
//Child1 {name: "zhangsan", age: 20}
//原理:将父级构造函数的this指向子构造函数的实例中去
//缺点:无法继承Parent1原型链上的属性和方法
//原型链实现继承
function Parent2() {
this.name = 'parent2';
this.play = [1, 2, 3]
}
function Child2() {
}
Child2.prototype = new Parent2();
var s1 = new Child2();
var s2 = new Child2();
console.log(s1.play);
//[1, 2, 3]
console.log(s2.play);
//[1, 2, 3]
s1.play.push(4);
console.log(s2.play);
//s1.play changed!!
//[1, 2, 3, 4]
//缺点:原型链上的原型对象是共用的,实例改变其值,其他实例对应的属性也会变
//组合方式
function Parent3() {
this.name = 'parent3';
this.play = [1, 2, 3];
}
function Child3() {
Parent3.call(this);
}
Child3.prototype = new Parent3();
//这个方法没有上述缺点
//但是父构造函数执行了两次
//组合优化方式2
function Parent4() {
this.name = 'parent3';
this.play = [1, 2, 3];
}
function Child4() {
Parent4.call(this);
}
Child4.prototype = Parent4.prototype;
var s4 = new Child4();
console.log(s4.constructor);
//ƒ Parent4() 不是 Child4,这是问题所在
//Child4 和 Parent4 共用了一个原型对象
//组合继承优化2
function Parent5() {
this.name = 'parent3';
this.play = [1, 2, 3];
}
function Child5() {
Parent5.call(this);
}
Child5.prototype = Object.create(Parent4.prototype);
//原理是通过Object.create方法创建一个中间对象,参数是该对象的原型对象,然后把子类的构造函数赋值为该子类
Child5.prototype.constructor = Child5;
</script>
</html>