MST
星途 面试题库

面试题:JavaScript属性特性在继承体系下的设计模式应用

当涉及到JavaScript的原型继承体系时,属性特性会在原型链上如何传播和表现?请详细阐述如何利用属性特性设计一个继承模式,使得父类的某些属性在子类中具有不同的可配置性、可枚举性或可写性。例如,父类有一个属性,子类继承后该属性不能被重新配置且不可枚举,但可写,写出具体的代码实现及解释。
47.0万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

属性特性在原型链上的传播和表现

  1. 传播:在JavaScript的原型继承体系中,当访问对象的属性时,如果对象本身没有该属性,JavaScript会沿着原型链向上查找,直到找到该属性或者到达原型链顶端(null)。例如,若child对象继承自parent对象,child对象本身没有prop属性,那么就会在parent对象的原型上查找prop属性。
  2. 表现:属性特性(可配置性configurable、可枚举性enumerable、可写性writable)也会随着原型链继承。默认情况下,通过字面量或构造函数创建对象的属性,这些特性值分别为truetruetrue。但如果通过Object.defineProperty定义属性,可以精确控制这些特性。

利用属性特性设计继承模式实现特定需求

下面通过代码实现一个继承模式,使得父类的某些属性在子类中具有不同的可配置性、可枚举性或可写性。

// 定义父类
function Parent() {
    this.sharedProp = 'parent value';
}

// 子类通过原型链继承父类
function Child() {
    Parent.call(this);
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

// 在子类上重新定义sharedProp属性,修改其特性
Object.defineProperty(Child.prototype,'sharedProp', {
    configurable: false,
    enumerable: false,
    writable: true,
    value: 'child value'
});

// 测试
const childInstance = new Child();
console.log(childInstance.sharedProp); // 输出 'child value'

// 尝试重新配置属性
try {
    Object.defineProperty(childInstance,'sharedProp', { value: 'new value' });
} catch (error) {
    console.log('不能重新配置属性:', error.message); 
}

// 检查属性是否可枚举
const keys = Object.keys(childInstance);
console.log('可枚举属性:', keys); 

代码解释

  1. 定义父类和子类:首先定义了Parent构造函数和Child构造函数,通过Parent.call(this)在子类构造函数中调用父类构造函数,实现属性的继承。然后通过Object.create创建子类原型,使其继承父类原型,并修正子类的constructor属性。
  2. 修改子类属性特性:使用Object.defineProperty在子类原型上重新定义sharedProp属性,将其configurable设置为false,意味着不能再使用Object.defineProperty修改该属性的特性;enumerable设置为false,表示该属性不会出现在for...in循环或Object.keys等操作中;writable设置为true,说明该属性的值可以被修改。
  3. 测试:创建Child类的实例childInstance,首先输出属性值验证可写性。然后尝试重新配置属性,由于configurablefalse,会抛出错误。最后通过Object.keys检查属性是否可枚举,验证enumerablefalse的设置。