如何理解class继承的问题,有哪些要点
Admin 2022-09-06 群英技术资讯 677 次浏览
这篇文章主要介绍了如何理解class继承的问题,有哪些要点相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何理解class继承的问题,有哪些要点文章都会有所收获,下面我们一起来看看吧。然而,class 的出现真的改变这一现状了吗?
不如往下看。
与函数类型相似,定义类也有两种主要方式:类声明和类表达式。
// 类声明 class Person {}
// 类表达式 const Animal = class {};
不过,与函数定义不同的是,虽然函数声明可以提升,但类定义不能。
与函数构造函数一样,多数编程风格都建议类名的首字母要大写,以区别于通过它创建的实例。
类可以包含:
这些项都是可选的
class Person {
constructor(name) {
this.name = name
console.log('person ctor');
}
}
let p1 = new Person("p1")
constructor 会告诉解释器 在使用 new 操作符创建类的新实例时,应该调用这个函数。
等同于
function Person(name){
this.name = name
console.log('person ctor')
}
let p1 = new Person("p1")
类构造函数与构造函数的主要区别是,这样写会报错:
class Animal {}
let a = Animal(); // TypeError: class constructor Animal cannot be invoked without 'new'
所以,new 操作符是强制要写的;
使用 new 时,原理与 new 一个对象也是一样的,因为太重要了,再强调一遍:
(1) 在内存中创建一个新对象。
(2) 这个新对象内部的[[Prototype]]指针被赋值为构造函数的 prototype 属性。
(3) 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)。
(4) 执行构造函数内部的代码(给新对象添加属性)。
(5) 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象。
从各方面来看,ECMAScript 类就是一种特殊函数。
我们可以用 typeof 打印试试:
class Person {}
console.log(typeof Person); // function
也可以用 instanceof 检查它的原型链
class Person {}
let p = new Person()
console.log(p instanceof Person); // true
通过 class 构造的每个实例都对应一个唯一的成员对象,这意味着所有成员都不会在原型上共享;
class Person {
constructor() {
this.name = new String('Jack');
this.sayName = () => console.log(this.name);
}
}
let p1 = new Person();
let p2 = new Person();
console.log(p1.name === p2.name) // false
console.log(p1.sayName === p2.sayName) // false
如果想要共享,就改写成方法,写在 constructor 外面:
class Person {
constructor() {
this.name = new String('Jack');
}
sayName(){
console.log(this.name);
}
}
let p1 = new Person();
let p2 = new Person();
console.log(p1.sayName === p2.sayName) // true
我们可以在方法前面加 static 关键字,实现:静态类成员。我们不能在类的实例上调用静态方法,只能通过类本身调用。不做赘述。
ECMAScript 6 新增特性中最出色的一个就是原生支持了类继承机制。虽然类继承使用的是新语法,但背后依旧使用的是原型链。
让我们再回顾构造函数继承和原型链继承 2 个经典的问题:
① 构造函数继承的问题:构造函数外在原型上定义方法,不能重用
function SuperType(){}
SuperType.prototype.sayName = ()=>{console.log("bob")}
function SubType(){
SuperType.call(this) // 构造函数继承
}
let p1 = new SubType()
console.log(p1.sayName()) // Uncaught TypeError: p1.sayName is not a function
而原型链继承可以解决这一点:
function SuperType(){}
SuperType.prototype.sayName = ()=>{console.log("bob")}
function SubType(){}
SubType.prototype = new SuperType() // 原型链继承
let p1 = new SubType()
console.log(p1.sayName()) // bob
② 原型链继承的问题:原型中包含的引用值会在所有实例间共享。
function SuperType(){
this.name = ["bob","tom"];
}
function SubType(){}
SubType.prototype = new SuperType() // 原型链继承
let p1 = new SubType()
p1.name.push("jerry")
let p2 = new SubType()
console.log(p2.name) // ['bob', 'tom', 'jerry']
而构造函数继承可以解决这一点:
function SuperType(){
this.name = ["bob","tom"];
}
function SubType(){
SuperType.call(this) // 构造函数继承
}
let p1 = new SubType()
p1.name.push("jerry")
let p2 = new SubType()
console.log(p2.name) // ['bob', 'tom']
class 继承有这两个问题吗??
代码一试便知:
class SuperType{}
SuperType.prototype.sayName = ()=>{console.log("bob")}
class SubType extends SuperType{
}
let p1 = new SubType()
p1.sayName() // bob
问题①,没有问题,在构造函数外写的原型继承,公共方法还是能访问的!!
class SuperType{
constructor(){
this.name=["bob","tom"]
}
}
class SubType extends SuperType{
}
let p1 = new SubType()
let p2 = new SubType()
p1.name.push("Jerry")
console.log(p2.name) // ['bob', 'tom']
问题②,没有问题,在 constructor 的引用值属性,修改不会产生干涉!!
class 继承完美的解决了构造函数继承的问题,和原型链继承的问题,写起来也没有组合继承、寄生继承那么麻烦,如果非得用 JS 模拟面向对象编程,class 必不可少!!
其实写 Class C 和 C.prototype 一起写是很危险的:明明都在操作面向对象的类了,还要操作原型链。类操作和原型操作是两种不同的设计思路,有兴趣可见本瓜一年前的一篇文章:“类”设计模式和“原型”设计模式——“复制”和“委托”的差异
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
小程序全屏滚动字幕效果的实现代码和优化是怎样?在实际项目的操作过程或是学习过程中,不少人都会遇到这样的问题,接下来就让小编带大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
这篇文章主要为大家详细介绍了Vue+Vant实现顶部搜索栏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
这篇文章主要介绍了JavaScript中的语法和代码结构,对JS初学者而言,这些基础一定要看一下
目录前言偏函数传参现状封装 partial运行机制拓展 partial柯里化阶段小结前言承接上一篇《XDM,JS如何函数式编程?看这就够了!(一)》,我们知道了函数式编程的几个基本概念。这里作简要回顾:函数式编程目的是为了数据流更加明显,从而代码更具可读性;函数需要一个或多个输入(理想情况下只需一个!)和一个输出,输入
这篇文章主要为大家介绍了图解Vue的响应式原理,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008