JavaScript Class类实例讲解

目录
  • Class类
  • 初识class
  • class中getter和setter设置
  • 表达式方式书写
  • 静态属性与静态方法
  • 私有属性和私有方法
  • class继承
  • 静态属性和方法继承
  • 私有属性和方法继承
  • class显示原型与隐式原型关系

Class类

ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰,更像面向对象编程的语法。

初识class

之前ES5通过构造函数实现实例化的方法

<script>
    // 定义人类
    function People(name,age){
        this.name = name
        this.age = age
    }
    // 添加方法
    People.prototype.say = function (){
        console.log('hello world');
    }
    // 实例化方法
    let person = new People('张三',18)
    person.say()//hello world
    console.log(person);//People {name: '张三', age: 18}
</script>

ES6 class方法实现

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

<script>
    // class
    class People {
        // 构造方法 名字是固定格式不能修改
        constructor(name,age){
            this.name = name
            this.age = age
        }
        // 方法必须使用该语法,不能使用 ES5 的对象完整形式
        say(){
            console.log('hello world');
        }
    }
    // 实例化对象
    let person = new People('张三',18)
    person.say()//hello world
    console.log(person);//People {name: '张三', age: 18}
</script>

class中getter和setter设置

在ES6中,类的内部可以使用 getter (取值函数) 和 setter (存值函数) 关键字,即 get 和 set ,对某个属性设置取值函数和存值函数,拦截该函数的存取行为。

<script>
    class People {
        get name(){
            console.log('我是张三');
            return '这是我的名字'//如果不写return,默认是undefined
        }
        set name(Name){//形参必须有
            console.log('我的名字被修改了');
        }
    }
    // 实例化对象
    let p = new People()
    // 只要读取 p 的实例化属性,就会执行 get 关键字函数里面代码,而且这个函数的返回值就是属性的一个值
    console.log(p.name);
    // 只要对 name 属性进行一个修改,如果有set关键字函数,就会执行该函数
    p.name = 'f'
</script>

表达式方式书写

和函数一样,类可以用表达式定义书写,需要注意的是:定义的类名只能在Class内部使用,指代当前类,在Class外部,类只能用自己定义等于类的常量。

<script>
    const myClass = class Me {
        getClass(){
            return Me.name//返回类名
        }
    }
    let c = new myClass()
    console.log(c.getClass())//Me
    Me.name//Me is not defined
    // 如果类的内部没用到的话,可以省略Me,也就是可以写成下面的形式
    const MyClass = class {};
</script>

静态属性与静态方法

静态属性是指 Class 本身的属性,即 Class.propName,而不是定义在实例对象 this 上的属性。

实例对象和函数对象的属性是不相通的,实例对象的属性和构造函数的原型对象相通,实例对象只能继承构造函数原型中的属性和方法。

<script>
    function People(){
    }
    // 函数属性和方法
    People.name = '张三'
    People.say = function(){
        console.log('hello world');
    }
    // 原型对象属性和方法
    People.prototype.age = 18
    // 实例化对象
    let p = new People()
    console.log(People.name,People.say());
    console.log(p.age);
    console.log(p.name,p.say());
</script>

以class方法展示,因为ES6明确规定,Class内部只有静态方法,没有静态属性,而要想得到设置静态属性,需要在实例属性前面加上 static 关键字;静态方法也要加上 static 关键字,表示该方法不会被实例继承,而是直接通过类来调用。

<script>
    class People {
        // 静态属性
        static name = '张三'
        static say(){
            console.log('hello world');
        }
    }
    let p = new People()
    console.log(p.name);//undefined
    console.log(People.name);//张三
</script>

私有属性和私有方法

常见需求:私有属性和方法,是只能在类内部访问的属性和方法,外部不能访问,有利于代码的封装。

ES6中正式为class添加了私有属性和方法,方法是在属性和方法名之前使用 # 表示,如果不带 # ,会被当作另一个属性和方法。

<script>
    class person {
        // 私有属性
        #name
        constructor(name){
            this.#name = name
        }
        // 私有方法
        #sayName(){
            return this.#name
        }
        result(){
            console.log(this.#name);
        }
    }
    let p = new person()
    p.result = '张三'
    console.log(p);//person {result: '张三', #sayName: ƒ, #name: undefined}
    p.#name//报错
