兼容性问题场景
- IE 中 prototype 不可枚举
- 问题阐述:在现代浏览器中,通过
Object.defineProperty
定义在 prototype
上的属性,若设置了 enumerable: true
,可以通过 for...in
循环遍历出来。但在 IE 浏览器下,即使设置了 enumerable
为 true
,prototype
上的属性也不会出现在 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;
}
- 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();
};
}