class Person{
// 构造
constructor(x,y){
this.x = x;
this.y = y;
}
toString(){
return (this.x + "的年龄是" +this.y+"岁");
}
}
export {Person};
//index.js
import {Person} from './Person';
let person = new Person('张三',);
console.log(person.toString());</span>

1、class初始化定义:

Person 是一个类 ,定义了属性(x,y)与方法 toString()

console.log(typeof Person);//function
console.log(Person === Person.prototype.constructor);//true

so: 类的数据类型就是函数,类本身就指向构造函数, 可以理解为:类就是构造函数 , 因为es5的中 【构造函数 === 构造函数.prototype.constructor】

2、class类的修改与增加属性方法:

构造函数的prototype属性,在ES6的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面,通过以下方式可是覆盖类中的方法,当然定义类的时候也可以通过这个方式添加方法。

Object.assign(Person.prototype,{
getWidth(){
console.log('12');
},
getHeight(){
console.log('24');
}
});
Person.prototype.sex = 'man' ;
console.log(p.sex); // man Person.prototype.sex = 'woman' ;
console.log(p.sex); //woman //class拥有保护机制,可以增加,或覆盖原来有属性,但是如下就不行
Person.prototype == {}
console.log(p.sex); //'woman';
//sex属性还在,prototype从新赋空值这样是不生效的
 

PS建议:class类已经定义完毕不可修改,不可直接修改Person.prototype,个别场景需要,应新建一个继承class上,然后再修改,拓展,新class继承老的class

3、constructor构造函数:

constructor方法是类的构造函数是默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个默认的constructor方法会被添加。所以即使你没有添加构造函数,也是有默认的构造函数的。一般constructor方法默认返回实例对象this,但是也可以指定constructor方法返回一个全新的对象,让返回的实例对象不是该类的实例。

class AA {
sayHello(){console.log('Hello')}
}
class BB{
// 构造
constructor() {
this.x = 'x'
return new AA();
}
sayX(){console.log(this.x)}
}
let b = new BB();
b.sayHello(); // hello
b.sayX(); //TypeError: b.sayX is not a function

4、类的构造函数,不使用new是没法调用的,使你使用实例对象去调用也是不行,这是它跟普通构造函数的一个主要区别。实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上);

class Person{
// 构造
constructor(x,y){
this.x = x;
this.y = y;
} toString(){
return (this.x + "的年龄是" +this.y+"岁");
}
}
let p = new Person('lis',8);
console.log(p.hasOwnProperty('x'));// true
console.log(p.hasOwnProperty('toString'));//false
//x,y是定义在this对象上,toString定义在类上。

4.1、类内部定义的方法(Person的toString方法),ES6中它是不可枚举的,这一点与ES5的行为不一致,ES5是可以枚举的。

Object.assign(Person.prototype,{
getWidth(){
console.log('');
},
getHeight(){
console.log('');
}
}); //ES5
console.log(Object.keys(Person.prototype));//["toString", "getWidth", "getHeight"]
console.log(Object.getOwnPropertyNames(Person.prototype));//["constructor", "toString", "getWidth", "getHeight"] //ES6
console.log(Object.keys(Person.prototype));//["getWidth", "getHeight"] 没有toString 可以用getOwnPropertyNames
console.log(Object.getOwnPropertyNames(Person.prototype));//["constructor", "toString", "getWidth", "getHeight"]
//
//Object.keys(obj),返回数组里是该obj可被枚举的所有属性。Object.getOwnPropertyNames(obj),返回数组里是该obj上所有的实例属性。

5、可以通过实例的__proto__属性为Class添加方法(绝不推荐)。

let person1 = new Person('李四',13);
person1.__proto__.getH = function (){
return "Height";
};
console.log(person1.getH());

6、class不存在变量提升,需要先定义再使用,因为ES6不会把类的声明提升到代码头部,但是ES5就不一样,ES5存在变量提升,可以先使用,然后再定义。

new A();
function A(){ }//ES5可以先使用再定义,存在变量提升
//错误
new B();
class B{ }//B is not a constructor
//ES6不能先使用再定义,不存在变量提升

7、const Expression = class Expre  谁才是真的class名,下边这个类的名字是Expression而不是Expre,Expre只在Class的内部代码可用,指代当前类。

