MST

星途 面试题库

面试题:JavaScript对象可扩展能力兼容性处理与原型链关系

当对一个继承自原型链上的对象进行可扩展能力兼容性处理时,会遇到哪些潜在问题?例如,若在一个通过`Object.create`创建的对象上,既要处理其可扩展能力兼容性,又要保证原型链上属性的正常访问和修改,应该怎么做?
26.2万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

潜在问题

  1. 浏览器兼容性:不同浏览器对对象可扩展能力的支持存在差异,特别是在旧版本浏览器中,可能对 Object.preventExtensionsObject.sealObject.freeze 等方法支持不完善或存在行为差异。
  2. 原型链干扰:在处理对象可扩展能力时,可能意外影响原型链上属性的访问和修改。例如,若错误地对原型对象设置为不可扩展,可能导致所有继承自该原型的对象都无法添加新属性,即使在实例对象层面尝试处理可扩展性也无效。
  3. 属性特性冲突:对象属性具有多种特性,如 configurableenumerablewritable 等。在处理可扩展能力时,可能会与这些属性特性产生冲突。比如,若将一个对象设置为不可扩展,再试图修改原型链上一个 configurablefalse 的属性,可能会导致错误。

解决方案

  1. 检测环境支持
    if (typeof Object.preventExtensions!== 'function') {
        Object.preventExtensions = function (obj) {
            // 自定义实现逻辑
            Object.defineProperty(obj, '__proto__', {
                value: Object.getPrototypeOf(obj),
                writable: false,
                configurable: false,
                enumerable: false
            });
            return obj;
        };
    }
    if (typeof Object.seal!== 'function') {
        Object.seal = function (obj) {
            Object.preventExtensions(obj);
            const propNames = Object.getOwnPropertyNames(obj);
            propNames.forEach(name => {
                Object.defineProperty(obj, name, {
                    configurable: false
                });
            });
            return obj;
        };
    }
    if (typeof Object.freeze!== 'function') {
        Object.freeze = function (obj) {
            Object.seal(obj);
            const propNames = Object.getOwnPropertyNames(obj);
            propNames.forEach(name => {
                Object.defineProperty(obj, name, {
                    writable: false
                });
            });
            return obj;
        };
    }
    
  2. 处理对象可扩展能力
    const proto = {
        prop: 'proto value'
    };
    const obj = Object.create(proto);
    // 处理可扩展能力兼容性
    Object.preventExtensions(obj);
    // 保证原型链上属性的正常访问和修改
    console.log(obj.prop); // 正常访问原型链上属性
    proto.prop = 'new proto value';
    console.log(obj.prop); // 原型链上属性修改后,实例对象可正常获取新值
    

通过上述方法,先对环境进行检测并提供兼容性实现,然后在通过 Object.create 创建的对象上设置可扩展能力,同时能确保原型链上属性的正常访问和修改。