这是我参与更文挑战的第12天,活动详情查看:更文挑战
[重学JavaScript系列文章连载中…]
传统JavaScript没有类的概念,只有对象。为了让JavaScript更像一门面向对象的语言,ES6引入了Class(类)的概念,通过class关键字定义类。
先看个使用es5构造函数创建实例以及class创建实例的对比:
// es5构造函数
function Person(name,age){
// 实例属性
this.name = name
this.age = age
}
// 原型属性
Person.prototype.tag = 'man'
// 原型方法
Person.prototype.say = function(){
console.log(this.name+'在说话')
}
var p = new Person('张三',18)
p.say() // 张三在说话
复制代码
// ES6 class写法
class Person1{
// 构造函数
constructor(name,age){
// 实例属性
this.name = name
this.age = age
}
// 原型属性
tag = 'man'
// 原型方法
say(){
console.log(this.name+'在说话')
}
}
var p1 = new Person1('李四',18)
p1.say() // 李四在说话
p1.say === Person1.prototype.say // true
typeof Person1 // 'function'
复制代码
从例子中,可以看出class
本质还是函数,p1
实例的say
属性与Person1
类原型中的say
属性是相等的。
实际上class
的属性和函数也都是定义在prototype
属性中,只是ES6将prototype
属性相关操作封装在class
中,省去了我们之间操作prototype
属性。
静态属性和方法
静态属性和方法使用static关键字修饰,只能通过类本身使用,不能被实例访问。
class Person{
static name = 'class'
static getName(){
console.log('static getName')
}
}
// 通过类本身可以访问到
Person.name // 'class'
Person.getName // 'static getName'
// 通过实例访问不到
let p = new Person()
p.name // undefined
p.getName() // undefined
复制代码
这个例子我们没有声明构造函数,为啥没报错呢?因为没声明时,会自动隐式添加一个空的构造函数。
继承
ES6可以通过extends关键字实现类的继承。
// 父类
class Person{
constructor(name,age){
this.name = name
this.age = age
}
static tag = 'person'
getName(){
return this.name
}
}
// 子类
class Boy extends Person{
constructor(name,age,sex){
// 执行父类构造函数
super(name,age)
this.sex = sex
}
getSex(){
return this.sex
}
}
var b = new Boy('张三',18,'男')
b.getName() // '张三'
b.getSex() // '男'
b.tag // undefined
Boy.tag // 'person'
复制代码
父类的静态函数无法被实例继承,但可以被子类继承,子类可以通过自身去访问,而不是通过子类实例。
注意点:
- class只能与new关键字配置使用
class Person(){}
new Person() // 正确
Person() // 报错:类构造器无法执行
复制代码
- class定义类不存在变量提升
var p = new Person() // 报错:Person没有定义
class Person(){}
复制代码
- 类中声明函数,不需要加function关键字
class Person(){
say function(){ // 语法错误:UnExpected token function
}
}
复制代码
- this指向问题
class Person(){
constructor(name){
this.name = name
}
getName(){
return this.name
}
}
const {getName} = new Person('张三')
getName() // 报错:Cannot read property 'name' of undefined
复制代码
getName()
函数是在全局环境中执行,this
指向的是全局环境。但ES6的class
关键字中使用了严格模式,而严格模式下this
不能指向全局环境,而是指向undefined
,所以通过undefined
应用name就报错。
解决办法:在构造函数中重新绑定this
class Person{
constructor(name){
this.name = name
// 重新绑定getName函数中的this指向实例
this.getName = this.getName.bind(this)
}
getName(){
return this.name
}
}
const {getName} = new Person('张三')
getName() // 张三
复制代码
自此我们学习了ES6的class
关键字。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END