JS面向对象继承创建和使用

简介: JS面向对象继承创建和使用

以下只列举三种常见方式
1:拷贝继承
首先我们要知道子类究竟要继承父类的哪些特征?
答案是属性和方法。继承父类的属性。我们采用call通过对象冒充的方式。让子类具有父类的属性。那么接下来我们所说的三种方式,都是针对父类的方法。更直接一点,就是父类prototype上的方法。
那么我们就好理解。所谓拷贝继承。就是通过拷贝的方式,把父类prototype上的方法统统赋值给 子类的prototype
接下来我们看一个简单的例子。
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.eat=function(){
console.log("eat")
}

function Student(name,age,className){
Person.call(this,age,name)
this.className=className
}

for(var attr in Person.prototype){

  Student.prototype[attr]=Person.prototype[attr]

}

var s1=new Student();
console.log(s1.constructor)
s1.eat(); --》eat

2 类式继承
所谓类式继承。也就是通过一个父类新建一个实例类,由于该实例是由父类new出来的,所以就具有了所有父类的属性和方法。接下来我们只需要把子类的prototype指向这个实例类。那么子类的原型上就具有了父类的方法。
function Person(name,age){
this.name=name;
this.age=age
}

Person.prototype.eat=function(){
console.log("eat")
}
var p=new Person(); //所谓类式继承,就是通过父类创建一个类的实例,把子类的原型链等于这个类的实例,实现继承

function Student(name,age,className){

Person.call(this,name,age)
this.className="two"

}

Student.prototype=p;
var s1=new Student("sean",20);
s1.eat() --》eat
这个有一个问题:Student.prototype=p;本质是对象的引用。所以当我们修改Student.prototype.eat里函数的内容时,父类的方法也发生了变化。这时候我们只需要通过Student.constructor=Student。修正它的构造函数指向,这样就可以避免这个问题。constructor 属性是专门为 function 而设计的,它存在于每一个 function 的prototype 属性中。这个 constructor 保存了指向 function 的一个引用。也就是说constructor 的值实际上是其构造函数。

3 原型继承
所谓原型继承:其实和类式继承很相识。只不过类式继承是通过把一个父对象的实例等于子类的原型prototype属性来实现,而
原型继承则是通过一个空函数来实现,也就是把父类的原型赋值给空函数,再把该空函数返回的一个实例对象等于子类的原型prototype属性。有点绕。
基本上分3步骤:

(1)var F = function(){};
(2)F.prototype = Parent.prototype;
(3)Child.prototype = new F();

还是通过上面的例子:
function Person(name,age){
this.name=name;
this.age=age
}

Person.prototype.eat=function(){
console.log("eat")
}

function Student(name,age,className){

Person.call(this,name,age)
this.className="two"

}

function fn(){}
fn.prototype=Person.prototype;
Student.prototype=new fn();

var s1=new Student("sean",20);
s1.eat()
原型继承还是要相比类式继承的优点在于通过空函数占用内存较小。但是它还是存在子类constructor 指向的构造函数出错的问题。所以还是要手动修正。加上Student.constructor =constructor
function Person(name,age){
this.name=name;
this.age=age
}

Person.prototype.eat=function(){
console.log("eat")
}

function Student(name,age,className){

Person.call(this,name,age)
this.className="two"

}

function fn(){}
fn.prototype=Person.prototype;
Student.prototype=new fn();
Student.constructor =Student
var s1=new Student("sean",20);
s1.eat()
console.log(Student.constructor) --->function Student(){ ..... }

es6中定义了类的概念。不需要我们每次去写一个founction FN()这样一个构造函数。而通过class关键字去申明一个类。写法简洁。但是这只是一个语法糖,写法简单了,内部还是采用es5 构造函数去定义的。es5中我们的属性都通过传参到构造函数中,es6中则把属性通过参数的形式写在了一个叫constructor的构造函数中。方法在es5中通过prototype上定义函数的形式来完成。而es6中则直接简写成类似这样的形式
eat(){

 console.log("eat")

}

