MST

星途 面试题库

面试题:JavaScript 中 prototype 特性在不同浏览器下常见的兼容性问题及修复思路

请列举至少两个 JavaScript prototype 特性在不同浏览器(如 IE 与现代浏览器)中出现兼容性问题的场景,并简要阐述你认为可行的修复思路。
40.9万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

兼容性问题场景

  1. IE 中 prototype 不可枚举
    • 问题阐述:在现代浏览器中,通过 Object.defineProperty 定义在 prototype 上的属性,若设置了 enumerable: true,可以通过 for...in 循环遍历出来。但在 IE 浏览器下,即使设置了 enumerabletrueprototype 上的属性也不会出现在 for...in 循环中。例如:
function Person() {}
Object.defineProperty(Person.prototype, 'name', {
    value: 'John',
    enumerable: true
});
var person = new Person();
for (var prop in person) {
    if (person.hasOwnProperty(prop)) {
        console.log(prop);
    }
}
// 在现代浏览器中会输出 'name',但在 IE 中不会
- **修复思路**:可以手动创建一个方法来模拟遍历 `prototype` 上可枚举属性。
function getPrototypeEnumerableProps(obj) {
    var props = [];
    var proto = Object.getPrototypeOf(obj);
    while (proto) {
        for (var prop in proto) {
            if (Object.prototype.hasOwnProperty.call(proto, prop) && Object.getOwnPropertyDescriptor(proto, prop).enumerable) {
                props.push(prop);
            }
        }
        proto = Object.getPrototypeOf(proto);
    }
    return props;
}
  1. IE 中 prototype 链式调用问题
    • 问题阐述:在继承过程中,现代浏览器能很好地处理 prototype 的链式关系。例如,通过 Object.create 创建一个新对象并设置其原型链。但在 IE 中,Object.create 方法不存在,且手动设置 prototype 进行继承时,可能会出现一些链式调用异常。比如:
function Animal() {}
function Dog() {}
Dog.prototype = new Animal();
var dog = new Dog();
// 在现代浏览器中,dog.__proto__ === Dog.prototype 且 Dog.prototype.__proto__ === Animal.prototype
// 在 IE 某些版本中,这种原型链关系可能不完整或异常
- **修复思路**:可以自己实现一个 `Object.create` 方法来兼容 IE。
if (!Object.create) {
    Object.create = function (proto, propertiesObject) {
        if (typeof proto!== 'object' && typeof proto!== 'function') {
            throw new TypeError('Object prototype may only be an Object or null');
        } else if (proto === null) {
            throw new Error('This browser or environment doesn\'t support null prototype objects');
        }
        if (typeof propertiesObject!== 'undefined') {
            throw new Error('ES5 does not support second argument');
        }
        function F() {}
        F.prototype = proto;
        return new F();
    };
}