IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> ES6特性:类Class -> 正文阅读

[JavaScript知识库]ES6特性:类Class

Class类

1、简介

JavaScript 语言中,生成实例对象的传统方法是通过构造函数。 ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰更像面向对象编程的语法而已所以ES6 的类,完全可以看作构造函数的另一种写法。例如:

ES5中写法

// 通常形式下的构造方法
function Person(name,age){
    this.name = name;
    this.age = age;
}

// 添加方法
Person.prototype.speak = function(){
    console.log("我可以说话!!");
}

// 创建对象
let p1 = new Person("小明",29);
p1.speak(); // 我可以说话!!
console.log(p1); // Person { name: '小明', age: 29 }

在ES6中可以写成

class Person{
  constructor(name,age){
    this.name = name;
    this.age = age;
  }
  speak(){
    console.log("我可以说话!!");
  }
}

let p1 = new Person("小明",29);
p1.speak(); // 我可以说话!!
console.log(p1); //Person { name: '小明', age: 29 }

2、构造函数construct

constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。

class Person{
}
//等同于:
class Person{
  // 构造函数
  constructor(){}
}

3、实例属性和方法

定义在类体中的属性称为实例属性,定义在类体中的方法称为实例方法。实例方法本质上是在prototype原型中的,所以所有的实例都可以调用。

class Person{
    //共同的实例属性
    temp = 'hello';

    constructor(name,age){
      // 每个实例独有的实例属性  常用
      this.name = name;
      this.age = age;

      // 每个实例独有的实例方法 ,写在构造函数里面
      this.sayName = function(){
        console.log("i am ",this.name);
      }
    }

  }
  //创建对象
  let p1 = new Person('Ronda',22);
  let p2 = new Person('Fairy',23);

  console.log(p1.sayName === p2.sayName);  
  // false 因为是实例方法,所有每个实例内都会有自己的方法
  console.log(p1.name);  // Ronda
  console.log(p1.temp);  // hello
  p1.sayName();  // i am Ronda
  console.log(p2.name);  // Fairy
  console.log(p2.temp);  // hello
  p2.sayName();  // i am Fairy

学到这里可以发现js和java语言的形式越来越像了

4、原型属性和方法

就是在构造函数的原型对象上存在的属性和方法。

class Person{
    constructor(name,age){
        this.name = name;
        this.age = age;
    }

    //原型方法:写在构造函数外面
    sayName(){
        console.log("i am ",this.name);
    }
}

//设置原型属性:在类class外面设置
Person.prototype.temp = "hello";

//创建对象
let p1 = new Person('Randa',22);
let p2 = new Person('fairy',23);

p1.sayName(); //调用原型方法
console.log(p1.sayName === p2.sayName); 
//true 因为sayName()方法来自同一个原型

console.log(p1.temp); //hello
console.log(p2.temp); //hello

5、静态属性和方法

通过static关键字来定义静态属性和静态方法。静态属性和静态方法是定义在类上的,所以可以通过类直接访问。在静态方法中,this指向当前类

class Person {
  // 静态属性
  static num = 200;
  // 静态方法
  static number() {
    console.log(this); // [class Person] { num: 200 }
    return this.num; //200
  }
}
console.log(Person);  // [class Person] { num: 200 }
console.log(Person.number());	//200
console.log(Person.num);	//200

6、继承

class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要简洁很多。
子类中可以没有构造函数,系统会默认提供一个。子类如果提供了构造函数就必须显示调用super。super函数类似于之前的借用构造函数,并且子类必须在constructor方法中调用super方法,否则新建实例时会报错。因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象

// 父类
class Animal { 
	//构造函数
	constructor(name){
      this.name = name;
	}
	//原型方法
	sayName(){
      console.log("my name is ",this.name);
	}
}

//Dog类继承Animal类
class Dog extends Animal{
	constructor(name,age){
	 //Dog类中没有name,要使用super引入
      super(name); 
      this.age = age;
	}
}

//创建dog对象
let dog = new Dog('乐乐','1');
dog.sayName();
// 打印出:my name is  乐乐

console.log(Dog);//[class Dog extends Animal]
console.log(Dog.prototype);//Animal{} 
console.log(Object.getPrototypeOf(Dog));//[class Animal]
console.log(Object.getPrototypeOf(Dog.prototype));//{}
console.log(Dog.__proto__ === Animal);  //true
console.log(Dog.prototype.__proto__ === Animal.prototype);  //true

