2013-06-22 2 views
2

первый: Недавно я знал, что Array.prototype сам является массив ([]) Но удивительная вещь, что это не экземпляр объекта массива .Как это возможно что.? является причиной этого?обучения Array.prototype и вычисления его длины

Второе:Array.prototype обладает многими свойствами, но когда и войти т.е. console.log(Array.prototype.length), выход '0' .Что это причина здесь я попытался это Aswell, результат тот же

var x=[]; 
x['a']="b"; 
x['b']="c"; 
console.log(x.length)//output:0 

Было бы здорово? если u дайте мне знать разницу в элементе и свойстве массива

+1

Ну, на самом деле вы первый большой массив x, и вы устанавливаете свойства для x, и это делает объект объектом Object.keys (x) –

+0

Это случай массива против объекта. Похоже, вы хотите использовать объект здесь. – elclanrs

+0

'var x = {};', '[]' это массив, он не принимает именованные ключи, только числовые (индексы) - тогда, чтобы подсчитать количество ключей, вы можете сделать, как предложил @jurka! –

ответ

4

Я недавно знал, что Array.prototype сам по себе является массивом ([]).

Вы правы, это массив. Спецификация указана в §15.4.4, Properties of the Array Prototype Object:

Объект-прототип массива сам по себе представляет собой массив; его [[Class]] составляет "Array", и он имеет свойство length (начальное значение которого составляет +0) и специальный внутренний метод [[DefineOwnProperty]], описанный в 15.4.5.1.


Но удивительная вещь, что это не экземпляр объекта Array. Как это возможно? Что является причиной этого?

Если вы пробовали Array.prototype instanceof Array, тогда результат действительно будет false. Зачем? Из-за того, как работает оператор instanceof. Он сравнивает прототип объекта со значением свойства prototype функции-конструктора.
I.e. в данном случае это не

Object.getPrototypeOf(Array.prototype) === Array.prototype 

Как мы уже видим в этом сравнении, мы пытаемся проверить Array.prototype ли его собственный прототип, который невозможно. В спецификации также упоминается в том же абзаце:

значение внутреннего свойства объекта массива прототипа [[Prototype]] является стандартным встроенным в прототипе объекта объекта (15.2.4).

То есть, Object.getPrototypeOf(Array.prototype) === Object.prototype и Object.prototype !== Array.prototype. Следовательно, instanceof дает false, но Array.prototype - это массив, тем не менее.


Array.prototype обладает многими свойствами, но, когда у входа т.е. console.log(Array.prototype.length), выход '0'.

0 быть значение Array.prototype.length определено в описании (смотри выше).

Было бы здорово, если и дайте мне знать разницу элемента и свойство массива

элемент массива является свойство с именем свойства, что является положительным 32- битное целое число (или 0).A Недвижимость - любое другое имущество, не имеющее такого свойства. Они не рассматриваются никакими операциями массива.

спецификация обеспечивает более точное описание в §15.4, Array Objects:

массив объектов особого обращения к определенному классу имен свойств. Имя свойства P (в виде значения String) является индексом массива тогда и только тогда, когда ToString(ToUint32(P)) равно P и ToUint32(P) не равна 2 -1. Свойство, имя свойства которого является индексом массива, также называется элементом .

Таким образом, вы видите, что если имя свойства преобразуется в (строковое представление) 32-битовое целое без знака и по-прежнему имеет то же значение, то это индекс массива, а связанное значение является элементом массив.

Спецификация непрерывной

Значение length собственности численно больше, чем имя каждого свойства, имя которого является индексом массива;

Мы только что узнали, какие имена свойств считаются индексами массива, которые могут быть преобразованы в целые числа без знака. По этому определению, "a" не является индексом массива, так

var x = []; 
x['a'] = 42; 

не меняет length свойства. Но "3" является индексом массива, так

x["3"] = 42; 

изменяет length свойство 4.

4