//定义一个person类
class Person{

constructor(name,age){

  this.name=name;
  this.age=age

}

eat(){

 console.log("eat")

}
}
注意:
每一个类都会有一个默认的固定的方法,这个方法名字 constructor
constructor构造函数:对类进行初始化的,当我们通过new的方式调用该类的时候,默认执行的函数就是这个 constructor 函数,所以 constructor 其实就是通过类创建对象的时候的初始化函数,我们会通过这个函数对产生的对象进行一些初始化的工作,比如属性初始化
注意:class中的方法,其实就是一个函数,但是函数不能有function

同样上面的例子:
class Person{
constructor(name,age){

  this.name=name;
  this.age=age

}

eat(){

 console.log("eat")

}
}

class Student extends Person{

constructor(name,age,className){

super(name,age)                      //super关键词用来继承父类的属性,相当于在es5中call的作用
this.className=className     //子类新的属性

}

test(){

  console.log("考试")

}

}

var p=new Person()
var s=new Student("sean","24")
console.log(s.name) ----》sean

ES6中类的出现。简化了写法。让我们不必再去更多的考虑写法。而是关注内容本身

相关文章
|
1月前
|
JavaScript 前端开发
如何在 JavaScript 中使用 __proto__ 实现对象的继承?
使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
|
1月前
|
JavaScript 前端开发
Javascript如何实现继承?
【10月更文挑战第24天】JavaScript 中实现继承的方式有很多种,每种方式都有其优缺点和适用场景。在实际开发中,我们需要根据具体的需求和情况选择合适的继承方式,以实现代码的复用和扩展。
|
1月前
|
JavaScript 前端开发
如何使用原型链继承实现 JavaScript 继承?
【10月更文挑战第22天】使用原型链继承可以实现JavaScript中的继承关系,但需要注意其共享性、查找效率以及参数传递等问题,根据具体的应用场景合理地选择和使用继承方式,以满足代码的复用性和可维护性要求。
|
1月前
|
JavaScript 前端开发 开发者
js实现继承怎么实现
【10月更文挑战第26天】每种方式都有其优缺点和适用场景,开发者可以根据具体的需求和项目情况选择合适的继承方式来实现代码的复用和扩展。
31 1
|
6月前
|
设计模式 JavaScript 前端开发
在JavaScript中,继承是一个重要的概念,它允许我们基于现有的类(或构造函数)创建新的类
【6月更文挑战第15天】JavaScript继承促进代码复用与扩展,创建类层次结构,但过深的继承链导致复杂性增加,紧密耦合增加维护成本,单继承限制灵活性,方法覆盖可能隐藏父类功能,且可能影响性能。设计时需谨慎权衡并考虑使用组合等替代方案。
47 7
|
6月前
|
JavaScript 前端开发
在 JavaScript 中,实现继承的方法有多种
【6月更文挑战第15天】JavaScript 继承常见方法包括:1) 原型链继承,利用原型查找,实例共享原型属性;2) 借用构造函数,避免共享,但方法不在原型上复用;3) 组合继承,结合两者优点,常用但有额外开销;4) ES6 的 class,语法糖,仍基于原型链,提供直观的面向对象编程。
38 7
|
3月前
|
自然语言处理 JavaScript 前端开发
一文梳理JavaScript中常见的七大继承方案
该文章系统地概述了JavaScript中七种常见的继承模式,包括原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合继承等,并探讨了每种模式的实现方式及其优缺点。
一文梳理JavaScript中常见的七大继承方案
|
3月前
|
JavaScript 前端开发
js之class继承|27
js之class继承|27
|
3月前
|
JSON JavaScript 前端开发
js原型继承|26
js原型继承|26
|
3月前
|
JavaScript 前端开发 开发者
JavaScript 类继承
JavaScript 类继承
22 1