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中类的出现。简化了写法。让我们不必再去更多的考虑写法。而是关注内容本身

目录
相关文章
|
3月前
|
设计模式 JavaScript 前端开发
在JavaScript中,继承是一个重要的概念,它允许我们基于现有的类(或构造函数)创建新的类
【6月更文挑战第15天】JavaScript继承促进代码复用与扩展,创建类层次结构,但过深的继承链导致复杂性增加,紧密耦合增加维护成本,单继承限制灵活性,方法覆盖可能隐藏父类功能,且可能影响性能。设计时需谨慎权衡并考虑使用组合等替代方案。
43 7
|
3月前
|
JavaScript 前端开发
在 JavaScript 中,实现继承的方法有多种
【6月更文挑战第15天】JavaScript 继承常见方法包括:1) 原型链继承,利用原型查找,实例共享原型属性;2) 借用构造函数,避免共享,但方法不在原型上复用;3) 组合继承,结合两者优点,常用但有额外开销;4) ES6 的 class,语法糖,仍基于原型链,提供直观的面向对象编程。
31 7
|
20天前
|
开发者 图形学 iOS开发
掌握Unity的跨平台部署与发布秘籍,让你的游戏作品在多个平台上大放异彩——从基础设置到高级优化,深入解析一站式游戏开发解决方案的每一个细节,带你领略高效发布流程的魅力所在
【8月更文挑战第31天】跨平台游戏开发是当今游戏产业的热点,尤其在移动设备普及的背景下更为重要。作为领先的游戏开发引擎,Unity以其卓越的跨平台支持能力脱颖而出,能够将游戏轻松部署至iOS、Android、PC、Mac、Web及游戏主机等多个平台。本文通过杂文形式探讨Unity在各平台的部署与发布策略,并提供具体实例,涵盖项目设置、性能优化、打包流程及发布前准备等关键环节,助力开发者充分利用Unity的强大功能,实现多平台游戏开发。
44 0
|
28天前
|
JavaScript 前端开发 开发者
揭开JavaScript的神秘面纱:原型链背后隐藏的继承秘密
【8月更文挑战第23天】原型链是JavaScript面向对象编程的核心特性,它使对象能继承另一个对象的属性和方法。每个对象内部都有一个[[Prototype]]属性指向其原型对象,形成链式结构。访问对象属性时,若当前对象不存在该属性,则沿原型链向上查找。
23 0
|
1月前
|
JavaScript 前端开发
JS的6种继承方式
JS的6种继承方式
|
3月前
|
设计模式 JavaScript 前端开发
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
JavaScript的继承机制基于原型链,它定义了对象属性和方法的查找规则。每个对象都有一个原型,通过原型链,对象能访问到构造函数原型上的方法。例如`Animal.prototype`上的`speak`方法可被`Animal`实例访问。原型链的尽头是`Object.prototype`,其`[[Prototype]]`为`null`。继承方式包括原型链继承(通过`Object.create`)、构造函数继承(使用`call`或`apply`)和组合继承(结合两者)。ES6的`class`语法是语法糖,但底层仍基于原型。继承选择应根据需求,理解原型链原理对JavaScript面向对象编程至关重要
76 7
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
|
1月前
|
设计模式 JavaScript 前端开发
js对原型和继承的理解
了解JavaScript中原型和继承的概念对于编写优雅高效的代码、理解库和框架的内部机制以及执行高级设计模式都有着重要的意义。
36 0
|
3月前
|
JavaScript 前端开发
JavaScript进阶-原型链与继承
【6月更文挑战第18天】JavaScript的原型链和继承是其面向对象编程的核心。每个对象都有一个指向原型的对象链,当查找属性时会沿着此链搜索。原型链可能导致污染、效率下降及构造函数与原型混淆的问题,应谨慎扩展原生原型、保持原型结构简洁并使用`Object.create`或ES6的`class`。继承方式包括原型链、构造函数、组合继承和ES6的Class继承,需避免循环引用、方法覆盖和不当的构造函数使用。通过代码示例展示了这两种继承形式,理解并有效利用这些机制能提升代码质量。
57 5
|
3月前
|
JavaScript 前端开发
JavaScript 继承的方式和优缺点
JavaScript 继承的方式和优缺点
|
3月前
|
JavaScript 前端开发
JavaScript 中,可以使用类继承来创建子类
JavaScript 中,可以使用类继承来创建子类
23 0