前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >ES6之class基本语法

ES6之class基本语法

作者头像
wade
发布于 2020-04-23 09:06:24
发布于 2020-04-23 09:06:24
28400
代码可运行
举报
文章被收录于专栏:coding个人笔记coding个人笔记
运行总次数:0
代码可运行

类这个概念对于做后台的应该是非常熟悉,JavaScript的类对于其他面向对象的语言差异很大,只能使用构造函数生成实例对象。为了接近传统语言,ES6引入了class类这个概念,通过class关键字定义类。

Class其实是一个语法糖,几乎所有功能都可以用其他方法实现,只是让代码更清晰,更像面向对象编程。

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class User{ 
  constructor(){ 
   console.log('默认调用'); 
  } 
  eat(){ 
    console.log('eat方法'); 
  }
}var user = new User();//默认调用
user.eat()//eat方法

注意,类的方法是不能加function关键字,方法之间也不能用逗号分隔,不然会报错。类的所有方法都定义在类的prototype方法。在类的实例调用方法就是调用原型上的方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class User{ 
  eat(){}
}

等同于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function User() {}
User.prototype.eat = function () {}

类内部定义的方法都是不可枚举的,这跟ES5不一样。

Constructor方法:

这个方法是默认方法,通过new生成实例对象的时候自动调用,每个类都会有,如果没有显式定义,会自动添加一个空的constructor方法。默认返回实例对象,也就是this。你也可以返回另外的对象,这跟构造函数是一样的。类必须使用new调用,而我们的构造函数还能当做方法直接调用。

与 ES5 一样,实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上),类的所有实例共享一个原型对象,因此一个实例对象通过原型__proto__改写了原型,所有实例对象都会改变,所有不推荐使用实例的__proto__改写原型。

同样的,getter函数和setter函数也可以在类里面使用关键字get和set:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class User{ 
  constructor(){ 
    this.name = 'wade'; 
   }    get eat(){ 
   return '这是get'; 
  } 
  set eat(val){ 
   console.log('set调用了'); 
  }
}
var user = new User();
user.eat = 3//set调用了
console.log(user.eat);//这是get

表达式:

属性可以用[]表达式,这个跟对象是一样的,类也可以直接用表达式定义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var val = 'my'
var User = class Muser{ 
 [val](){ 
     }
}

Muser只能在class内部可用,class外部使用User。如果内部不使用,也可以省略Muser或者立即执行class:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var User = class {}
var user = new class{}()

要注意,class默认就是严格模式,而且不存在变量提升,name的属性也是返回class关键字后面的类名,还可以使用Gernerator方法。类方法内部的this默认指向类的实例,单独拿出来使用会报错。

类的方法前面加上static关键字,那么这个方法不会被实例继承,可以通过类调用,这个方法叫做静态方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class User{ 
  static eat(){ 
   console.log('eat'); 
  }
}var user = new User();
console.log(user.eat());//报错
User.eat()//eat

如果静态方法包含this关键字,这个this指的是类,而不是实例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class User{ 
  static eat() { 
    this.say(); 
  } 
  static say() { 
    console.log('hello'); 
  } 
  say() { 
   console.log('world'); 
  }
}
User.eat() // hello

静态方法和非静态方法还可以重名。静态方法是可以被子类继承的。

实例属性除了定义在constructor里面,还能直接定义在最顶层:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class User1{ 
  constructor(){ 
    this.name = 'wade'; 
  }
}
class User2{ 
  name = 'kobe';
}
console.log(new User1().name);//wade
console.log(new User2().name);//kobe

Class本身的属性叫做class的静态属性,Class.propName,不是定义在实例对象this上的属性。Class内部只有静态方法没有静态属性,现在只有一种写法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class User{};User.prop = 1;

但是有提案使用static定义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class User{ 
  static prop = 1;
};

从代码组织原则和声明来看,这样的写法无疑是更好的。

我们都知道代码封装私有属性和私有方法是很重要的,但是ES6的class暂时是没有提供的。变通的解决方法比如区分命名、方法移出模块、用symbol变量等。但都不是很好。现在有个提案,使用#来提供私有属性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class User{ 
  #prop = 1; 
 #eat(){}
};

只能在内部使用,外部访问就报错。私有属性也可以设置 getter 和 setter 方法。私有属性不限于从this引用,只要是在类的内部,实例也可以引用私有属性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class User{ 
  #prop = 1; 
  static eat(user){ 
   console.log(user.#prop); 
  }
};
User.eat(new User());//1

new是从构造函数生成实例对象的命令。ES6 为new命令引入了一个new.target属性,该属性一般用在构造函数之中,返回new命令作用于的那个构造函数。如果构造函数不是通过new命令或Reflect.construct()调用的,new.target会返回undefined,因此这个属性可以用来确定构造函数是怎么调用的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function User() { 
  console.log(new.target === User);//true 
  console.log(new.target !== undefined);//true
}
var user = new User();

如果不是new:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function User() { 
  console.log(new.target === User);//false 
  console.log(new.target !== undefined);//false
}
User();

Class 内部调用new.target,返回当前 Class:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class User{ 
  constructor(){ 
    console.log(new.target === User)//true 
  }
}
new User();

子类继承父类时,new.target会返回子类。利用这个特点,可以写出不能独立使用、必须继承后才能使用的类。

(完)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 coding个人笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档