Array, Array Constructor, for in loop, typeof, instanceOf

Source: Internet
Author: User
Tags hasownproperty

Note: arrays in JavaScript are not associated arrays. In JavaScript, only objects are used to manage key-value mappings. However, the associated array maintains the order, but the object is not.

Because the for in loop will enumerate all attributes on the prototype chain, the only way to filter these attributes is to use the 'hasownproperties' function, so it will be much slower than the common for loop.

Iteration)
To achieve the best performance of traversing arrays, we recommend that you use a classic for loop.
Copy codeThe Code is as follows:
Var list = [1, 2, 3, 4, 5, ....... 100000000];
For (var I = 0, l = list. length; I <l; I ++ ){
Console. log (list [I]);
}

The preceding Code caches the length of an array through l = list. length.

Although length is an attribute of an array, accessing it in each loop still has performance overhead. The latest JavaScript Engine may have been optimized at this point, but we cannot ensure that our code runs on these recent engines.

In fact, the method of not using the cached array length is much slower than that of the cached version.

'Length' property (The 'length' property)
The getter method of the length attribute simply returns the length of the array, while the setter method truncates the array.
Copy codeThe Code is as follows:
Var foo = [1, 2, 3, 4, 5, 6];
Foo. length = 3;
Foo; // [1, 2, 3]

Foo. length = 6;
Foo; // [1, 2, 3]

Note: In Firebug, the foo value is: [1, 2, 3, undefined], but the result is not accurate, if you view the foo result on the Chrome console, you will find that: [1, 2, 3] Because undefined is a variable in JavaScript, note that the variable is not a keyword, therefore, the meanings of the above two results are completely different.

// Translator's note: for verification, we will execute the following code to check whether serial number 5 exists in foo.
5 in foo; // No matter in Firebug or Chrome, false is returned.
Foo [5] = undefined;
5 in foo; // true is returned no matter in Firebug or Chrome.
Setting a smaller value for length truncates the array, but increasing the value of length does not affect the array.

Conclusion (In conclusion)
For better performance, we recommend that you use a common for loop and cache the length attribute of the array. Using for in to traverse arrays is considered a bad code habit and tends to produce errors and cause performance problems.

Array Constructor
Since the Array constructor is ambiguous about how to process parameters, we always recommend that you use the Array literal syntax-[]-to create an Array.

[1, 2, 3]; // result: [1, 2, 3]
New Array (1, 2, 3); // result: [1, 2, 3]

[3]; // result: [3]
New Array (3); // result: []
New Array ('3') // result: ['3']
Note: here the ambiguity refers to the two constructor syntax var arr1 = new Array (arrayLength); var arr2 = new Array (element0, element1 ,..., elementN );

// Translator's note: The following code will be confusing.
New Array (3, 4, 5); // result: [3, 4, 5]
New Array (3) // result: [], the Array length is 3
Since only one parameter is passed to the constructor (Note: it refers to new Array (3); this call method), and this parameter is a number, the constructor returns an empty array with the length attribute set to this parameter. Note that only the length attribute is set, and the real array is not generated. Note: In Firebug, you will see [undefined, undefined, undefined], which is actually incorrect. Detailed analysis is provided in the previous section.

Var arr = new Array (3 );
Arr [1]; // undefined
1 in arr; // false. The array has not been generated.
This method takes precedence over setting the array Length attribute and is only useful in a few cases. for example, loop strings are required to avoid the trouble of for loop.

New Array (count + 1). join (stringToRepeat );
// Note: new Array (3). join ('#') will return "##"
Conclusion (In conclusion)
Avoid using arrays to create new arrays. We recommend that you use the literal Syntax of arrays. They are more short and concise, thus increasing the readability of the Code.

For in Loop
Like the in operator, the for in loop traverses all attributes of the prototype chain when searching for object attributes.

Note: The for in loop does not traverse the attributes whose enumerable is set to false, such as The length attribute of the array.
Copy codeThe Code is as follows:
// Modify Object. prototype
Object. prototype. bar = 1;

Var foo = {moo: 2 };
For (var I in foo ){
Console. log (I); // two attributes are output: bar and moo.
}

Because it is impossible to change the behavior of for in itself, it is necessary to filter out the attributes that do not want to appear in the loop body, which can be done through the 'hasownproperties' function on the Object. prototype.

Note: Because for in always needs to traverse the entire prototype chain, if an object's inheritance level is too deep, performance will be affected.

Use 'hasownproperties' to filter (Using 'hasownproperties' for filtering)
Copy codeThe Code is as follows:
// The foo variable is in the previous example.
For (var I in foo ){
If (foo. hasOwnProperty (I )){
Console. log (I );
}
}

The code of this version is the only correct method. Because hasOwnProperty is used, only moo is output this time. If hasOwnProperty is not used, this Code may cause errors when the native Object prototype (such as Object. prototype) is extended.