Прежде всего объекты JavaScript наследуют от других объектов, а не от конструкторских функций. Следовательно, утверждение «Но удивительно, что это не экземпляр объекта Array» неверен.

Скажем у вас есть объект, называемый rectangle следующим образом:

var rectangle = { 
    height: 5, 
    width: 10 
}; 

rectangle.area = function() { 
    return this.width * this.height; 
}; 

Теперь я могу вычислить площадь этого прямоугольника путем вызова метода rectangle.area. Однако скажу, что я хотел создать новый прямоугольник с разными width и height. Это то, что я хотел бы сделать:

var rectangle2 = Object.create(rectangle); 

rectangle2.height = 8; 
rectangle2.width = 20; 

alert(rectangle2.area()); 

Здесь объект rectangle2 наследует от объекта rectangle. Таким образом, вы видите, что объекты фактически наследуются от других объектов, а не от конструкторских функций. Прочитайте следующую нить для более подробной информации:

Questions regarding prototype function

Если перед вызовом функции с new ключевым словом JavaScript создает новый объект, который наследует от prototype функции. Следовательно, экземпляр фактически наследуется от prototype.

Объект a наследует только от объекта b если объект b находится в цепи прототипов объекта a. Именно по этой причине у нас есть метод isPrototypeOf.


Следующая вещь, чтобы помнить, что оператор instanceof самом деле не означает ничего. Он может быть реализован в JavaScript следующим образом:

function instanceOf(obj, func) { 
    return Object.prototype.isPrototypeOf.call(func.prototype, obj); 
} 

Таким образом, как вы можете ясно видеть объект квалифицируется как «экземпляр» функции, только если он наследует от prototype этой функции.

Именно поэтому Array.prototype instanceof Array возвращает false - объект не может наследовать сам.

Для получения дополнительной информации о том, как instanceof оператор работает на прочитайте следующую тему:

JavaScript inheritance and the constructor property


Наконец length свойство массива всегда один больше, чем наибольший числовой индекс из массив. Например:

var a = []; 
alert(a.length); // 0 
a[99999] = null; 
alert(a.length); // 100000 

Вот почему Array.prototype.length является 0 - Array.prototype не имеет цифровых клавиш. Однако, если присвоить ему числовой ключ, то length свойство изменится соответствующим образом:

Array.prototype[99999] = null; 
alert(Array.prototype.length); // 100000 

То же самое относится и к x - свойства "a" и "b" не являются числовыми. Следовательно, они не влияют на массив length.


BTW, если вы заинтересованы в прототипном наследовании, то вы должны читать мой блог на Why Prototypal Inheritance Matters.

0

при создании переменной как

var x=[]; 
x[0] = 0; or x[x.length]=0; or x.push(0); 

его массив, и он будет иметь свойство длины. члены массива могут быть переданы с помощью индекса (который всегда числовой ie0,1,2, ...)

Но когда вы создаете переменную

var x={}; 
x.key1= "value1"; or x["key1"]="value1"; 

становится объект (объект JSON). члены объекта всегда будут ссылаться с помощью клавиш. как x.key1, х, key2 и т.д. ...

вы не можете получить доступ к членам массива по X.0 или x.1 и т.д. ...

надеюсь, это поможет вам

0

к вашему first point: Array - объект функции типа.

console.log(Array); 
function Array() { [native code] } 

Array.prototype с другой стороны, является внутренним реализации методов общих между экземплярами.

Так,

console.log(Array.prototype); 
[] 

Вот почему console.log(Array.prototype.length) возвращает 0. Это пустой массив.

Не думайте о Array.protoype как о экземпляре массива. Это просто внутренняя реализация, на которую вы можете вызвать любой метод объекта-прототипа.

Экземпляр может быть создан с помощью нового оператора. И все экземпляры наследуют объект-прототип функции-конструктора, в данном случае Array.

var arr = new Array(); 

Надеюсь, он уточнит ваш первый пункт.

Смежные вопросы