我正在尝试对数组方法include()进行填充以与IE8配合使用,我需要为一个项目提供支持,并且我不想使用indexOf()。
我知道这里有一个polyfill,所以我去了:
并将其包含在脚本的顶部。
IE8对Object.defineProperty()的支持有限,因此我也对其进行了填充: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties#Polyfill
最后,我需要填充Object.keys(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys#Polyfill
放在一起,我的polyfill是:
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 !== 'function' && (typeof obj !== 'object' || 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;
};
}());
}
function defineProperties(obj, properties) {
function convertToDescriptor(desc) {
function hasProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
function isCallable(v) {
// NB: modify as necessary if other values than functions are callable.
return typeof v === 'function';
}
if (typeof desc !== 'object' || desc === null)
throw new TypeError('bad desc');
var d = {};
if (hasProperty(desc, 'enumerable'))
d.enumerable = !!desc.enumerable;
if (hasProperty(desc, 'configurable'))
d.configurable = !!desc.configurable;
if (hasProperty(desc, 'value'))
d.value = desc.value;
if (hasProperty(desc, 'writable'))
d.writable = !!desc.writable;
if (hasProperty(desc, 'get')) {
var g = desc.get;
if (!isCallable(g) && typeof g !== 'undefined')
throw new TypeError('bad get');
d.get = g;
}
if (hasProperty(desc, 'set')) {
var s = desc.set;
if (!isCallable(s) && typeof s !== 'undefined')
throw new TypeError('bad set');
d.set = s;
}
if (('get' in d || 'set' in d) && ('value' in d || 'writable' in d))
throw new TypeError('identity-confused descriptor');
return d;
}
if (typeof obj !== 'object' || obj === null)
throw new TypeError('bad obj');
properties = Object(properties);
var keys = Object.keys(properties);
var descs = [];
for (var i = 0; i < keys.length; i++)
descs.push([keys[i], convertToDescriptor(properties[keys[i]])]);
for (var i = 0; i < descs.length; i++)
Object.defineProperty(obj, descs[i][0], descs[i][1]);
return obj;
}
if (!Array.prototype.includes) {
alert('test');
defineProperties(Array.prototype, 'includes', {
value: function(searchElement, fromIndex) {
'use strict';
if (this === null) {
throw new TypeError('"this" is null or not defined');
}
// 1. Let O be ? ToObject(this value).
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If len is 0, return false.
if (len === 0) {
return false;
}
// 4. Let n be ? ToInteger(fromIndex).
// (If fromIndex is undefined, this step produces the value 0.)
var n = fromIndex | 0;
// 5. If n ≥ 0, then
// a. Let k be n.
// 6. Else n < 0,
// a. Let k be len + n.
// b. If k < 0, let k be 0.
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
function sameValueZero(x, y) {
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
}
// 7. Repeat, while k < len
while (k < len) {
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
// b. If SameValueZero(searchElement, elementK) is true, return true.
if (sameValueZero(o[k], searchElement)) {
return true;
}
// c. Increase k by 1.
k++;
}
// 8. Return false
return false;
}
});
}
为了测试上述脚本,我做了:
var arr = ["one", "two", "three"];
alert( arr.includes('two') );
IE8抛出此错误:
Object doesn't support this property or method.
我认为,通过使用polyfills,我可以为IE8添加对array includes()的支持。我究竟做错了什么?欢迎更正或链接到其他polyfills。没有jQuery或其他库。我只想向IE添加对includes()的支持。
答案 0 :(得分:0)
使用arr.indexOf('two')
如果返回1是因为它存在,而-1不存在
答案 1 :(得分:0)
不幸的是,我没有方法可以在IE8中进行测试,但是我认为这里发生了几件事-首先,您不需要定义defineProperties(obj, properties)
,因为{{1 }}和Object.keys
都不会使用它-它们都是独立的。它们是独立的这一事实也意味着您不需要包括Array.prototype.includes
polyfill。
我建议仅在需要时使用包含Object.keys
。
答案 2 :(得分:0)
您可以简单地使用Array#indexOf
来填充Array#includes
。
对于IE8,您还需要填充Array#indexOf
,因为它仅在IE9中实现。
if(!Array.prototype.includes){
//or use Object.defineProperty
Array.prototype.includes = function(search){
return !!~this.indexOf(search);
}
}
if(!Array.prototype.indexOf){
Array.prototype.indexOf = (function(Object, max, min){
"use strict";
return function indexOf(member, fromIndex) {
if(this===null||this===undefined)throw TypeError("Array.prototype.indexOf called on null or undefined");
var that = Object(this), Len = that.length >>> 0, i = min(fromIndex | 0, Len);
if (i < 0) i = max(0, Len+i); else if (i >= Len) return -1;
if(member===void 0){ for(; i !== Len; ++i) if(that[i]===void 0 && i in that) return i; // undefined
}else if(member !== member){ for(; i !== Len; ++i) if(that[i] !== that[i]) return i; // NaN
}else for(; i !== Len; ++i) if(that[i] === member) return i; // all else
return -1; // if the value was not found, then return -1
};
})(Object, Math.max, Math.min);
}
Array.prototype.includes = null;
Array.prototype.indexOf = null;
if(!Array.prototype.includes){
console.log('Polyfilled Array.prototype.includes');
//or use Object.defineProperty
Array.prototype.includes = function(search){
return !!~this.indexOf(search);
}
}
if(!Array.prototype.indexOf){
console.log("Polyfilled Array.prototype.indexOf");
Array.prototype.indexOf = (function(Object, max, min){
"use strict";
return function indexOf(member, fromIndex) {
if(this===null||this===undefined)throw TypeError("Array.prototype.indexOf called on null or undefined");
var that = Object(this), Len = that.length >>> 0, i = min(fromIndex | 0, Len);
if (i < 0) i = max(0, Len+i); else if (i >= Len) return -1;
if(member===void 0){ for(; i !== Len; ++i) if(that[i]===void 0 && i in that) return i; // undefined
}else if(member !== member){ for(; i !== Len; ++i) if(that[i] !== that[i]) return i; // NaN
}else for(; i !== Len; ++i) if(that[i] === member) return i; // all else
return -1; // if the value was not found, then return -1
};
})(Object, Math.max, Math.min);
}
var obj = {x: 1, y: 2};
var arr = [1, 'what', obj];
console.log('Array includes 1:',arr.includes(1));
console.log('Array includes \'what\':', arr.includes('what'));
console.log('Array includes obj:', arr.includes(obj));
console.log('Array inclues 3:', arr.includes(3));