JavaScript detects raw values, reference values, attributes _javascript tips

Source: Internet
Author: User
Tags hasownproperty

In JavaScript, we often see this code: A comparison of a variable with a null (which is problematic) to determine whether a variable is given a reasonable value. Like what:

var Controller = {
process:function (items) {
if (items!== null) {//bad wording
items.sort ();
Items.foreach (function (item) {
//execute some logic
});
}

In this code, the process () method obviously wants the items to be an array because we see items owning sort () and ForEach (). The intent of this code is obvious: if the parameter items are not a group number, the next action is stopped. The problem with this type of writing is that comparisons with null do not really prevent errors from happening. The value of the items can be 1, or it can be a string or even an arbitrary object. These values are not equal to NULL, which in turn results in an error when the process () method executes to sort ().

Only NULL comparisons do not provide enough information to determine whether subsequent code execution is really safe. Fortunately, JavaScript provides us with a number of ways to detect the true value of a variable.

Detecting raw values

There are 5 original types (also known as simple data types) in JavaScript: String, Number, Boolean, Undefined, and Null. If you want a value that is string, number, Boolean, or Undefined, the best choice is to use the typeof operator, which returns a string representing the type.

For a string, typeof returns "string".

For numbers, typeof returns "number".

For a Boolean value, typeof returns "Boolean".

For undefined, typeof returns "undefined".

The basic syntax for typeof is: typeof variable, you can also use this: typeof (variable), although this is a legitimate JavaScript syntax, this usage makes typeof look like a function rather than an operator. In view of this, we recommend the notation without parentheses.

Using typeof to detect these 4 original types is a very safe practice. Look at the following examples.

Detect "string"
if (typeof name = = = "string") {
anothername = name.substring (3);
}
Detect "number"
if (typeof count = = "Number") {
updatecount (count);
}
Detect "Boolean"
if (typeof found = = "Boolean" && found) {message
("found!");
}
Detect "Undefined"
if (typeof MyApp = = "Undefined") {
MyApp = {
//other code
};
}

The typeof operator is unique in that it is used with an undeclared variable without an error. Variables that are undefined and values that are undefined will return "undefined" through typeof.

The last original type, NULL, returns "Object" Via typeof, which looks odd and is considered a serious bug in the standard specification, so it is necessary to eliminate the use of typeof to detect null types when programming.

Console.log (typeof null); "Object"

A simple comparison with null usually does not contain enough information to determine whether the type of the value is legitimate, so null is generally not applied to the instrumentation statement.

With one exception, if the expected value is really null, you can compare it directly with NULL. For example:

If you need to detect null, use this method
var element = document.getElementById ("My-div");
if (element!== null) {
element.classname = "found";
}

If the DOM element does not exist, the value obtained by document.getElementById () is null. This method either returns a node or returns NULL. Since null is a predictable output, you can detect the return result by using the identity operator = = = or the!== operator.

The return value of the TypeOf operator has a function in addition to the string, number, Boolean, Undefined, and object mentioned above. From a technical standpoint, a function is also an object in JavaScript, not a data type. However, functions do have some special properties, so it is necessary to differentiate functions and other objects by typeof operators. This feature will be used in the later detection function.

Detecting reference values

In JavaScript, in addition to the original values are reference values (also known as objects), commonly used reference types are: Object, Array, Date, and REGEXP, these reference types are built-in objects of JavaScript. The TypeOf operator returns "Object" when judging these reference types.

Console.log (typeof {}); "Object"
Console.log (typeof []);//"Object"
Console.log (typeof new Date ());//"Object"
Console.log ( typeof new RegExp ()); "Object"

The best way to detect a reference value type is to use the instanceof operator, and the basic syntax for instanceof is:

Value instanceof constructor
//detection date
if (value instanceof date) {
console.log (value.getfullyear);
}
Detect error
if (value instanceof error) {
throw value
}
Detection of regular expression
if (value instanceof RegExp) {
if (value.test (Anothervalue)) {
console.log ("matches");
}
}

An interesting feature of instanceof is that it detects not only the constructor that constructs the object, but also the prototype chain. The prototype chain contains a lot of information, including the inheritance pattern used to define the object. For example, each object inherits from object by default, so the value instanceof object for each object returns ture. Like what:

var now = new Date ();
Console.log (now instanceof Object); Ture
Console.log (now instanceof Date);//Ture
The instanceof operator can also detect a custom type, such as:
function person (name) {
this.name = name;
var me = new Person ("Nicholas");
Console.log (Me instanceof Object); Ture
Console.log (Me instanceof person);//Ture

The person type is created in this sample code. The variable me is an instance of person, so me instanceof person is true. As mentioned above, all objects are considered instances of object, so me instanceof object is also ture.

When detecting built-in types and custom types in JavaScript, the best practice is to use the instanceof operator, which is also the only way.

But there is a serious limitation, assuming that two browser frames (frame) have constructor person, the person instance in frame a frameapersoninstance passed into frame B, the following results are available:

Console.log (frameapersoninstance instanceof Frameaperson)//Ture
Console.log (frameapersoninstance instanceof Framebperson)//False
Although the definition of two person is exactly the same, they are considered different types in different frames (frame). There are two very important built-in types that also have this problem: Array and Function, so detecting them generally does not use instanceof.

Detection function

Technically, a function in JavaScript is a reference type, and there is also a function constructor, each of which is an instance of:

function MyFunc () {}
//Bad writing
console.log (myFunc instanceof function);//True

However, this method cannot be used across frames (frame), because each frame has its own function constructor, but the typeof operator can also be used for functions, returning "function".

function MyFunc () {}
//Good notation
console.log (typeof myFunc = = "function");//True

The best way to detect a function is to use typeof, because it can be used across frames (frame).

Using typeof to detect a function has a limit. In IE 8 and earlier versions of IE browsers, using typeof to detect functions in a DOM node returned "object" instead of "function." Like what:

IE8 and earlier versions of IE
Console.log (typeof document.createelement);//"Object"
Console.log (typeof document.getElementById); "Object"
Console.log (typeof document.getelementbytagname);//"Object"

This bizarre behavior occurs because browsers have different implementations of the DOM. In short, these earlier versions of IE did not implement the DOM as a built-in JavaScript method, causing the built-in typeof operators to recognize these functions as objects. Because the DOM is clearly defined, knowing that an object member exists means that it is a method, and developers often use the in operator to detect the DOM's methods, such as:

Detect DOM Method
if ("Queryselectorall" in document) {
var images = Document.queryselectorall ("img");
}

This code checks whether Queryselectorall is defined in the document, and if so, uses this method. Although not the ideal approach, this is the safest way to detect whether a DOM method exists in IE 8 and earlier browsers. In all other cases, the TypeOf operator is the best choice for detecting JavaScript functions.

Instrumentation array

One of the oldest cross-domain problems in JavaScript is passing an array back and forth between frames (frame). Developers soon discovered that the instanceof Array could not return the correct results in this scenario. As mentioned above, each frame has its own Array constructor, so an instance of one frame is not recognized in another frame.

There has been much research on how to detect array types in JavaScript, and finally kangax an elegant solution:

function IsArray (value) {return
Object.prototype.toString.call (value) = = "[Object Array]";
}

Kangax discovers that the built-in toString () method that invokes a value returns the standard string result in all browsers. For arrays, the returned string is "[Object Array]" and does not take into account which frame (frame) The array instance is actually constructed in. This approach is often useful when identifying built-in objects, but do not use this method for custom objects.

ECMASCRIPT5 will formally introduce Array.isarray () into JavaScript. The only purpose is to accurately detect whether a value is an array. As with Kangax functions, Array.isarray () can also detect values passed across frames (frame), so many JavaScript class libraries now implement this method similarly.

function IsArray (value) {
if (typeof Array.isarray = = "function") {return
Array.isarray (value);
} else { C4/>return Object.prototype.toString.call (value) = = "[Object Array]";
}
}

The Array.isarray () method is implemented by IE 9+, FireFox 4+, Safari 5+, Opera 10.5+, and Chrome.

Detection properties

Another scenario where null (and undefined) is used is when detecting whether a property exists in an object, such as:

Bad writing: Detect False value
if (Object[propertyname]) {
//some code
}
//bad writing: and null phase comparison
if (Object[propertyname]!= NULL) {
//some code
}
//bad writing: and undefined compared
if (Object[propertyname]!= undefined) {
//some code
}

Each of the judgments in the above code actually checks the value of the attribute by a given name, rather than the existence of the attribute that the given name refers to. In the first judgment, the result is an error when the property value is false, such as: 0, "" (empty string), false, NULL, and undefined, after all, these are the legitimate values of the property.

The best way to determine whether a property exists is to use the in operator. The in operator simply determines whether a property exists and does not read the value of the property, and returns True if the instance object's properties exist, or inherit from the object's prototype. Like what:

var object = {
count:0,
related:null
};
Good writing
if ("Count" in object) {///
The code here will perform
}
//Bad writing: Detect False value
if (object["Count"]) {
// The code here will not execute
}
//Good
if ("related" in object) {///
The code here will perform
}
//bad writing, detect if
( Object["related"]!= null) {
//The code here will not execute
}

Use the hasOwnProperty () method if you only want to check whether an attribute of an instance object exists. All JavaScript objects that inherit from object have this method and return True if this property exists in the instance (False if the property exists only in the prototype). It should be noted that in IE 8 and earlier versions of IE, DOM objects are not inherited from object and therefore do not include this method. That is, you should first detect the existence of a DOM object before calling the hasOwnProperty () method.

For all non-DOM objects, this is a good notation if
(Object.hasownproperty ("related")) {
//execute the code here
}
//If you are not sure if you are a DOM object, Then write
if ("hasOwnProperty" in Object && object.hasownproperty ("related")) {
//execute code here
}

Because of IE 8 and earlier versions of IE, I prefer to use the in operator when determining whether an instance object's properties exist, and only use hasOwnProperty () when it is necessary to determine the instance properties.

Whenever you need to detect the existence of a property, use the In operator or hasOwnProperty (). Doing so can avoid many bugs.

The above is a small set of JavaScript to introduce the original value of the detection, reference value, attributes, I hope to help everyone, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

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.