简体   繁体   中英

Learning Array.prototype and calculating its length

first: I recently knew that Array.prototype is itself an array([]).But an amazing thing is that it is not the instance of Array object .How is that possible?What is the reason for this?

Second: Array.prototype has many properties but when u log ie console.log(Array.prototype.length) ,the output is '0' .What is the reason here?I tried this aswell ,the result is same

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

It would be great if u let me know the difference in element and property of an array

First of all objects in JavaScript inherit from other objects, not from constructor functions. Hence the statement "But an amazing thing is that it is not the instance of Array object" is wrong.

Say you have an object called rectangle as follows:

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

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

Now I can calculate the area of this rectangle by calling the method rectangle.area . However say I wanted to create a new rectangle with a different width and height . This is what I would do:

var rectangle2 = Object.create(rectangle);

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

alert(rectangle2.area());

Here the object rectangle2 inherits from the object rectangle . So you see objects actually inherit from other objects, not from constructor functions. Read the following thread for more details:

Questions regarding prototype function

When you precede a function call with the new keyword JavaScript creates a new object which inherits from the prototype of the function. Hence the instance actually inherits from the prototype .

An object a only inherits from an object b if the object b is in the prototype chain of object a . That's the reason we have the isPrototypeOf method.


The next thing to remember is that the instanceof operator doesn't really mean anything. It can be implemented in JavaScript as follows:

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

Hence as you can clearly see an object qualifies as an "instance" of a function only if it inherits from the prototype of that function.

That's the reason why Array.prototype instanceof Array returns false - an object can't inherit from itself.

For more information about how the instanceof operator works read the following thread:

JavaScript inheritance and the constructor property


Finally the length property of an array is always one more than the greatest numeric index of the array. For example:

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

That's the reason Array.prototype.length is 0 - Array.prototype has no numeric keys. However if you assign it a numeric key then the length property will change accordingly:

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

The same applies for x - the properties "a" and "b" are not numeric. Hence they don't affect the length of the array.


BTW if you're interested in prototypal inheritance then you should read my blog post on Why Prototypal Inheritance Matters .

I recently knew that Array.prototype is itself an array ( [] ).

You are right, it is an array. The specification says in §15.4.4, Properties of the Array Prototype Object :

The Array prototype object is itself an array; its [[Class]] is "Array" , and it has a length property (whose initial value is +0 ) and the special [[DefineOwnProperty]] internal method described in 15.4.5.1 .


But an amazing thing is that it is not the instance of Array object. How is that possible? What is the reason for this?

If you tried Array.prototype instanceof Array then the result will indeed be false . Why? Because of the way the instanceof operator works. It compares the prototype of an object with the value of the prototype property of the constructor function.
Ie in this case it does

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

As we can already see in this comparison, we are trying to test whether Array.prototype is its own prototype, which is impossible. The specification also mentions in the same paragraph:

The value of the [[Prototype]] internal property of the Array prototype object is the standard built-in Object prototype object ( 15.2.4 ).

That is, Object.getPrototypeOf(Array.prototype) === Object.prototype and Object.prototype !== Array.prototype . Hence instanceof yields false , but Array.prototype is an array nonetheless.


Array.prototype has many properties but when u log ie console.log(Array.prototype.length) , the output is '0'.

0 being the value of Array.prototype.length is defined in specification (see above).

It would be great if u let me know the difference in element and property of an array

An element of an array is a property with a property name that is a positive 32-bit integer (or 0 ). A property is any other property which does not have such a property name. Those are not considered by any array operations.

The specification provides a more precise description in §15.4, Array Objects :

Array objects give special treatment to a certain class of property names. A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 2 32 −1. A property whose property name is an array index is also called an element .

So you see, if a property name is converted to (the string representation of) an unsigned 32-bit integer and still has the same value, then it is an array index and the associated value is an element of the array.

The specification continuous with

The value of the length property is numerically greater than the name of every property whose name is an array index;

We just learned which property names are considered to be array indexes, those that can be converted to unsigned integers. By that definition, "a" is not an array index, so

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

does not change the length property. But "3" is an array index, so

x["3"] = 42;

changes the length property to 4 .

when you create a variable as

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

its an array and it will have length property. members of array can be referred using index(which is always numeric ie0,1,2, ...)

But when you create a variable as

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

it becomes an object(JSON object). members of object will be always referred using keys. like x.key1, x,key2 etc...

you can not access array members by x.0 or x.1 etc...

hope it helps you

To your first point: Array is an object of type function.

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

Array.prototype on the other hand, is an internal implementation of the methods shared between instances.

So,

console.log(Array.prototype);
[]

That's why console.log(Array.prototype.length) returns 0. It's an empty array.

Don't think of Array.protoype as an instance of Array. It's just an internal implementation on which you can call any method of the prototype object.

An instance can be created with the new operator. And all instances inherit the prototype object of the constructor function, in this case, Array.

var arr = new Array();

Hope it clarifies your first point.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM