首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
01 | 函数式vs.面向对象:响应未知和不确定
02 | 如何通过闭包对象管理程序中状态的变化?
03 | 如何通过部分应用和柯里化让函数具象化?
04 | 如何通过组合、管道和reducer让函数抽象化?
05|map、reduce和monad如何围绕值进行操作?
06 | 如何通过模块化、异步和观察做到动态加载?
07 | 深入理解对象的私有和静态属性
08|深入理解继承、Delegation和组合
09|面向对象:通过词法作用域和调用点理解this绑定
10|JS有哪8种数据类型,你需要注意什么?
11|通过JS引擎的堆栈了解闭包原理
12|JS语义分析该用迭代还是递归?
13 | JS引擎如何实现数组的稳定排序?
14 | 通过SparkPlug深入了解调用栈
15 | 如何通过哈希查找JS对象内存地址?
16 | 为什么环形队列适合做Node数据流缓存?
17 | 如何通过链表做LRU/LFU缓存?
18 | TurboFan如何用图做JS编译优化?
19 | 通过树和图看如何在无序中找到路径和秩序
20 | 算法思想:JS中分治、贪心、回溯和动态规划
21 | 创建型:为什么说Redux可以替代单例状态管理
22|结构型:Vue.js如何通过代理实现响应式编程
23 | 结构型:通过jQuery看结构型模式
24 | 行为型:通过观察者、迭代器模式看JS异步回调
25 | 行为型:模版、策略和状态模式有什么区别?
26|特殊型:前端有哪些处理加载和渲染的特殊“模式”?
27|性能:如何理解JavaScript中的并行、并发?
28|性能:通过Orinoco、Jank Busters看垃圾回收
29|网络:从HTTP/1到HTTP/3,你都需要了解什么?
30|安全:JS代码和程序都需要注意哪些安全问题?
31|测试(一):开发到重构中的测试
32|测试(二):功能性测试
33|测试(三):非功能性测试
34|静态类型检查:ESLint语法规则和代码风格的检查
35|Flow:通过Flow类看JS的类型检查
36|包管理和分发:通过NPM做包的管理和分发
37|编译和打包:通过Webpack、Babel做编译和打包
38|语法扩展:通过JSX来做语法扩展
39|Polyfill:通过Polyfill让浏览器提供原生支持
40|微前端:从MVC贫血模式到DDD充血模式
41|大前端:通过一云多端搭建跨PC/移动的平台应用
42|元编程:通过Proxies和Reflect赋能元编程
当前位置:
首页>>
技术小册>>
JavaScript进阶实战
小册名称:JavaScript进阶实战
### 07 | 深入理解对象的私有和静态属性 在JavaScript的广阔天地中,对象作为构建复杂应用程序的基石,其属性与方法的访问权限及作用范围的理解至关重要。随着ES6及后续版本的推出,JavaScript对类(Class)和模块(Module)的支持更加完善,特别是私有属性和静态属性的引入,为开发者提供了更强大的封装能力和更清晰的代码组织方式。本章将深入探讨JavaScript中对象的私有属性和静态属性的概念、用法、实现机制以及它们在实际开发中的应用场景。 #### 一、私有属性的引入与意义 ##### 1.1 私有属性的背景 在ES6之前,JavaScript没有直接支持私有成员(包括属性和方法)的原生语法。开发者通常通过闭包、Symbol或弱映射(WeakMap)等技术手段来模拟私有属性的行为,但这些方法各有利弊,且不够直观。ES2020(ECMAScript 2020)通过Class Fields提案的Stage 4完成,正式引入了类的私有字段语法,为JavaScript的面向对象编程带来了革命性的变化。 ##### 1.2 私有属性的定义 私有属性是指那些只能在类的内部被访问和修改的属性,外部代码(包括类的实例和继承的子类)都无法直接访问这些属性。在JavaScript中,私有属性通过在属性名前添加`#`符号来标识。 ```javascript class Counter { #count = 0; // 私有属性 increment() { this.#count++; } get value() { return this.#count; } } const counter = new Counter(); counter.increment(); console.log(counter.value); // 输出: 1 console.log(counter.#count); // 语法错误:Uncaught SyntaxError: Private field '#count' must be declared in an enclosing class ``` ##### 1.3 私有属性的作用 - **封装性增强**:私有属性确保了类的内部状态不被外部直接访问和修改,增强了类的封装性。 - **减少错误**:限制了对内部状态的直接访问,降低了因外部误操作导致内部状态不一致的风险。 - **更好的模块化**:通过隐藏内部实现细节,使得类的接口更加清晰,促进了代码的模块化。 #### 二、静态属性的探索与应用 ##### 2.1 静态属性的概念 静态属性是定义在类上而非其实例上的属性,它属于类本身,而不是类的任何特定实例。这意味着静态属性可以在没有创建类的实例的情况下被访问和修改。在JavaScript中,静态属性可以通过在类定义中直接赋值给类名来定义,或者使用静态方法中的静态属性访问器来定义。 ##### 2.2 静态属性的定义 ```javascript class MyClass { static staticProperty = 'I am a static property'; static getStaticProperty() { return MyClass.staticProperty; } } console.log(MyClass.staticProperty); // 输出: I am a static property console.log(MyClass.getStaticProperty()); // 输出: I am a static property // 注意:实例无法访问静态属性 const instance = new MyClass(); console.log(instance.staticProperty); // 输出: I am a static property(但不推荐这样访问,因为不直观) ``` ##### 2.3 静态属性的应用场景 - **工具函数与常量**:静态属性常用于存储工具函数或类的常量值,这些值对于类的所有实例都是共享的。 - **工厂方法**:在某些设计模式中,如工厂方法模式,静态方法用于创建并返回类的实例,而静态属性可能用于跟踪创建的实例数量或存储配置信息。 - **单例模式**:在单例模式中,类的静态属性通常用于存储类的唯一实例,确保全局只有一个实例被创建。 #### 三、私有属性与静态属性的实现机制 ##### 3.1 私有属性的实现 JavaScript引擎通过内部机制来实现私有属性的封装。当使用`#`符号定义私有属性时,这些属性不会直接添加到对象的属性描述符中,而是被存储在类的内部记录中。这意味着私有属性不能通过常规的属性访问方式(如`obj.propertyName`)来访问,只能通过类内部的方法或构造函数中的代码来访问。 ##### 3.2 静态属性的实现 静态属性则是直接附加到类构造函数的属性上。在JavaScript中,类其实是一个特殊的函数(构造函数),静态属性就是该函数的属性。由于JavaScript函数的原型链特性,这些静态属性对所有实例都是可访问的(尽管通常不推荐通过实例来访问静态属性),但它们并不属于任何特定实例,而是属于类本身。 #### 四、私有属性与静态属性的高级话题 ##### 4.1 私有方法的引入 与私有属性类似,ES2020也引入了私有方法的支持。私有方法也是通过在方法名前添加`#`符号来定义,只能在类内部被调用。 ```javascript class Counter { #count = 0; #increment() { this.#count++; } publicIncrement() { this.#increment(); // 调用私有方法 } get value() { return this.#count; } } ``` ##### 4.2 类的私有字段提案的扩展 随着ECMAScript标准的不断发展,类的私有字段提案也在不断扩展。例如,提案中讨论了支持计算属性名作为私有字段的可能性,以及私有字段的继承机制等。 ##### 4.3 静态私有属性与私有方法 虽然当前的JavaScript规范尚未直接支持静态私有属性或私有方法,但开发者可以通过闭包或WeakMap等技术来模拟这种行为。不过,随着语言的发展,未来可能会引入更直接的支持。 #### 五、结论 私有属性和静态属性是JavaScript面向对象编程中的重要概念,它们分别通过增强类的封装性和提供类级别的共享数据,为开发者提供了更强大、更灵活的代码组织和控制能力。深入理解并熟练使用这些特性,将有助于编写出更加模块化、可维护和高质量的JavaScript代码。随着ECMAScript标准的不断演进,我们可以期待未来JavaScript在面向对象编程方面将提供更多强大的功能和更简洁的语法。
上一篇:
06 | 如何通过模块化、异步和观察做到动态加载?
下一篇:
08|深入理解继承、Delegation和组合
该分类下的相关小册推荐:
JavaScript面试指南
KnockoutJS入门指南
WebSocket入门与案例实战
Javascript编程指南
零基础学JavaScript
web前端开发性能优化实战
Node.js 开发实战
npm script实战构建前端工作流
Flutter核心技术与实战
ES6入门指南
编程入门课:Javascript从入门到实战
javascript设计模式原理与实战