jQuery не является истинной реализацией Array: jQuery instanceof Array
ложно!
Если вы хотите создать настоящий экземпляр массива, и добавьте пользовательские методы, используйте этот код. Он использует Function.prototype.bind
для вызова конструктора с произвольным числом параметров.
Реализация ведет себя точно как истинный массив, за исключением одной точки:
- Когда конструктор
Array
вызывается с одним аргументом, он создает массив с длиной этого аргумента.
- Поскольку эта функция часто является источником ошибок, я решил опустить ее в реализации. Вы все еще можете установить длину n , установив свойство
length
.
function Employees() {
// Deal with missing "new"
if (!(this instanceof Employees)) {
// Convert arguments to an array, because we have to shift all index by 1
var args = Array.prototype.slice.call(arguments);
args.unshift(this); // Shift all indexes, set "this"
return new (Function.prototype.bind.apply(Employees, args));
} else {
// Set length property.
var len = arguments.length,
/*
* fn_internalLength: Internal method for calculating the length
**/
fn_internalLength,
/*
* explicitLength: Deals with explicit length setter
**/
explicitLength = 0;
// Setting all numeric keys
while (len--) {
this[len] = arguments[len];
}
// Internal method for defining lengths
fn_internalLength = function() {
var allKeys = Object.keys(this).sort(function(x, y) {
// Sort list. Highest index on top.
return y - x;
}), i=-1, length = allKeys.length, tmpKey,
foundLength = 0;
// Loop through all keys
while (++i < length && (tmpKey = allKeys[i]) >= 0) {
// Is the key is an INTEGER?
if (tmpKey - tmpKey === 0 && tmpKey % 1 === 0) {
foundLength = 1*tmpKey + 1;
break;
}
}
// Return MAX(actual length, explictly set length)
return foundLength > explicitLength ? foundLength : explicitLength;
}.bind(this);
// Define the magic length property
Object.defineProperty(this, 'length',
{
get: fn_internalLength,
set: function(newLength) {
var length = fn_internalLength();
if (newLength < length) {
for (var i=newLength; i<length; i++) {
delete this[i];
}
}
// Set explicit length
explicitLength = newLength;
},
enumerable: false,
configurable: false
});
}
}
Employees.prototype = new Array;
// Example: Custom method:
Employees.prototype.print = function() {
return this.join('--'); // Using inherit Array.prototype.join
};
// Just like the Array, `new` is optional
console.log(new Employees(1,2).print());
console.log(Employees(1,2).print());
// Is the object an array?
console.log(new Employees() instanceof Array); // True!
// Can't believe it?
console.log(new Employees() instanceof Employees); // True!