当对象包含空值时 IE8 对象预期错误
IE8 Object Expected error when object contains null value
我正在使用一个小的多边形填充以使 Object.key 可用于 IE8。当我的对象包含所有值时,一切似乎都运行良好。但是,当我在对象中有空值时,我收到有关 Object Expected 的错误。我不确定为什么有一个 null 会很重要。我的代码如下:
var data = [{
x: Date.UTC(2014, 8, 1),
y: 730,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2014, 9, 1),
y: 742,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2014, 10, 1),
y: 746,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2014, 11, 1),
y: null
}, {
x: Date.UTC(2015, 0, 1),
y: 737,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2015, 1, 1),
y: 751,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2015, 2, 1),
y: 765,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2015, 3, 1),
y: 766,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2015, 4, 1),
y: 757,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2015, 5, 1),
y: 750,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2015, 6, 1),
y: 748,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2015, 7, 1),
y: 723,
pf: ["001", "003"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}]
var pfMap = {
"001": {
"sd": "HI",
"ld": "By"
},
"002": {
"sd": "HI",
"ld": "By"
}
}
var nfMap = {
"001": {
"sd": "HI",
"ld": "By"
}
}
var tMap = {
"001": "Hi",
"002": "by"
}
var imMap={
"001":"HI"
}
// Shim added to aid in IE8
if (!Object.keys) {
Object.keys = (function() {
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
}
//recursion
function traverseData(data, elementName) {
var keys = Object.keys(data);
for (var i = 0; i < keys.length; ++i) {
if (Object.prototype.toString.call(data[keys[i]]) == "[object Object]" || Object.prototype.toString.call(data[keys[i]]) == "[object Array]") {
traverseData(data[keys[i]], keys[i]);
} else {
if (elementName != null && window[elementName + "Map"]) {
data[keys[i]] = window[elementName + "Map"][data[keys[i]]];
}
}
}
}
traverseData(data, "data");
var end = data;
如您所见,我正在构建一个简单的递归来创建一个新的图表对象。如果您注意到数据对象,第 4 个条目的 y 值设置为空。如果我用数字填写它,一切都会按预期进行。但是,如果它保留为 null,我会收到错误消息。知道为什么吗?
编辑:在 polyfill 中出现错误的相关行。我在 blow
区评论了
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) { // Throws error here
result.push(dontEnums[i]);
}
}
}
首先,用于检测 null
值的逻辑存在问题:
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
如果 obj
是 null
,那么 typeof obj
将是 "object"
。
试试这个:
if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null)
现在,您将收到自定义 Object.keys called on non-object
错误。
这个 null
是由于
Object.prototype.toString.call(data[keys[i]]) == "[object Object]"
根据 ECMAScript 5,Object.prototype.toString.call(null)
必须 return "[object Null]"
。但在旧浏览器上,它可能会生成 "[object Object]"
。
相反,您可以使用
if(typeof data[keys[i]]=== 'object' && data[keys[i]])
我正在使用一个小的多边形填充以使 Object.key 可用于 IE8。当我的对象包含所有值时,一切似乎都运行良好。但是,当我在对象中有空值时,我收到有关 Object Expected 的错误。我不确定为什么有一个 null 会很重要。我的代码如下:
var data = [{
x: Date.UTC(2014, 8, 1),
y: 730,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2014, 9, 1),
y: 742,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2014, 10, 1),
y: 746,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2014, 11, 1),
y: null
}, {
x: Date.UTC(2015, 0, 1),
y: 737,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2015, 1, 1),
y: 751,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2015, 2, 1),
y: 765,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2015, 3, 1),
y: 766,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2015, 4, 1),
y: 757,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2015, 5, 1),
y: 750,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2015, 6, 1),
y: 748,
pf: ["001", "002"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}, {
x: Date.UTC(2015, 7, 1),
y: 723,
pf: ["001", "003"],
nf: ["001", "002"],
t: ["001", "002"],
im:["001"]
}]
var pfMap = {
"001": {
"sd": "HI",
"ld": "By"
},
"002": {
"sd": "HI",
"ld": "By"
}
}
var nfMap = {
"001": {
"sd": "HI",
"ld": "By"
}
}
var tMap = {
"001": "Hi",
"002": "by"
}
var imMap={
"001":"HI"
}
// Shim added to aid in IE8
if (!Object.keys) {
Object.keys = (function() {
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
}
//recursion
function traverseData(data, elementName) {
var keys = Object.keys(data);
for (var i = 0; i < keys.length; ++i) {
if (Object.prototype.toString.call(data[keys[i]]) == "[object Object]" || Object.prototype.toString.call(data[keys[i]]) == "[object Array]") {
traverseData(data[keys[i]], keys[i]);
} else {
if (elementName != null && window[elementName + "Map"]) {
data[keys[i]] = window[elementName + "Map"][data[keys[i]]];
}
}
}
}
traverseData(data, "data");
var end = data;
如您所见,我正在构建一个简单的递归来创建一个新的图表对象。如果您注意到数据对象,第 4 个条目的 y 值设置为空。如果我用数字填写它,一切都会按预期进行。但是,如果它保留为 null,我会收到错误消息。知道为什么吗?
编辑:在 polyfill 中出现错误的相关行。我在 blow
区评论了 if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) { // Throws error here
result.push(dontEnums[i]);
}
}
}
首先,用于检测 null
值的逻辑存在问题:
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
如果 obj
是 null
,那么 typeof obj
将是 "object"
。
试试这个:
if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null)
现在,您将收到自定义 Object.keys called on non-object
错误。
这个 null
是由于
Object.prototype.toString.call(data[keys[i]]) == "[object Object]"
根据 ECMAScript 5,Object.prototype.toString.call(null)
必须 return "[object Null]"
。但在旧浏览器上,它可能会生成 "[object Object]"
。
相反,您可以使用
if(typeof data[keys[i]]=== 'object' && data[keys[i]])