想品客老师的第十天:类

类是一个优化js面向对象的工具

类的声明

        //1、
        class User{}
        console.log(typeof User)//function
        //2、
        let Hd=class{}
        //其实跟1差不多
        class Stu{
            show(){}//注意这里不用加逗号,对象才加逗号
            get(){
                console.log('后盾人')
            }
        }
        let hd=new Stu()
        hd.get()//后盾人

类的原理

类的本质就是个函数,也就相当于【根据这个函数的原型的constructor】

class User{}
console.log(User===User.prototype.constructor)//true

类其实就是个语法糖的结构,意思是确实好用但是你又得背了。。。

类里面直接的、不加任何修饰的内容,都是默认写在原型里的:

class User{show(){console.log('我是个公共属性')
}}
console.dir(User);

类里面有个constructor函数,这个方法的功能是初始化内部的属性,和function里的this.属性名是一个作用:

  class User {
            constructor(name) {
                this.name = name//和下面是一个作用
            }
        }
        // console.log(User === User.prototype.constructor)//true
        console.dir(User);
        function Hd(name) {
            this.name = name//和上面是一个作用
        }
        console.dir(Hd)

对象属性的声明

可以使用简单的this指针改变属性值为传入的形参,也可以用下面这种方法,更灵活:

 class User {
            site = "后盾人";
            constructor(name) {
                this.name = name;
            }
            changeSite(value) {
                this.site = value;
            }
            show() {
                return `${this.site}:${this.name}`;
            }
        }
        let hd = new User("后盾人");
        hd.changeSite("houdunren")//通过内部的方法声明hd对象内部的属性
        console.log(hd.show());

类的遍历

上一篇我们提到了有些方法存在原型中,我们不需要遍历,只能用if (h.hasOwnProperty(key))来解决

而类就可以轻松做到这个,因为class声明的方法不能遍历

   class Hd {
            constructor(name) {
                this.name = name
            }
            show() {
                console.log('我在原型里')

            }
        }
        let h = new Hd()
        for (const key in h) {
            console.log(key)//只打印name,不打印show方法
        }

class默认在严格模式下的运行

这是一般函数在严格模式下的执行:

class Hd {
  show() {
    function test() {
      console.log(this); // 严格模式下,this 是 undefined
    }
    test(); // 直接调用,没有绑定 this
  }
}

let hd = new Hd();
hd.show(); // 在严格模式下,test() 中的 this 是 undefined

而类里面直接就按严格模式执行

class Hd {
      show() {
        function test() {
          console.log(this);
        }
        test();
      }
    }
    let hd = new Hd();
    hd.show();

静态属性的使用

静态成员是就是构造函数或类里的属性和方法,静态属性就是构造函数或类里面的属性

在构造函数里定义静态属性:

  function Web(url) {
            this.url = url;
        }
        Web.url = "hdcms.com";
        let hd = new Web("houdunren.com");
        console.log(hd);
        console.dir(Web);

在类里面设置静态属性

class Request {
      static host = "https://www.houdunren.com";
      api(url) {
        return Request.host + `/${url}`;
      }
    }
    let obj = new Request();
    console.log(obj.api("article"));

像这种不改变的静态地址,最好前面加上static

静态方法的实现原理

在类中使用访问器

前面学过访问器,这是访问器在类的使用:

   class Request {
            constructor(host) {
                this.data = {}
                this.host = host
            }
            set host(url) {
                if (!/^https:?\/\//i.test(url)) {
                    throw new Error('地址错误')
                }
                this.data.host = url
            }
            get host() {
                return this.data['host']
            }
        }
        let hd = new Request('https://houdunren.com')

属性保护

用命名原则保护属性

意思就是约定俗成的【下划线开头的】属性就是私有属性

 class User {
      _url = "https://houdunren.com";//被保护的,外部访问不了
      constructor(name) {
        this.name = name;
      }
      set url(url) {//但是url可以访问
        if (!/^https?:/i.test(url)) {
          throw new Error("非常网址");
        }
        this._url = url;
      }
    }
    let hd = new User("后盾人");
    hd.name = "李四";
    hd.url = "https://hdcms.com";//所以通过url改变_url
    console.log(hd);

使用Symbol定义protected属性

关于symbol可以保护数据这里之前在对象学过类似的概念,但是我没懂:

如果想保存的话可以把属性定为私有属性,symbol可以让他变成私有属性

"use strict";
    const DATA = Symbol();
    const user = {
      // name: "后盾人",
      [DATA]: { name },
      age: 10,
      set name(value) {
        this[DATA].name = value;
      },
      get name() {
        return this[DATA].name;
      }
    };
    user.name = "hdcms";
    // user.data.name = "你好";
    console.log(user[Symbol()])

那你就要问了:symbol和私有属性什么关系,为啥symbol可以防止被修改?

deepseek太卡了,我们有请老朋友chatgpt作答:

Symbol 本身并没有提供不可修改(immutable)功能。它只是保证了每个 Symbol 是唯一的,也就是说它保证了属性键的唯一性,而不是数据本身的不可修改性。
但是,使用 Symbol 作为属性键可以间接达到“数据隐私”和“不可直接访问”的目的,因为 Symbol 属性不容易被外部直接修改。
怎么间接达到的?因为我们无法通过常规的方式来访问symbol定义的属性名的属性了:

