js中继承实现

ES5和ES6继承

ES5继承

1、首先定义一个Person类,定义实例类方法和原型上的方法。

		function Person(name,sex,age){
			this.name = name;
			this.sex = sex;
			this.age = age;
			//定义实例方法
			this.run = function (){
				console.log(this.name + ' run')
			}
		}
		//定义原型上方法
		Person.prototype.work = function (){
			console.log(this.name + ' work')
		}

实例对象方法和Person原型上的方法
2、实例化出来的p对象有个原型p.__proto__中有一个constructor构造器,构造器中显示的构造方法。
构造函数
3、借用构造函数,首先定义一个Teacher类,只能继承原有构造函数中已经给定的属性和方法(未给定义的值全为undefined),不能继承原型链上的属性和方法。

		function Teacher(){
			//借用构造函数
			Person.call(this);
		}

完整代码

		function Person(name,sex,age){
			this.name = name;
			this.sex = sex;
			this.age = age;
			this.height = 178
			//定义实例方法
			this.run = function (){
				console.log(this.name + ' run')
			}
		}
		//定义原型上方法
		Person.prototype.work = function (){
			console.log(this.name + ' work')
		}
		Person.prototype.power = '很有钱'
		function Teacher(){
			Person.call(this);
		}
		let p = new Person('zs','男',20)
		console.log(p)
		let t = new Teacher()
		console.log(t)

结果如下:借用构造函数继承属性
4、子构造函数像超类构造函数传递参数

function Person(name,sex,age){
			this.name = name;
			this.sex = sex;
			this.age = age;
			this.height = 178
			//定义实例方法
			this.run = function (){
				console.log(this.name + ' run')
			}
		}
		//定义原型上方法
		Person.prototype.work = function (){
			console.log(this.name + ' work')
		}
		Person.prototype.power = '很有钱'
		function Teacher(name,sex){
			Person.call(this,name,sex);
		}
		let t = new Teacher('ls','女')
		console.log(t)
		console.log(t.run())

子类型构造函数向超类传递自己的参数

5、原型链继承,可以继承父类的每个属性和方法以及父类原型上的方法和属性

function Person(name,sex,age){
			this.name = name;
			this.sex = sex;
			this.age = age;
			this.height = 178;
			this.run = function (){}
		}
		Person.prototype.power = "很有钱"
		Person.prototype.buy = function (){
			console.log("i can buy everything!")
		}
		function Teacher() {
			// body...
			this.skill = 'teach'
		}
		Teacher.prototype = new Person();
		let t = new Teacher()
		console.log(t)

结果图:原型链继承
6、原型链继承弊端,会共享非引用类型数据(类似数组,只对其操作,重新赋值,会添加到实例对象下)

function Person(name,sex,age){
			this.name = name;
			this.sex = sex;
			this.age = age;
			this.color = ['red','pink','green']
			this.obj = {"name":'abc','age':20}
			this.height = 178;
			this.run = function (){}
		}
		Person.prototype.power = "很有钱"
		Person.prototype.buy = function (){
			console.log("i can buy everything!")
		}
		function Teacher() {
			// body...
			this.skill = 'teach'
		}
		Teacher.prototype = new Person();
		let t1 = new Teacher()
		//会添加到实例上的一个属性
		t1.height = 188;
		//给原有的color数组添加一个yello值,会使每个实例里的数据发生改变
		t1.color.push('yellow')
		console.log(t1)
		let t2 = new Teacher()
		console.log(t2)

当修改color数组中数据时会影响到每一个实例。
原型链的弊端
7、组合继承方式

function Person(name,age){
			this.name = name;
			this.age = age;
			this.color = ['red','pink',"green"];
			this.run = function (){
				console.log(this.name + ' run');
			}
		}
		Person.prototype.work = function () {
			// body...
			console.log(this.name + ' work');
		}
		Person.prototype.power = "很有钱"
		function Teacher(name,age,sex){
			//借用构造函数继承属性
			Person.call(this,name,age);
			this.sex = sex
		}
		//原型链部分
		Teacher.prototype = Person.prototype;
		//更改构造器为自己的构造函数
		Teacher.prototype.constructor = Teacher;
		let t1 = new Teacher('ww','23','女');
		t1.color.push('yellow')
		console.log(t1)
		let t2 = new Teacher('zl','24','男');
		console.log(t2)

如下图所示
组合继承
上图中红色圈起部分,每个实例不同的color数组,不会影响。
8、企业级继承方法利用一个buffer空构造函数去继承。

function Person(name,sex,age){
			this.name = name;
			this.sex = sex;
			this.age = age;
			this.run = function () {
				console.log(this.name + ' run');
			}
		};
		function Teacher(name,sex,age){
			Person.call(this,name,sex,age);
			this.skill = 'teach';
			this.work = function (){
				console.log(this.name + this.skill + ' work');
			}
		};
		Buffer.prototype = Person.prototype;
		function Buffer(){}
		Teacher.prototype = new Buffer();
		Teacher.prototype.class = '6-3';
		Teacher.prototype.teach = function (){
			console.log(this.name + ' teach ' + this.class);
		}

		let t1 = new Teacher('ls','男',20);
		let t2 = new Teacher('zs','女',18);
		console.log(t1)
		console.log(t2)

在这里插入图片描述

ES6继承

1、es6中定义类的方式

class Person {
			constructor(name,sex,age){
				this.name = name;
				this.sex = sex;
				this.age = age;
			}
			run(){
				//es6模板字符串的语法
				console.log(`${this.name}  ${this.sex}  ${this.age} run!!!!`)
			}
		}
		let p = new Person('zs','男','20');
		p.run();

在这里插入图片描述
2、es6中利用extends实现继承

class Person {
			constructor(name,sex,age){
				this.name = name;
				this.sex = sex;
				this.age = age;
			}
			//这里定义的run()在原型上方法
			run(){
				//es6模板字符串的语法
				console.log(`${this.name}  ${this.sex}  ${this.age} run!!!!`)
			}
}
let p = new Person('zs','男','20');
console.log(p);
p.run();


class Teacher extends Person{
	constructor(name){
		//继承name
		super(name);
	}
}
let t = new Teacher('ls');
console.log(t);

在这里插入图片描述
注意一些区别,构造函数中为class.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值