查看这段代码。这是一个非常简单的JavaScript对象,使用模块模式实现(您可以在这个地址中看到实时示例)
var human = function() {
var _firstName = '';
var _lastName = ''
return {
get firstName() {
return _firstName;
}, get lastName() {
return _lastName;
}, set firstName(name) {
_firstName = name;
}, set lastName(name) {
_lastName = name;
}, get fullName() {
return _firstName + ' ' + _lastName;
}
}
}();
human.firstName = 'Saeed';
human.lastName = 'Neamati';
alert(human.fullName);
但是,IE8不支持JavaScript get
和set
关键字。您可以测试它并查看MDN。
我该怎么做才能使这个脚本兼容IE8 ?
我该怎么做才能使这个脚本兼容IE8 ?
彻底改变它。例如,不使用访问器属性,而是使用普通属性和函数的组合:
human.firstName = 'Saeed';
human.lastName = 'Neamati';
alert(human.getFullName());
有人建议在IE中使用DOM对象并使用Object.defineProperty()
添加属性。虽然它可能有效,但出于几个原因,我强烈建议不要使用这种方法,例如您编写的代码可能无法在所有浏览器中兼容:
var human = document.createElement('div');
Object.defineProperty(human, 'firstName', { ... });
Object.defineProperty(human, 'lastName', { ... });
Object.defineProperty(human, 'children', { value: 2 });
alert(human.children);
//-> "[object HTMLCollection]", not 2
至少Chrome是这样的。无论哪种方式,编写的代码都更安全,更容易在所有你想要支持的浏览器上运行。你从编写代码来利用getter和setter所获得的任何便利,在你专门针对Internet Explorer 8编写的额外代码中都失去了。
当然,除了性能降低之外,您将无法在对象上使用for...in
循环这一事实,以及当您使用您认为已经定义但在DOM对象上已经存在的属性时可能出现的混淆。
你不能(正如Andy回答的)
最接近的选项是
var human = function() {
var _firstName = '';
var _lastName = '';
return {
firstName: function() {
if (arguments.length === 1) {
_firstName = arguments[0];
}
else {
return _firstName;
}
},
lastName: function() {
if (arguments.length === 1) {
_lastName = arguments[0];
}
else {
return _lastName;
}
},
fullName: function() {
return _firstName + ' ' + _lastName;
}
};
}();
human.firstName('Saeed');
human.lastName('Neamati');
alert(human.fullName());
在http://jsfiddle.net/gaby/WYjqB/2/演示
IE8支持DOM节点上的getter和setter,所以如果你真的想要有getter和setter,你可以这样做:
var objectForIe8 = $("<div></div>")[0];
Object.defineProperty(objectForIe8, "querySelector", {
get: function() {
return this.name;
},
set: function(val) {
this.name = val+", buddy";
}
});
// notice you can overwrite dom properties when you want to use that property name
objectForIe8.querySelector = "I'm not your guy";
alert(objectForIe8.querySelector);
注意,这会给您带来相当大的性能损失,所以如果您需要创建数千个这样的对象,我不会使用这种技术。但如果你不担心这个特殊物体的性能,它会帮你渡过难关。如果你不在乎ie8的性能,只是想让它工作,只在ie8上使用这种技术,你是黄金的:)
在http://robertnyman.com/2009/05/28/getters-and-setters-with-javascript-code-samples-and-demos/上查看
扩展对象的未来和ECMAScript标准化方式所有的方法都是通过Object.defineProperty。这就是Internet Explorer选择实现getter和setter,但它是不幸的是,目前只能在ie8中使用任何其他网页浏览器。另外,IE 8只支持DOM节点,但是未来的版本计划在JavaScript对象上支持它好。
您可以在相同的站点http://robertnyman.com/javascript/javascript-getters-setters.html#object-defineproperty
找到测试用例。Object.defineProperty(document.body, "description", {
get : function () {
return this.desc;
},
set : function (val) {
this.desc = val;
}
});
document.body.description = "Content container";
结果:document.body.description = "Content container"