В JavaScript массивы могут быть созданы с использованием конструктора массива или быстро созданы с использованием [], что также является предпочтительным методом. Массив является прототипом, унаследованным от объекта, и он не имеет специального возвращаемого значения для типа, он только возвращает «объект».
В JS можно сказать, что все является объектом, и массив также является массивом.
Многие объекты имеют много удобных методов, таких как Push, Concat, Slice и т. Д. Массивов, но если некоторые объекты не реализуют эти методы, мы все равно хотим использовать эти функции. Так что мне делать?
1. Многие методы обеспечивают очень эффективные реализации, и мы можем моделировать их реализации.
Например, браузеры ниже IE8 не поддерживают метод индекса массива. Чтобы сделать индекс поддержки массива, мы можем сами написать метод для реализации метода индекса:
(Нажмите F12, чтобы отлаживать с помощью браузера IE, чтобы выбрать версию браузера в IE5.)
var arr = [,,,,]; if (array.prototype.indexof) {alert («Ваш браузер поддерживает метод индекса.»);} else {alert («Ваш браузер не поддерживает метод индекса.»);} if (! array.prototype.indexof) {array.prototy. i ++) {if (this [i] == item) {return i;}} return -;}} alert (arr.indexof ()); alert (arr.indexof ());Конечно, этот метод очень мусор. Я не буду уродливо в конкретной реализации здесь и предоставлю версию копии на Baidu:
Если вы заинтересованы, вы можете увидеть, как реализован двигатель V8: https://github.com/v8/v8/blob/master/src/js/array.js
if (! array.prototype.indexof) {array.prototype.indexof = function (elt /*, from* /) {var len = this.length >>>; var from = number (аргументы []) || ; от = (от <)? Math.ceil (from): math.floor (from); if (from <) from+= len; for (; from <len; from ++) {if (from in this && this [from] === elt) return из;} return -;};}2. Назначение наследия и применить методы
Если у нас есть объект, разве не очень трудно писать каждый объект для его реализации самостоятельно?
На языках высокого уровня мы можем использовать наследование для решения проблемы, например, следующий код Java:
открытый класс mylist <e> extends arraylist <e> {public void myadd (e e) {super.add (e); System.out.println ("Add:"+e);}}Но нет концепции наследования в JS. Мы можем использовать звонок и применить для решения таких проблем.
Приведенный выше код может быть переписан как:
var myObject = function () {} myObject.prototype.add = function () {array.prototype.push.call (this, arguments); // Выходные аргументы (var i =; i <arguments.length; i ++) {console.log ("add:"+аргументы [i]);Здесь мы можем видеть: хотя метод MYADD реализован в методе наследования языков высокого уровня, метод MYADD может пройти только один параметр сейчас. Если вы хотите передать несколько параметров, вам нужно написать еще один метод Public Void MyAdd (e [] e) или даже Public void MyAdd (List <e> E). JS может быть сделан с помощью одного метода, используя объект Arguments для представления всех вводов параметров, что трудно для языков высокого уровня.
(ps, на самом деле, вы можете написать публичный void myadd (e ... e) в Java. Это неопределенный параметр. Использование публичного void myadd (e [] e) одинаково)
Методы вызова и применения используются для изменения указателя этого указателя в функции. Вызов имеет только два параметра, и применение обычно используется после знания количества параметров. Ниже приведен пример:
var obj = function (name) {this.name = name;} obj.prototype.getName = function () {return this.name;} var obj1 = new obj ("zou"); var obj2 = {name: 'andy'}; var name = obj1.getName.call (obj2);Ссылка:
Применить (объект, arg1, arg2, ...)
Call (Object, [arg1, arg2, ......])
Только один «массив» может сопровождаться вызовом, включая все параметры. Применить синтаксический сахар. Если вы знаете количество параметров, применить применение очень удобно.
Приведенный выше объект также может быть нулевым или неопределенным, поэтому этот объект является глобальным объектом (окном). Например, приведен выше пример:
var name = 'Goo'; alert (obj1.getName.call (null)); (В строгом режиме, поскольку глобальный объект является нулевым, будет брошено исключение: uncaught typeerror: не удается прочитать «имя" null) null)
3. Object.DefineProperty
(Примечание: не используйте этот тип функции ниже IE8)
Microsoft: добавьте свойства в объекты или измените свойства существующих свойств.
Getters, Setters,
На самом деле, есть также функции Getters и Setter для свойств объектов в JS, но я лично думаю, что Getters и Setters в JS больше похожи на C#.
Например, следующий код определяет Getter/Setter:
function myobj () {} object.defineproperty (myobj.prototype, 'length', {get: function () {return this.length_; // Это не может быть длиной.}, set: function (value) {return this.length_ = value;}});Комментированное место не может быть длиной, иначе оно будет бесконечно рекурсивным.
Вы также можете удалить установку и сделать только переменную для чтения.
Object.defineproperty (myobj.prototype, 'length', {get: function () {return this.length_; // Это не может быть длиной.}, /*Set: function (value) {return this.length_ = value;}* /}); myobj.length = 3;Этот код вызовет исключение: uncaught typeerror: не может установить длину свойства #<myobj>, который имеет только Getter.
Чтобы сделать свойства объекта только для чтения, вы также можете использовать записи: False.
Object.defineproperty (myobj.prototype, 'length', {writeable: false});Запись: False не может сосуществовать с Get Set, в противном случае ошибка типа будет выбрана.
Настраивается: может ли он быть удален с помощью оператора Delete, но настраиваемое свойство, по -видимому, является действительным в строгом режиме. Такой код все еще может быть выполнен в безродовом режиме: (сообщила об ошибке в строгом режиме)
Object.defineproperty (myobj.prototype, 'length', {настраивается: false}); var obj = new myobj (); удалить obj.length;Значение: указывает фиксированное значение объекта. Значение: 10, указывая, что начальное значение этого объекта составляет 10.
В безложении режима такой код не будет сообщать об ошибке, и в строгом режиме он сообщит об ошибке:
Object.defineproperty (myobj.prototype, 'length', {writeable: false, value: '10 '}); var obj = new myobj (); obj.length = 100;Вы можете использовать GetownPropertyDescriptor, чтобы получить и изменить эти значения. Например, теперь мое свойство длиной только для чтения.
Запуск такого кода, но произошла ошибка:
Object.defineproperty (myobj.prototype, 'length', {value :, writeble: false,}); var descriptor = object.getownpropertydescriptor (myobj.prototype, "длина"); descriptor.writable = true; object.defineproperty (myobj.prototype, 'length', descriptor); Uncaught typeerror: не может переопределить свойство: длинаЭто связано с тем, что значение настраиваемой по умолчанию является false. После вызова DefineProperty, настраиваемое имеет ложное свойство, поэтому его нельзя изменить. Это не может быть изменено в будущем.
Поэтому вы должны использовать настраиваемое: true, и это свойство объекта может быть изменено. Полный код заключается в следующем:
Object.defineproperty (myobj.prototype, 'length', {value :, writeable: false, настраивается: true}); var descriptor = object.getownpropertydescriptor (myobj.prototype, "length"); true; object.defineproperty (myobj.prototype, 'длина', дескриптор); myobj.prototype.length =; var obj = new myobj (); alert (obj.length);Вы можете добавить дескриптор предложения. Конфигурируемый = false;
Это означает, что я изменил это свойство, и вы не можете изменить его в будущем
Эта функция также полезна во многих случаях. Если вы используете методы вызова и применения, длина объекта должна быть переменной. Если атрибут длины объекта только для чтения, при вызове и применении будет брошено исключение.
Например, длина объекта DomtokenList не может быть изменена. Я получил объект Dom DomtokenList,
Но его настраивается верно, мы можем изменить его, чтобы его свойство было изменено:
Смотрите, эта настраиваемая верно, а установка не определен. Давайте напишем для него метод сбора, разве это не в порядке?
var descriptor = object.getownpropertydescriptor (domtokenlist.prototype, 'length'); descriptor.set = function (value) {this.length = value;} object.defineproperty (domtokenlist.prototype, 'length', descriptor);Затем беги,
Другое исключение было брошено, Uncaught DrangeError: максимальный размер стека вызовов превышен (…)
Это связано с тем, что когда мы устанавливаем это. В длину, это будет бесконечно повторяться в этом набором методе, который мы пишем.
Поэтому нам нужно использовать удаление для устранения влияния атрибута длины, то есть:
var descriptor = object.getownpropertydescriptor (domtokenlist.prototype, 'length'); descriptor.set = function (value) {delete domtokenlist.prototype.length; this.length = value;} object.defineproperty (domtokenlist.prototype, 'длина', дескриптор);Таким образом, Domtokenlist также поддерживает Push, POP и другие операции.
Array.prototype.push.call (document.body.classlist, 'abc')
Затем инкапсулировать
Domtokenlist.prototype.push = function () {array.prototype.push.call (document.body.classlist, array.prototype.slice.call (аргументы));}Метод Array.prototype.slice.call (аргументы) используется для преобразования объектов аргументов в массивы.