HLJ 发布于
2025-06-11 10:36:04
0阅读

JavaScript 中的私有和受保护的属性和方法

JavaScript 中的私有和受保护的属性和方法

在 JavaScript 中,实现面向对象编程中的私有(private)和受保护(protected)成员有几种不同的方式。虽然 JavaScript 本身没有像 Java 或 C++ 那样的原生访问修饰符,但可以通过一些模式和技术来实现类似的功能。

1. 传统实现方式 (ES5 及之前)

私有成员

function MyClass() {
  // 私有变量 - 只能在构造函数内部访问
  var privateVar = 'private';
  
  // 私有方法
  function privateMethod() {
    return privateVar;
  }
  
  // 特权方法 - 可以访问私有成员
  this.getPrivate = function() {
    return privateMethod();
  };
}

var instance = new MyClass();
console.log(instance.getPrivate()); // "private"
console.log(instance.privateVar);   // undefined

受保护成员

JavaScript 没有真正的受保护成员,但可以通过约定来实现:

function ParentClass() {
  // 约定: 下划线前缀表示受保护
  this._protectedVar = 'protected';
}

ParentClass.prototype.getProtected = function() {
  return this._protectedVar;
};

function ChildClass() {
  ParentClass.call(this);
}

ChildClass.prototype = Object.create(ParentClass.prototype);

var child = new ChildClass();
console.log(child.getProtected()); // "protected"
console.log(child._protectedVar);  // "protected" (但可以访问)

2. ES6+ 的实现方式

私有字段 (ES2022 正式加入标准)

class MyClass {
  #privateField = 'private'; // 真正的私有字段
  
  // 私有方法 (提案阶段)
  #privateMethod() {
    return this.#privateField;
  }
  
  getPrivate() {
    return this.#privateMethod();
  }
}

const instance = new MyClass();
console.log(instance.getPrivate()); // "private"
console.log(instance.#privateField); // 报错: SyntaxError

受保护成员的约定

class Parent {
  _protectedField = 'protected'; // 约定为受保护
  
  getProtected() {
    return this._protectedField;
  }
}

class Child extends Parent {
  getChildProtected() {
    return this._protectedField; // 可以访问父类的"受保护"成员
  }
}

const child = new Child();
console.log(child.getProtected());      // "protected"
console.log(child._protectedField);     // "protected" (但仍可访问)

3. 使用 WeakMap 实现私有性

const privateProps = new WeakMap();

class MyClass {
  constructor() {
    privateProps.set(this, {
      privateField: 'private',
      privateMethod: () => privateProps.get(this).privateField
    });
  }
  
  getPrivate() {
    return privateProps.get(this).privateMethod();
  }
}

const instance = new MyClass();
console.log(instance.getPrivate()); // "private"
console.log(instance.privateField); // undefined

4. TypeScript 中的实现

TypeScript 提供了更完整的访问控制修饰符:

class MyClass {
  private privateField: string = 'private';
  protected protectedField: string = 'protected';
  
  private privateMethod(): string {
    return this.privateField;
  }
  
  public getPrivate(): string {
    return this.privateMethod();
  }
}

class ChildClass extends MyClass {
  public getProtected(): string {
    return this.protectedField; // 可以访问受保护成员
    // return this.privateField; // 错误: 不能访问私有成员
  }
}

总结

  1. 真正的私有成员:使用 ES2022 的 # 前缀或 WeakMap 模式
  2. 约定式私有/受保护:使用下划线 _ 前缀命名约定
  3. 模块作用域:在模块中使用普通变量和函数,不导出即为私有
  4. 闭包:在构造函数中创建局部变量和函数

现代 JavaScript 开发中,推荐使用 ES2022 的私有字段语法或 TypeScript 的访问修饰符来实现真正的私有和受保护成员。

当前文章内容为原创转载请注明出处:http://www.good1230.com/detail/2025-06-11/822.html
最后生成于 2025-06-13 20:53:29
此内容有帮助 ?
0