A widely used class library Prototype extends native JavaScript objects. Therefore, when this class library is included in the page, the for in loop that does not use hasOwnProperty filter will inevitably cause problems.

Best practices)
HasOwnProperty is always recommended. Do not make any assumptions about the environment where the code is running, or whether the native object has been extended.

Typeof Operator
The typeof operator (together with 'instanceof ') is perhaps the biggest design defect in JavaScript, because it is almost impossible to get the desired results from them.

Although instanceof has a very small number of application scenarios, typeof has only one practical application (Note: This practical application is used to detect whether an object has been defined or assigned a value ), this application is not used to check the object type.

Note: Because typeof can also be called like the function syntax, such as typeof (obj), this is a function call. The two parentheses are only used to calculate the value of an expression. The return value is used as an operand of the typeof operator. In fact, there is no function named typeof.

The JavaScript type table)
Value Class Type
-------------------------------------
"Foo" String string
New String ("foo") String object
1.2 Number number
'New Number (1.2) Number object
True Boolean boolean
New Boolean (true) Boolean object
New Date () Date object
New Error () Error object
[1, 2, 3] Array object
New Array (1, 2, 3) Array object
New Function ("") Function
/Abc/g RegExp object (function in Nitro/V8)
New RegExp ("meow") RegExp object (function in Nitro/V8)
{} Object
New Object () Object object
In the preceding table, the Type column represents the operation result of the typeof operator. We can see that this value returns "object" in most cases ".

The Class column indicates the value of the object's internal attribute [[Class.

The value of [[Class] can only be one of the following strings: Arguments, Array, Boolean, Date, Error, Function, JSON, Math, Number, object, RegExp, String.

To obtain [[Class] of an Object, we need to use the toString method defined on Object. prototype.

The Class of an object)
The JavaScript standard document only provides a method to obtain the value of [[Class], that is, Object. prototype. toString.
Copy codeThe Code is as follows:
Function is (type, obj ){
Var clas = Object. prototype. toString. call (obj). slice (8,-1 );
Return obj! = Undefined & obj! = Null & clas = type;
}

Is ('string', 'test'); // true
Is ('string', new String ('test'); // true

In the preceding example, the Object. prototype. toString method is called. this is set to the Object that needs to obtain the value of [[Class.

Note: Object. prototype. toString returns a string in the standard format. Therefore, the preceding example uses slice to capture the string at the specified position, as shown below:
Copy codeThe Code is as follows:
Object. prototype. toString. call ([]) // "[object Array]"
Object. prototype. toString. call ({}) // "[object Object]"
Object. prototype. toString. call (2) // "[object Number]"

ES5 tip: In ECMAScript 5, for convenience, to call the Object. prototype. toString Method for null and undefined, the returned values are changed from Object to Null and Undefined.

Note: the differences between IE8 and Firefox 4 are as follows:
Copy codeThe Code is as follows:
// IE8
Object. prototype. toString. call (null) // "[object Object]"
Object. prototype. toString. call (undefined) // "[object Object]"

// Firefox 4
Object. prototype. toString. call (null) // "[object Null]"
Object. prototype. toString. call (undefined) // "[object Undefined]"
Test as a variable (Testing for undefined variables)
Typeof foo! = 'Undefined'

The code above checks whether foo has been defined. If it is not defined, direct use will cause ReferenceError exceptions. This is the only useful part of typeof.

Conclusion (In conclusion)
To check the type of an Object, we strongly recommend that you use the Object. prototype. toString method, because this is the only method that can be depended on. As shown in the above table, some return values of typeof are not defined in the standard document, so different engine implementations may be different.

Unless we want to check whether a variable has been defined, we should try to avoid using the typeof operator.

Instanceof Operator
The instanceof operator is used to compare the constructors of two operands. It makes sense only when comparing custom objects. If it is used to compare the built-in types, it will be of little use like the typeof operator.

Compare custom objects (Comparing m objects)
Copy codeThe Code is as follows:
Function Foo (){}
Function Bar (){}
Bar. prototype = new Foo ();

New Bar () instanceof Bar; // true
New Bar () instanceof Foo; // true

// If you only set Bar. prototype to function Foo, rather than an instance of the Foo constructor
Bar. prototype = Foo;
New Bar () instanceof Foo; // false
'Instanceof 'compared with the built-in type (Using 'instanceof' with native types)
New String ('foo') instanceof String; // true
New String ('foo') instanceof Object; // true

'Foo' instanceof String; // false
'Foo' instanceof Object; // false

Note that an error occurs when instanceof is used to compare objects with different JavaScript contexts (for example, different document structures in a browser), because their constructors are not the same object.

Conclusion (In conclusion)
The instanceof operator should only be used to compare custom objects from the same JavaScript context. Like the 'typeof 'operator, any other usage should be avoided.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.