一.关于类/class:
类是一种对象的模板,
ES6
的
class
可以看作只是一个
语法糖
,它的绝大
部分功能,
ES5
都可以做到,新的
class
写法只是让对象原型的写法更加清晰、更像
面向对象编程的语法而已。
特点
:面向对象,具备
属性
与
方法
人: Person
属性: name
展示名字: showName
Person.prototype.showName
ES5 原型写法:
function Person(name,age){
this.name=name;
//定义属性
this.age=age;
}
Person.prototype.showName=function(){
return `person's name is ${this.name}`
}
let p1 = new Person('King', 33);
console.log(p1.showName());
ES6 中变形:
class Person{
//构造类
constructor(name,age){
console.log(`构造函数执行了, ${name}, ${age}`);
// 构造方法(函数), 调用
new,自动执行
}
}
console.log(typeof Person);
//function
let p1 = new Person('Strive',18);
同下↓
const Person = class{
//将类赋中一个表达式
constructor(name,age){
//console.log(`构造函数执行了, ${name}, ${age}`);
this.name = name;
this.age = age;
}
showName(){
return `名字为: ${this.name}`;
}
showAge(){
return `年龄: ${this.age}`;
}
}
注:
构造函数的 prototype 属性,在 ES6 的“类”上面继续存在。事实上,类
的所有方法都定义在类的 prototype 属性上面。
class Point {
constructor() {
// ...
}
toString() {
// ...
}
toValue() {
// ...
}
}
等同于
Point.prototype = {
constructor() {},
toString() {},
toValue() {},
};
注意:
1. ES6 里面 class 没有提升功能,必须在定义好了以后再执行。在 ES5,用函数模拟
可以,默认函数提升
类没有预解析,必须先定义再使用
let p1 = new Person();
console.log(p1.name);
class Person{
constructor(){
this.name ='aaa';
}
}
//Cannot access 'Person' before initialization
2. 类必须使用 new 调用,否则会报错。
class Point {
// ...
}
// 报错
var point = Point(2, 3);
// 正确
var point = new Point(2, 3);
3.实例的属性除非显式定义在其本身(即定义在 this 对象上),否则都是定义在原型
上(即定义在 class 上)。
//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
var point = new Point(2, 3);
point.toString()
// (2, 3)
point.hasOwnProperty('x')
// true
point.hasOwnProperty('y')
// true
point.hasOwnProperty('toString')
// false
point.__proto__.hasOwnProperty('toString')
// true
//彻底理解 JavaScript 原型链(一)—__proto__的默认指向
https://www.jianshu.com/p/686b61c4a43d
矫正 this:
1. fn.call(this 指向谁, args1, args2....)
2. fn.apply(this 指向谁, [args1, args2....])
3. fn.bind()
//只是矫正 this
eg:10
二:关于类的其它用法
1.在“类”的内部可以使用
get
和
set
关键字,对某个属性设置存值函数和取值函数,
拦截该属性的存取行为。
class MyClass {
constructor() {
// ...
}
get prop() {
return 'getter';
}
set prop(value) {
console.log('setter: '+value);
}
}
let inst = new MyClass();
inst.prop = 123;
// setter: 123
inst.prop
// 'getter'
class 里面取值函数(getter), 存值函数(setter),封装框架时用的,eg:10
2.静态方法: 所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上
static 关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态
方法”。
class Foo {
static classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function
3.函数表达式:与函数一样,类也可以使用表达式的形式定义。
let person = new class {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}('张三');
4.类的继承
//父类
function Person(name){
this.name = name;
}
Person.prototype.showName = function(){
return `名字是: ${this.name}`;
};
//子类
function Student(name,skill){
Person.call(this,name);
//继承属性
this.skill = skill;
}
Student.prototype = new Person();
//继承方法
同下↓ ES6
//父类
class Person{
constructor(name){
this.name = name;
}
showName(){
return `名字为: ${this.name}`;
}
}
//子类
class Student extends Person{//es6 的特色
}