欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > 想品客老师的第天:类

想品客老师的第天:类

2025/9/28 22:33:27 来源:https://blog.csdn.net/Au_ust/article/details/145422636  浏览:    关键词:想品客老师的第天:类

类是一个优化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)//trueconsole.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改变_urlconsole.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);

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词