Array, array constructor, for in Loop, typeof, Instanceof_javascript tips

Source: Internet
Author: User
Tags array length class definition object object hasownproperty
Note: The array in JavaScript is not an associative array. Only objects in JavaScript can manage the corresponding relationship of key values. But associative arrays are kept in order, and objects are not.

Because the for in loop enumerates all the properties on the prototype chain, the only way to filter these properties is by using the ' hasownproperty ' function, so that it will be many times slower than the normal for loop.

Traversal (Iteration)
In order to achieve the best performance of traversing arrays, the classic for loop is recommended.
Copy Code code 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 code above has a process of caching the length of an array through L = list.length.

Although length is an attribute of an array, there is a performance overhead in accessing it in each loop. Perhaps the latest JavaScript engine has been optimized for this, but we can't guarantee that our code is running on these latest engines.

In fact, it is much slower than cached versions to not use the length of the cached array.

' Length ' attribute (the ' length ' property)
The getter method of the length property simply returns the length of the array, and the setter method truncates the array.
Copy Code code as follows:

var foo = [1, 2, 3, 4, 5, 6];
Foo.length = 3;
Foo [1, 2, 3]

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

Translator Note: In Firebug the value of Foo at this time is: [1, 2, 3, undefined, undefined, undefined] but this is not an accurate result, and if you look at the results of Foo on the Chrome console, you'll find this: [1 , 2, 3] because undefined is a variable in JavaScript, note that a variable is not a keyword, so the meaning of the above two results is completely different.

For verification, we'll execute the following code to see if ordinal 5 exists in Foo.
5 in Foo; return false either in Firebug or Chrome
FOO[5] = undefined;
5 in Foo; return true either in Firebug or Chrome
Setting a smaller value for length truncates the array, but increasing the length property value does not affect the pairs.

conclusion (In conclusion)
For better performance, it is recommended that you use a normal for loop and cache the length property of the array. Traversing an array with a for in is considered a bad code habit and tends to generate errors and cause performance problems.

Array Constructor
Because the array's constructor is somewhat ambiguous in how it handles arguments, it is always recommended that you use the literal syntax of an array-[]-to create an array.

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

[3]; Results: [3]
New Array (3); Results: []
New Array (' 3 ')//Result: [' 3 ']
Translator Note: The ambiguity here refers to the two constructors of the array syntax var arr1 = new Array (arraylength); var arr2 = new Array (element0, Element1, ..., ELEMENTN);

So the code below would be confusing.
New Array (3, 4, 5); Results: [3, 4, 5]
New Array (3)//Result: [], this array length is 3
Because there is only one argument passed into the constructor (translator note: The new Array (3); This is called, and the parameter is a number, and the constructor returns an empty array of the length property that is set to this parameter. It should be noted that only the length property is set at this time, and the real array is not generated. In Firebug, you will see [Undefined, Undefined, undefined], which is actually wrong. Detailed analysis is available in the previous section.

var arr = new Array (3);
ARR[1]; Undefined
1 in Arr; False, the array has not yet been generated
This preference over setting array length attributes is only useful in a few situations, such as the need to loop strings, to avoid the hassle of a for loop.

New Array (count + 1). Join (Stringtorepeat);
Translator Note: The new Array (3). Join (' # ') will return "# #"
conclusion (In conclusion)
You should try to avoid using array constructors to create new arrays. It is recommended that you use the literal syntax of an array. They are shorter and more concise, thus increasing the readability of the code.

For In loop
As in the in operator, for-in loops also traverse all properties on the prototype chain when looking for object properties.

Note: The For In loop does not traverse those properties that enumerable set to false, such as the length property of the array.
Copy Code code as follows:

Modify Object.prototype
Object.prototype.bar = 1;

var foo = {Moo:2};
for (var i in Foo) {
Console.log (i); Output two properties: Bar and Moo
}

Because it is not possible to change the behavior of for in itself, it is necessary to filter out those attributes that do not want to appear in the loop body, which can be accomplished by the ' hasownproperty ' function on the Object.prototype prototype.

Note: Because for-in always traverses the entire prototype chain, it can affect performance if an object's inheritance level is too deep.

Use ' hasOwnProperty ' filter (using ' hasOwnProperty ' for filtering)
Copy Code code as follows:

The Foo variable is the example in the
for (var i in Foo) {
if (Foo.hasownproperty (i)) {
Console.log (i);
}
}

This version of the code is the only correct way to spell it. Since we used hasownproperty, we only output moo this time. If you do not use hasOwnProperty, this code may have an error 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, a for in loop that does not use the hasOwnProperty filter will inevitably cause problems.

Best practices (top practices)
It is always recommended to use hasOwnProperty. Do not make any assumptions about the environment in which the code is running, and do not assume that the native object has been extended.

typeof operator
The typeof operator (together with ' instanceof ') may be the biggest design flaw in JavaScript, because it's almost impossible to get the desired results from them.

Although Instanceof still has a few application scenarios, typeof has only one practical application (Translator Note: This practical application is used to detect whether an object has been defined or assigned), and this application is not used to check the type of object.

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

JavaScript Types Table (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 function
/abc/g RegExp Object (function in NITRO/V8)
New RegExp ("Meow") RegExp object (function in NITRO/V8)
{} Object Object
New Object () object
In the table above, Type a column represents the result of the operation of the typeof operator. As you can see, this value returns "Object" in most cases.

Class a column represents the value of an object's internal property [[Class]].

JavaScript standard document definition: [[Class]] value may only be one of the following strings: Arguments, Array, Boolean, Date, Error, Function, JSON, Math, number, objec T, RegExp, String.

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

class definition of object (the class of an object)
The JavaScript standard document only gives a way to get [[Class]] values, and that is to use Object.prototype.toString.
Copy Code code 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 example above, the Object.prototype.toString method is called, this is set to obtain an object that requires a [[Class]] value.

Translator Note: Object.prototype.toString returns a standard format string, so the previous example can intercept the string at the specified position by slice, as follows:
Copy Code code 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, the Object.prototype.toString method is called on null and undefined, and its return value is changed from Object to null and undefined.

Translator Note: This change can be seen from IE8 and Firefox 4, as follows:
Copy Code code 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 for definition variable (testing for undefined variables)
typeof foo!== ' undefined '

The code above detects whether Foo has been defined, and if it is not defined, it can cause referenceerror exceptions. This is the only useful place for TypeOf.

conclusion (In conclusion)
In order to detect the type of an object, it is strongly recommended to use the Object.prototype.toString method, because this is the only way to rely. As shown in the table above, some of the return values for typeof are not defined in the standard document, so different engine implementations may be different.

Unless you want to detect 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 the two operands. It is only meaningful to compare a custom object. If used to compare built-in types, it will be as useful as the TypeOf operator.

Compare custom objects (comparing custom objects)
Copy Code code 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 as a function of Foo, not an instance of the Foo constructor
Bar.prototype = Foo;
New Bar () instanceof Foo; False
' instanceof ' compares built-in types (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

It is important to note that instanceof is used to compare objects belonging to different JavaScript contexts (for example, different document structures in browsers), because their constructors are not the same object.

conclusion (In conclusion)
The instanceof operator should be used only to compare custom objects from the same JavaScript context. As with 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.