class 作为构造函数的语法糖,同时有prototype属性和__proto__属性,因此同时存在两条继承链
1.子类的__proto__属性,表示构造函数的继承,总是指向父类。
2.子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。

下面是ES5中的对象继承的实现

// 构造方法 : 用于构造父类普通手机
function Phone(brand,price){
    this.brand = brand;
    this.price = price;
}

// 在原型中添加方法
Phone.prototype.call = function(){
    console.log("打电话");
}

// 子类,智能手机
function SmartPhone(brand,price,color,size){
    Phone.call(this,brand,price); // 这里this指向父类Phone,会对brand和price进行初始化
    this.color = color;
    this.size = size;
}

// 设置自己构造函数的原型
SmartPhone.prototype = new Phone;
SmartPhone.prototype.constructor = SmartPhone;

// 声明子类的方法
SmartPhone.prototype.photo = function(){
    console.log("拍照");
}

SmartPhone.prototype.playGames = function(){
    console.log("打游戏");
}

// 创建子类实例
const oppo = new SmartPhone("oppo",2000,"white",'5.5inch');
console.log(oppo);

结果:
SmartPhone {
brand: ‘oppo’,
price: 2000,
color: ‘white’,
size: ‘5.5inch’
}

super关键字使用

super这个关键字,既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同。

  • 第一种情况,super作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。
class A {}

class B extends A {
  constructor() {
    super();
  }
}
  • 第二种情况,super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。
class A {
  p() {
    return 2;
  }
}

class B extends A {
  constructor() {
    super();   // 这里 super() 代表调用父类构造函数
    console.log(super.p()); // 2  这里的super是对象,因为在普通方法constructor内使用,所以super对象是父类的原型对象
  }
}

let b = new B();

需要注意,由于super指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过super调用的,例如:

class A {
  constructor() {
    this.p = 2;
  }
}
class B extends A {
  m() {
    return super.p; //这里super指向父类原型对象,而原型对象中没有定义p
  }
}

let b = new B();
console.log(b.m())  // undefined
console.log(b.p); // 2

例如super指向父类本身的情况

class A {
  // 静态属性
  static num = 200;
  constructor() {
    this.num = 20;
  }
  // 静态方法
  static number() {
    return this.num;
  }
}
class B extends A {
  static getNumber() {
    // super是A类本身
    return super.number();
  }
}
console.log(B.getNumber());  //200

7、子类对父类方法的重写

class Phone{
    constructor(brand,price){
        this.brand = brand;
        this.price = price;
    }

    call(){
        console.log("我可以打电话");
    }
}

class SmartPhone extends Phone{
    constructor(brand,price,color){
        super(brand,price);
        this.color = color;
    }

    // 重写父类中的方法
    call(){
        console.log("我可以打视频电话");
    }
}

const oppo = new SmartPhone("oppo","2000","white");
oppo.call();
console.log(oppo);
/* 
我可以打视频电话
SmartPhone { brand: 'oppo', price: '2000', color: 'white' }
*/

需要注意:
(1)子类并不能使用super关键字直接调用父类中的成员方法
(2)子类只能完完全全的重写父类中的成员方法,并且在调用时调用的是重写后的方法

8、setter和getter

和java中的get方法和set方法类似,get获取值,set设置值,并且是动态的

class Phone{
    // 将price属性绑定在函数上
    // get获取price属性中的值
    get price(){
        console.log("价格属性被读取了");
        // get 中需要有一个return返回值
        return '返回值';
    }

    // set动态设置值,要传入参数
    set price(price){  
        console.log("价格属性被修改了");
    }
}

// 实例化对象
let phone = new Phone();

// 可以修改该属性值,此时会触发set方法,如果不修改,则不会触发set
phone.price = 'free';

console.log(phone.price); 

结果:
价格属性被修改了
价格属性被读取了
返回值

9、私有属性

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        class Person {
            // 公有属性
            name;
            // 私有属性
            #age;
            #weight;

            // 构造方法
            constructor(name, age, weight) {
                this.name = name;
                this.#age = age;
                this.#weight = weight;
            }
            /*
            通过让实例对象调用这个公共方法让私有属性可以在外面被访问
			intro(){
				console.log(this.name);
				console.log(this.#age);
				console.log(this.#weight);
			}
			*/
        }

        const girl = new Person("小红", 12, '45kg');
        console.log(girl);

        console.log(girl.name);
        console.log(girl.#age); // 报错
        console.log(girl.#weight); // 报错
        
        girl.intro();
    </script>
</body>
</html>
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-15 11:32:29  更:2022-05-15 11:33:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:54:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码