const Expression = class Expre{
static getAge(){
return '12';
}
getClassName(){
return " ClassName1= " +Expre.name + " ClassName2= " +Expression.name;
}
}; let exp = new Expression();
//let exp = new Expre();错误
//bundle.js:7935 Uncaught ReferenceError: Expre is not defined
console.log(exp.getClassName());//ClassName1= Expre ClassName2= Expre
//console.log(Expre.getAge());错误
//bundle.js:7935 Uncaught ReferenceError: Expre is not defined
console.log(Expression.getAge()) //也可以这么写
//说明:如果省略了class后面的那个名字Expre,MyExpre.name返回的就是MyExpre,如果没有省略MyExpre.name返回就是class后面的那个名字Expre。
const MyExpre = class{
getClassName(){
return MyExpre.name;
}
};

8、采用Class表达式,可以写出立即执行的Class

let person = new class{
// 构造
constructor(props) {
this.props = props;
}
getProps(){
return this.props;
}
}('构造函数的参数');
console.log(person.getProps());//构造函数的参数

9、私有方法的需求:

私有方法是常见需求,但ES6不提供,只能通过变通方法模拟实现。一种做法是在命名上加以区别,在方法前面加上_(下划线),表示这是一个只限于内部使用的私有方法。但是,这种命名是不保险的,在类的外部,还是可以调用到这个方法。另一种方法就是索性将私有方法移出模块,因为模块内部的所有方法都是对外可见的。

export default class PrivateMethod{
// 构造
constructor() {
}
getName(){
priName();
}
} function priName(){
console.log('私有方法测试');
}
//index.js
import PriMe from './PrivateMethod';
let prime = new PriMe();
prime.getName();

10、类内部this指向问题:

类的方法内部如果含有this,它默认指向类的实例。getName方法中的this,默认指向ThisStu类的实例。但是,如果将这个方法提取出来单独使用,this会指向该方法运行时所在的环境,因为找不到name方法而导致报错。

class ThisStu{
getName(){
return this.name();
}
name(){
return '王五';
}
} let thisStu = new ThisStu();
console.log(thisStu.getName()); //王五
const {getName} = thisStu;
getName(); //Cannot read property 'name' of undefined

一个比较简单的解决方法是,在构造方法中绑定this,这样就不会找不到name方法了。

class ThisStu{
constructor() {
this.getName = this.getName.bind(this);
}
getName(){
return this.name();
}
name(){
return '王五';
}
} //或者 用剪头函数 在构造函数,直接给当前实例的getName赋值
class ThisStu1{
constructor() {
this.getName = ()=>{
return this.name();
}
}
name(){
return '王五';
}
}

11、Class类的静态方法  static的定义

类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。

//定义静态方法
static getAge(){
return '获取Age的静态方法';
}
//通过类名直接调用
console.log(StaticMethod.getAge());

如果StaticMethod继承StaticMethodParent,StaticMethodParent的静态方法,可以被StaticMethod继承。

export default class StaticMethodParent{
static getCommon(){
return '父类的静态方法';
}
}
//通过子类直接调用
console.log(StaticMethod.getCommon());
如果StaticMethod继承StaticMethodParent,StaticMethodParent的静态方法,可以在StaticMethod中用super调用。
//定义静态方法
static getAge(){
//子类可以调用父类的静态方法
console.log(super.getCommon());
return '获取Age的静态方法';
}

说明:静态方法只能在静态方法中调用,不能再实例方法中调用。

参考资料地址:https://blog.csdn.net/pcaxb/article/details/53759637

http://es6.ruanyifeng.com/#docs/class