const DATA = Symbol("privateData"); // 创建一个唯一的 Symbol
const user = {
  [DATA]: { name: "Alice", age: 25 }, // 用 Symbol 创建私有数据
  get name() {
    return this[DATA].name;
  },
  set name(value) {
    this[DATA].name = value;
  }
};
 
console.log(user.name);  // "Alice"
user.name = "Bob";       // 调用 setter
console.log(user.name);  // "Bob"
 
// 但是我们不能直接访问或修改 [DATA] 属性
console.log(user[DATA]); // undefined

在这个例子中,[DATA] 是一个私有的 Symbol 属性。虽然你可以通过 name 的 getter 和 setter 修改 name,但是无法直接通过 user[DATA] 来访问或修改 name。这是因为 Symbol 提供了 唯一性,使得你无法直接通过常规方式访问这个属性。

这样就只能用访问器修改数据了?了吗??

 "use strict";
            const DATA = Symbol();
            const user = {
                // name: "后盾人",
                [DATA]: { name },
                age: 10,
                set name(value) {
                    this[DATA].name = value;
                },
                get name() {
                    return this[DATA].name;
                }
            };
            //user.name = "hdcms";
            user[DATA].name='荷叶饭'
            console.log(user[DATA])

可是我这么写的时候修改成功了啊?后盾人你在说什么?

 const protecteds = Symbol();
    class Common {
      constructor() {
        this[protecteds] = {};
        this[protecteds].host = "https://houdunren.com";
      }
      set host(url) {
        if (!/^https?:/i.test(url)) {
          throw new Error("非常网址");
        }
        this[protecteds].host = url;
      }
      get host() {
        return this[protecteds].host;
      }
    }
    class User extends Common {
      constructor(name) {
        super();
        this[protecteds].name = name;
      }
      get name() {
        return this[protecteds].name;
      }
    }
    let hd = new User("后盾人");
    hd.host = "https://www.hdcms.com";
    console.log(hd.name);

使用WeakMap保护属性

卧槽电脑坏了学不进去

 const protecteds = new WeakMap();
    class Comment {
      constructor() {
        protecteds.set(this, {
          host: '"https://houdunren.com"'
        });
      }
      set host(url) {
        if (!/^https?:/i.test(url)) {
          throw new Error("非常网址");
        }
        protecteds.set(this, { ...protecteds.get(this), url });
      }
      get host() {
        return protecteds.get(this)["host"];
      }
    }
    class User extends Comment {
      constructor(name) {
        super();
        this.name = name;
      }
      set name(name) {
        protecteds.set(this, { ...protecteds.get(this), name });
      }
      get name() {
        return protecteds.get(this)["name"];
      }
    }
    let hd = new User("后盾人");
    // hd.name = "向军";
    // console.log(hd.name);
    console.log(hd);

草泥马七彩虹我草泥马

鸡肉和巴豆,这篇学不下去换个学去了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/964098.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaFX - 3D 形状

在前面的章节中,我们已经了解了如何在 JavaFX 应用程序中的 XY 平面上绘制 2D 形状。除了这些 2D 形状之外,我们还可以使用 JavaFX 绘制其他几个 3D 形状。 通常,3D 形状是可以在 XYZ 平面上绘制的几何图形。它们由两个或多个维度定义&#…

arm-linux-gnueabihf安装

Linaro Releases windows下打开wsl2中的ubuntu,资源管理器中输入: \\wsl$gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz 复制到/home/ark01/tool 在 Ubuntu 中创建目录: /usr/local/arm,命令如下: …

【双指针题目】

双指针 美丽区间&#xff08;滑动窗口&#xff09;合并数列&#xff08;双指针的应用&#xff09;等腰三角形全部所有的子序列 美丽区间&#xff08;滑动窗口&#xff09; 美丽区间 滑动窗口模板&#xff1a; int left 0, right 0;while (right < nums.size()) {// 增大…

【汽车电子软件架构】AutoSAR从放弃到入门专栏导读

本文是汽车电子软件架构&#xff1a;AutoSAR从放弃到入门专栏的导读篇。文章延续专栏文章的一贯作风&#xff0c;从概念与定义入手&#xff0c;希望读者能对AutoSAR架构有一个整体的认识&#xff0c;然后对专栏涉及的文章进行分类与链接。本文首先从AutoSAR汽车软件架构的概念&…

八、Spring Boot 日志详解

目录 一、日志的用途 二、日志使用 2.1 打印日志 2.1.1 在程序中获取日志对象 2.1.2 使用日志对象打印日志 2.2、日志框架介绍 2.2.1 门面模式(外观模式) 2.2.2 门面模式的实现 2.2.3 SLF4J 框架介绍 2.3 日志格式的说明 2.4 日志级别 2.4.1 日志级别的分类 2.4.2…

【Linux】24.进程信号(1)

