一、继承
一个类型的对象能够访问另外一个类型的属性和方法
继承是类和类之间的关系
1.构造函数的继承
<script>
function Person(name, age) {
this.name = name;
this.age = age;
this.sayHello = function () {
console.log(this.name);
}
}
function Male(name, age) {
/* this.name = name;
this.age = age;
this.sayHello = function () {
console.log(this.name);
} */
//Person(name, age);
//直接调用Person,是让Person里的代码在Male里执行了一下,
//但是并没有给Male实例添加对应属性和方法,原因是this指向不对
//改变this指向
Person.call(this, name, age);//利用call方法改变this指向
this.sexy = "male";
/*
}
var male = new Male("john", 20);
console.log(male);
</script>
2.原型继承
<script>
function Person() {
}
Person.prototype.name = "john";
Person.prototype.age = 20;
Person.prototype.sayHello = function () {
console.log(this.name);
}
function Male() {
}
/* Male.prototype = Person.prototype; //Male原型对象就具有了Person原型对象的属性和方法
//但是父类原型和子类原型是同一个,子类的修改会影响到父类
Male.prototype.sexy = "male"; */
Male.prototype = new Person();//这一步实现了Male对Person的继承 成为原型继承
Male.prototype.sexy = "male";
var male = new Male();
/*
male这个实例里面有没有__proto__
male.__proto__== Male.prototype
Male.prototype.__proto__ == Person.prototype
//这时就形成了原型链
*/
male.sayHello();
//male访问sayHello,访问顺序:实例属性->Male.prototype->Person.prototype->……->Object.prototype->undefined
console.log(male.sexy);
var person = new Person();
console.log(person.sexy);
</script>
3.组合继承
<script>
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function () {
console.log(this.name);
}
function Male(name, age) {
Person.call(this, name, age);//上述两个方法一起用 就是组合继承
}
//Male.prototype = new Person();
//将Perosn原型对象上的方法给到Male的原型对象
for (let i in Person.prototype) { //也可以这样写
Male.prototype[i] = Person.prototype[i];
}
Male.prototype.sexy = "male";
var male = new Male("john", 20);
male.sayHello();
var person = new Person();
console.log(person.sexy);
</script>
4.寄生式组合继承
<script>
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function () {
console.log(this.name);
}
function Male(name, age) {
Person.call(this, name, age);
}
/* //Object.create()
var obj1 = {
a: 1
};
var obj2 = Object.create(obj1);
console.log(obj2); //obj2.__proto__ == obj1 */
Male.prototype = Object.create(Person.prototype);//利用Object.create
Male.prototype.constructor = Male;//constructor 构造函数
//Male.prototype.__proto__ == Person.prototype
var male = new Male("john", 20);
male.sayHello();
//通过实例找构造函数
console.log(male.__proto__.constructor);
//子类继承父类关联起来的封装函数
function inherit(Sup, Sub) { //Sup表示父类,Sub表示子类
Sub.prototype = Object.create(Sup.prototype);
Sub.prototype.constructor = Sub;
}
</script>
5.ES6继承 extends 关键字
<script>
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHello() {
console.log(this.name);
}
static foo() { //静态方法 类方法
console.log("foo");
}
}
// Person.foo();
class Male extends Person {
constructor(name, age) { //除了继承来的属性,自己需要添加属性
super(name, age); //指向父类的构造函数,同时创建this,改变this指向
this.sexy = "male"; //在使用this之前先调用super方法
}
sayHi() {
//在原型方法里需要使用到父类的原型方法
console.log("hi");
super.sayHello(); //指向父类的原型对象
}
static bar() {
super.foo(); //指向父类
}
}
var male = new Male("john", 20);
male.sayHello();
male.sayHi();
Male.bar();
</script>