ES6 的class类 笔记的更多相关文章

  1. es6入门5--class类的基本用法

    在ES6之前,准确来说JavaScript语言并无类的概念,却有模拟类的做法.相比在类似java这类传统面向对象语言中通过类来生成实例,js则通过构造函数模拟类来生成实例. 这是因为在JS设计初期,作 ...

  2. Nodejs与ES6系列4:ES6中的类

    ES6中的类 4.1.class基本语法 在之前的javascript语法中是不存在class这样的概念,如果要通过构造函数生成一个新对象代码 function Shape(width,height) ...

  3. ES6中的类

    前面的话 大多数面向对象的编程语言都支持类和类继承的特性,而JS却不支持这些特性,只能通过其他方法定义并关联多个相似的对象,这种状态一直延续到了ES5.由于类似的库层出不穷,最终还是在ECMAScri ...

  4. 深入理解ES6之——JS类的相关知识

    基本的类声明 类声明以class关键字开始,其后是类的名称:剩余部分的语法看起来像对象字面量中的方法简写,并且在方法之间不需要使用逗号. class Person { //等价于prototype的构 ...

  5. ES6中的类和继承

    class的写法及继承 JavaScript 语言中,生成实例对象的传统方法是通过构造函数.下面是一个例子     function Point(x, y) {  this.x = x;  this. ...

  6. ES6中的类继承和ES5中的继承模式详解

    1.ES5中的继承模式 我们先看ES5中的继承. 既然要实现继承,首先我们得要有一个父类. Animal.prototype.eat = function(food) { console.log(th ...

  7. 160803、如何在ES6中管理类的私有数据

    如何在ES6中管理类的私有数据?本文为你介绍四种方法: 在类的构造函数作用域中处理私有数据成员 遵照命名约定(例如前置下划线)标记私有属性 将私有数据保存在WeakMap中 使用Symbol作为私有属 ...

  8. ES6里关于类的拓展(二):继承与派生类

    继承与派生类 在ES6之前,实现继承与自定义类型是一个不小的工作.严格意义上的继承需要多个步骤实现 function Rectangle(length, width) { this.length = ...

  9. ES6里关于类的拓展(一)

    大多数面向对象的编程语言都支持类和类继承的特性,而JS却不支持这些特性,只能通过其他方法定义并关联多个相似的对象,这种状态一直延续到了ES5.由于类似的库层出不穷,最终还是在ECMAScript 6中 ...

随机推荐

  1. Linux下多网卡绑定bond0及模式

    Linux 多网卡绑定 网卡绑定mode共有七种(0~6) bond0.bond1.bond2.bond3.bond4.bond5.bond6 常用的有三种 mode=0:平衡负载模式,有自动备援,但 ...

  2. AKKA事件机制

    AKKA Event Bus 事件机制就用于当前运行环境,与集群环境不同,详细见AKKA 集群中的发布与订阅Distributed Publish Subscribe in Cluster 简单实现示 ...

  3. mysql密码中有特殊字符&在命令行下登录

    在服务器上,通常为了快速登录数据库,我们会使用mysql -hhost -uusername -ppassword db的方式登录数据库,如果密码中没有特殊字符&,会直接进入数据库sql命令行 ...

  4. GoLang 开山篇

    GoLang 开山篇 1.Golang 的学习方向 Go语言,我们可以简单的写成Golang. 2.GoLang 的应用领域 2.1 区块链的应用开发 2.2 后台的服务应用 2.3 云计算/云服务后 ...

  5. 单口 RAM、伪双口 RAM、真双口 RAM、单口 ROM、双口 ROM 到底有什么区别呢?

    打开 IP Catalog,搜索 Block Memory Generator,即可看到其 Memory Type 可分为 5 中,分别是单口 RAM(Single Port RAM).伪双口 RAM ...

  6. mybatis-plus-generator 模板生成代码

    maven: <dependencies> <dependency> <groupId>com.baomidou</groupId> <artif ...

  7. python实现Huffman编码

    一.问题 利用二叉树的结构对Huffman树进行编码,实现最短编码 二.解决 # 构建节点类 class TreeNode: def __init__(self, data): "" ...

  8. - 集合 遍历 foreach Iterator 并发修改 ConcurrentModificationException MD

    目录 目录 为什么不能在 foreach 循环里进行元素的 remove/add 操作 背景 foreach 循环 问题重现 fail-fast remove/add 做了什么 正确姿势 直接使用普通 ...

  9. Web前端推荐学习站点

    http://javascript.ruanyifeng.com/   JavaScript参考标准教程,写的很不错. https://www.xiaohuochai.cc/  小火柴前端站 http ...

  10. python3对字符串进行base64转码

    import base64# 使用base64的b64encode()进行转码,转码之后在用‘utf-8’解码# s 要转码的字符串res = base64.b64encode(s.encode(&q ...