文章目录 1. 信号入门1.1 进程与信号的相关知识1.2 技术应用角度的信号1.3 注意1.4 信号概念1.5 信号处理常见方式概览 2. 产生信号2.1 通过终端按键产生信号2.2 调用系统函数向进程发信号2.3 由软件条件产生信号2.4 硬件异常产生信号2.5 信号保存 3. 阻塞信号3.1 信号其他相关…

[Proteus仿真]基于51单片机的智能温控系统

[Proteus仿真]基于51单片机的智能温控系统 基于51单片机的智能温控系统&#xff1a;DS18B20精准测温LCD1602双屏显示三键设置上下限声光报警&#xff0c;支持温度校准、抗干扰设计、阈值记忆。 一.仿真原理图 ​​ 二.模块介绍 温度采集模块&#xff08;DS18B20&#xff0…

Windows下怎么安装FFFmpeg呢?

在Windows下使用Open-webui报错&#xff0c;说Couldnt find ffmpeg or avconv,解决open-webui报错Couldn‘t find ffmpeg or avconv-CSDN博客于是尝试解决问题&#xff0c;那么Windows下怎么安装FFFmpeg呢&#xff1f; 尝试了两种方法。 第一种方法pip安装&#xff08;失败&…

C基础寒假练习(2)

一、输出3-100以内的完美数&#xff0c;(完美数&#xff1a;因子和(因子不包含自身)数本身 #include <stdio.h>// 函数声明 int isPerfectNumber(int num);int main() {printf("3-100以内的完美数有:\n");for (int i 3; i < 100; i){if (isPerfectNumber…

【智力测试——二分、前缀和、乘法逆元、组合计数】

题目 代码 #include <bits/stdc.h> using namespace std; using ll long long; const int mod 1e9 7; const int N 1e5 10; int r[N], c[N], f[2 * N]; int nr[N], nc[N], nn, nm; int cntr[N], cntc[N]; int n, m, t;void init(int n) {f[0] f[1] 1;for (int i …

Vue-el挂载点

目录 一、Vue中的el挂载点是什么&#xff1f;二、Vue实例的作用范围是什么呢&#xff1f;三、Vue中的el是否可以挂载哪些选择器&#xff1f;四、el是否可以设置其他的dom元素呢&#xff1f; 一、Vue中的el挂载点是什么&#xff1f; el是用来设置Vue实例挂载&#xff08;管理&a…

c语言练习【实现终端功能、dup2实现文件拷贝、read write文件加载到链表】

练习1&#xff1a;实现终端功能 请实现一个终端的功能&#xff0c;注意需要带有cd功能 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h>#define MAX_CM…

MySQL数据库环境搭建

下载MySQL 官网&#xff1a;https://downloads.mysql.com/archives/installer/ 下载社区版就行了。 安装流程 看b站大佬的视频吧&#xff1a;https://www.bilibili.com/video/BV12q4y1477i/?spm_id_from333.337.search-card.all.click&vd_source37dfd298d2133f3e1f3e3c…

1.2 基于深度学习的底层视觉技术

文章目录 高层视觉任务与底层视觉任务深度神经网络相对于传统方法的优势 高层视觉任务与底层视觉任务 计算机视觉中的任务包含高层视觉任务&#xff0c;底层视觉任务。高层视觉任务是处理语义级别相关的任务&#xff0c;例如图像分类、目标检测、图像分割等。底层视觉任务处理与…

YOLOV11-1:YoloV11-安装和CLI方式训练模型

YoloV11-安装和CLI方式训练模型 1.安装和运行1.1安装的基础环境1.2安装yolo相关组件1.3命令行方式使用1.3.1 训练1.3.2 预测 本文介绍yoloV11的安装和命令行接口 1.安装和运行 1.1安装的基础环境 GPU环境&#xff0c;其中CUDA是12.4版本 1.2安装yolo相关组件 # 克隆github…

后盾人JS -- 原型

没有原型的对象 也有没有原型的对象 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document<…

【NEXT】网络编程——上传文件(不限于jpg/png/pdf/txt/doc等),或请求参数值是file类型时,调用在线服务接口

最近在使用华为AI平台ModelArts训练自己的图像识别模型&#xff0c;并部署了在线服务接口。供给客户端&#xff08;如&#xff1a;鸿蒙APP/元服务&#xff09;调用。 import核心能力&#xff1a; import { http } from kit.NetworkKit; import { fileIo } from kit.CoreFileK…

游戏引擎 Unity - Unity 下载与安装

Unity Unity 首次发布于 2005 年&#xff0c;属于 Unity Technologies Unity 使用的开发技术有&#xff1a;C# Unity 的适用平台&#xff1a;PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域&#xff1a;开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…

结构体DMA串口接收比特错位

发送&#xff1a; 显示&#xff1a; uint16_t接收时候会比特错位。

在线知识库的构建策略提升组织信息管理效率与决策能力

内容概要 在线知识库作为现代企业信息管理的重要组成部分&#xff0c;具有显著的定义与重要性。它不仅为组织提供了一个集中存储与管理知识的平台&#xff0c;还能够有效提升信息检索的效率&#xff0c;促进知识的创新和利用。通过这样的知识库&#xff0c;企业可以更好地应对…