</script>

当我们想判断某个类的私有属性是否存在时,我们可以用 in 运算符进行判断。

<script>
    class A {
        #foo = 0;
        m() {
            console.log(#foo in this); // true
            console.log(#bar in this); // Private field '#bar' must be declared in an enclosing class(提示我们:私有字段“#bar”必须在封闭类中声明)
        }
    }
    let a = new A()
    a.m()
</script>

class继承

构造函数实现继承

通过原型链进行继承,如果有不熟悉原型链的朋友,可以看一下我之前的文章:原型和原型链

<script>
    // 动物
    function Animals(name,age){
        this.name = name
        this.age = age
    }
    Animals.prototype.call = function(){
        console.log('我是动物');
    }
    // 狗
    function Dog(name,age,color,gender){
        // 改变this的指向,继承父类
        Animals.call(this,name,age)
        this.color = color
        this.gender = gender
    }
    // 设置子类构造函数的原型
    Dog.prototype = new Animals //此时子类的实例对象就会继承父类上面的方法
    Dog.prototype.constructor = Dog

    // 声明子类的方法
    Dog.prototype.say = function(){
        console.log('汪汪汪!!!');
    }
    // 子类对象进行实例化
    const d = new Dog('小明',3,'棕色','雄')
    console.log(d);
</script>

class类实现继承

class可以通过 extends 关键字实现继承,让子类继承父类属性和方法,可以看出 extends 的写法比上文 原型链继承 清晰方便的多。

<script>
    class Animals {
        // 构造方法
        constructor(name,age){
            this.name = name
            this.age = age
        }
        // 父类成员的属性
        call(){
            console.log('我是动物');
        }
    }
    class Dog extends Animals {
        // 构造方法
        constructor(name,age,color,gender){
            // 调用父类方法,需要用super(),super()就是父类的constructor()方法
            super(name,age)
            this.color = color
            this.gender = gender
        }
        // 子类独有的方法
        say(){
            console.log('汪汪汪!!!');
        }
        // 当子类和父类重名时,优先调用的是子类的方法
        call(){
            console.log('我也是动物');
            // 如果想调用父类方法,使用如下语句:super.父类方法()
            super.call()
        }
    }
    // 实例化子类对象
    const d = new Dog('小明',3,'棕色','雄')
    console.log(d);
    d.call()
    d.say()
</script>

super 关键字

上面代码用到 super 这个关键字,这里简单说明一下:子类继承父类的 constructor() 构造函数中必须要有 super(),代表调用父类的构造函数,没有就会报错,super虽然代表父类的构造函数,但是返回的是子类的实例,即super内部的this指的是子类的实例。作为函数时,super() 只能用在子类的构造函数中,用在其他地方就会报错。

判断继承是否存在

Object.getPrototypeOf()方法可以用来从子类上获取父类,所以可以用来判断一个类是否继承另一个类。

<script>
    class people {}
    class boy extends people {}
    console.log(Object.getPrototypeOf(boy) === people);//true
</script>

静态属性和方法继承

父类的静态属性和方法也能被子类继续,如下:

<script>
    class people {
        // 父类静态属性 属性为数值
        static age = 18
        // 父类静态属性 属性为对象
        static h = {height:180}
        // 父类静态方法
        static say(){
            console.log('hello world');
        }
    }
    // 子类继承父类
    class boy extends people {
        constructor(){
            // 调用父类的构造函数
            super()
            // boy类继承静态属性时,会采用浅拷贝,拷贝父类静态属性的值,因此people.age和boy.age是两个彼此独立的属性。
            boy.age--
            // 如果父类的静态属性的值是一个对象,那么子类的静态属性也会指向这个对象,因为浅拷贝只会拷贝对象的内存地址所以,子类修改这个对象的属性值,会影响到父类。
            boy.h.height--
        }
    }
    // 实例化子类
    let b = new boy()
    boy.say()
    console.log(people.age);
    console.log(boy.age);
    console.log(boy.h.height);
    console.log(people.h.height);
    console.log(b);
</script>

私有属性和方法继承

私有属性和方法只能定义在它本身的class里面使用,所以子类会继承父类所有的属性和方法除了私有属性和方法,那么如何让子类访问到父类中的私有属性和方法呢?如果父类定义了私有属性的读写方法,子类就可以通过这些方法,读取私有属性。

<script>
    class people {
        #name = '张三'
        // 定义用来读取私有属性和方法的函数
        getName(){
            return this.#name
        }
    }
    class boy extends people {
        constructor(){
            // 调用父类的构造函数
            super()
            console.log(this.getName());//张三
        }
    }
    let b = new boy()
</script>

class显示原型与隐式原型关系

每个对象都有隐式原型 __proto__ 属性,指向对应的构造函数的显示原型 prototype 属性,class作为构造函数的语法糖,同时也具有 prototype 属性和 __proto__ 属性,所以存在两条继承链。当然这里这做一个了解。

<script>
    class people {}
    class boy extends people{}
    // 子类的__proto__属性,表示构造函数的继承,总是指向父类。
    console.log(boy.__proto__ === people); // true
    // 子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。
    console.log(boy.prototype.__proto__ === people.prototype); // true
</script>

到此这篇关于JavaScript Class类实例讲解的文章就介绍到这了,更多相关JS Class类内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • ES6 javascript中Class类继承用法实例详解

    本文实例讲述了ES6 javascript中Class类继承用法.分享给大家供大家参考,具体如下: 1. 基本用法 Class 之间可以通过extends关键字实现继承, 这比 ES5 的通过修改原型链实现继承, 要清晰和方便很多. class ColorPoint extends Point {} 上面代码定义了一个ColorPoint类, 该类通过extends关键字, 继承了Point类的所有属性和方法. 但是由于没有部署任何代码, 所以这两个类完全一样, 等于复制了一个Point类. 下

  • JavaScript ES6 Class类实现原理详解

    JavaScript ES6之前的还没有Class类的概念,生成实例对象的传统方法是通过构造函数. 例如: function Mold(a,b){ this.a=a; this.b=b; } Mold.prototype.count=function(){ return this.a+this.b; }; let sum=new Mold(1,2); console.log(sum.count()) //3 这中写法跟传统的面向对象语言差异较大,写起来也比较繁杂. ES6提供了更加接近其他语言的

  • 详解用JS添加和删除class类名

    下面介绍一下如何给一个节点添加和删除class名 添加:节点.classList.add("类名"): 删除:节点.classList.remove("类名"): 以tab切换为例: 在写tab切换的时候,通常我们会给选中的tab设置不同的样式,常用的方法是给被选中的tab新增一个class名,然后改这个class名的样式. 比如 起一个class名叫"active" 设置样式 .active{ color: #FFD113 !important

  • js学习笔记之class类、super和extends关键词

    目录 前言 1.es6之前创建对象 2.es6之后class的声明 3.类的继承 4.继承类的静态成员 写在最后 前言 JavaScript 语言在ES6中引入了 class 这一个关键字,在学习面试的中,经常会遇到面试官问到谈一下你对 ES6 中class的认识,同时我们的代码中如何去使用这个关键字,使用这个关键字需要注意什么,这篇来总结一下相关知识点. 正文 1.es6之前创建对象 先来看下es6之前我们要想创建一个对象,只能通过构造函数的方式来创建,将静态方法添加在原型上面使得每一个实例能

  • 前端JavaScript中的class类

    目录 1.类 1.1 constructor() 1.2 getter和setter 1.3 this 1.4 静态属性 1.5 静态方法 2.继承 2.1 super关键字 2.2 _proto_和prototype 2.3 继承中的__proto__ 2.4 继承实例中的__proto__ 3.小结 1.类 类是用于创建对象的模板.JavaScript中生成对象实例的方法是通过构造函数,这跟主流面向对象语言(java,C# )写法上差异较大,如下: function Point(x, y)

  • ES6 javascript中class类的get与set用法实例分析

    本文实例讲述了ES6 javascript中class类的get与set用法.分享给大家供大家参考,具体如下: 与 ES5 一样, 在 Class 内部可以使用get和set关键字, 对某个属性设置存值函数和取值函数, 拦截该属性的存取行为. class MyClass { constructor() { // ... } get prop() { return 'getter'; } set prop(value) { console.log('setter: ' + value); } }

  • JavaScript Class类实例讲解

    目录 Class类 初识class class中getter和setter设置 表达式方式书写 静态属性与静态方法 私有属性和私有方法 class继承 静态属性和方法继承 私有属性和方法继承 class显示原型与隐式原型关系 Class类 ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板.通过class关键字,可以定义类.基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰,更像面向对

  • javascript帧动画(实例讲解)

    前面的话 帧动画就是在"连续的关键帧"中分解动画动作,也就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成的动画.由于是一帧一帧的画,所以帧动画具有非常大的灵活性,几乎可以表现任何想表现的内容.本文将详细介绍javascript帧动画 概述 [分类] 常见的帧动画的方式有三种,包括gif.CSS3 animation和javascript git和CSS3 animation不能灵活地控制动画的暂停和播放.不能对帧动画做更加灵活地扩展.另外,gif图不能捕捉动画完成的事件.所以,

  • HttpUtils 发送http请求工具类(实例讲解)

    废话不多说,直接上代码 import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFac

  • JavaScript操作表单实例讲解(上)

    一.获得表单引用 1>通过直接定位的方式来获取 document.getElementById(); document.getElementsByName(); document.getElementsByTagName(); 2>通过集合的方式来获取引用 document.forms[下标] document.forms["name"] document.forms.name 3>通过name直接获取"(只适用于表单) document.name 二.获得

  • Javascript操作表单实例讲解(下)

    在上篇文章给大家介绍了js操作表单实例讲解(下)的相关知识,本文接着给大家介绍Javascript操作表单实例讲解(下),具体详情如下所示: 一.文本域 <input type="text" /> ----------------------------- 操作文本域的值 value 属性 设置或者获取值 ----------------------------- 二.单选按钮和多选按钮 <input type="radio" /> <

  • JavaScript事件方法(实例讲解)

    废话不多说,直接上代码 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <style type="text

  • Java编写超时工具类实例讲解

    我们在开发过程中,在进行时间操作时,如果在规定的时间内完成处理的话,有可能会回到正确的结果.否则,就会被视为超时任务.此时,我们不再等待(不再执行)的时间操作,直接向调用者传达这个任务需要时间,被取消了. 1.说明 java已经为我们提供了解决办法.jdk1.5带来的并发库Future类可以满足这一需求.Future类中重要的方法有get()和cancel().get()获取数据对象,如果数据没有加载,则在获取数据之前堵塞,cancel()取消数据加载.另一个get(timeout)操作表明,如

  • Java中Swing类实例讲解

    Swing类部分画图方法讲解 定义框架 JFrame jFrame=new JFrame("标题名字"); jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置用户在此窗体上发起 "close" 时默认执行的操作. //有两种选择,默认是 HIDE_ON_CLOSE即点击关闭时隐藏界面. jFrame.setBounds(0,0,1200,1200); //设置框架的大小 jFrame.setVisi

  • JavaScript数组常用方法实例讲解总结

    目录 数组常用方法 concat() 方法 join() 方法 pop() 方法 push() 方法 reverse() 方法 shift() 方法 slice() 方法 sort() 方法 splice() 方法 toSource() 方法 toString() 方法 toLocaleString() 方法 unshift() 方法 valueOf() 方法 导读:在实际开发中,前端工程师除了写页面布局及样式还要对后端返回的数据进行处理,返回的数据大多数是json格式,一般都是返回一个对象或者

  • Android VideoView类实例讲解

    本节使用系统的示例类VideoView继续SurfaceView类相关内容的讲解,以让大家能更深入理解Android系统中图形绘制基础类的实现原理.也许你会发现无法改变VideoView类的控制方面,我们可以通过重构VideoView类来实现更加个性化的播放器.          下面是VideoView类的相关代码. Java 代码 public class VideoView extends SurfaceView implements MediaPlayerControl { privat

随机推荐