In JavaScript, we often see code like this: a comparison of variables to null (this usage is very problematic), used to determine whether a variable is given a reasonable value. for example:
var Controller = {process: function(items) {if (items !== null) { // Bad writing method items.sort();items.forEach(function(item) {// Execute some logic});}}}In this code, the process() method obviously expects items to be an array, because we see items have sort() and forEach() . The intention of this code is very obvious: if the parameter items are not a group number, then the next operation will be stopped. The problem with this writing method is that comparison with null cannot really prevent errors. The value of items can be 1, a string, or even any object. These values are not equal to null, which in turn will cause an error when the process() method is executed to sort().
Comparing with null alone does not provide enough information to determine whether subsequent code execution is really safe. Fortunately, JavaScript provides us with many ways to detect the true value of a variable.
Detect original value
There are 5 primitive types (also known as simple data types) in JavaScript: String , Number , Boolean , Undefined , and Null . If you want a value to be String , Number , Boolean , or Undefined , the best option is to use the typeof operator, which returns a string representing the type.
For strings, typeof returns "string".
For numbers, typeof returns "number".
For boolean, typeof returns "boolean".
For undefined, typeof returns "undefined".
The basic syntax of typeof is: typeof variable , you can also use typeof(variable) , although this is the legal JavaScript syntax, which makes typeof look like a function rather than an operator. In view of this, we recommend writing without brackets.
Using typeof to detect these 4 primitive types is very safe. Let’s take a 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 will not report an error when used with an undeclared variable. Undefined variables and variables with value undefined will both return "undefined" via typeof.
The last primitive type null , through typeof, will return "object" , which looks weird and is considered a serious bug in the standard specification, so when programming, you must prevent the use of typeof to detect null types.
console.log(typeof null); // "object"
Simply comparing with null usually does not contain enough information to determine whether the type of value is legal, so null is generally not used in detection statements.
But there is an exception, if the expected value is really null , you can directly compare 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 foreseeable output at this time, the return result can be detected using the identity operator === or the non-identity operator!==.
In addition to the string , number , boolean , undefined , and object mentioned above, the return value of the typeof operator also has function . From a technical point of view, functions are also objects in JavaScript, not data types. However, functions do have some special properties, so it is necessary to distinguish functions from other objects by the typeof operator. This feature will be used in the detection function later.
Detect reference values
In JavaScript, except for the original values, all reference values (also called objects). Commonly used reference types are: Object, Array, Date and RegExp. These reference types are built-in objects in 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"console.log(typeof new RegExp()); // "object"The best way to detect a referenced value type is to use the instanceof operator. The basic syntax of instanceof is:
value instanceof constructor// Detect date if (value instanceof Date) {console.log(value.getFullYear);}// Detect Errorif (value instanceof Error) {throw value;}// Detect regular expression if (value instanceof RegExp) {if (value.test(anotherValue)) {console.log("Matches");}}An interesting feature of instanceof is that it not only detects the constructor that constructs this object, but also detects the prototype chain. The prototype chain contains a lot of information, including the inheritance pattern used to define the object. For example, by default, each object inherits from Object, so the value instance of Object of each object returns ture. for example:
var now = new Date();console.log(now instanceof Object); // the natureconsole.log(now instanceof Date); // the natureinstanceof operator can also detect custom types, such as: function Person(name){this.name = name;}var me = new Person("Nicholas");console.log(me instanceof Object); // the natureconsole.log(me instanceof Person); // the natureThe 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 a ture.
When detecting built-in and custom types in JavaScript, the best way to do this is to use the instanceof operator, which is the only way to do it.
But there is a serious limitation. Assuming that both browser frames (frames) have constructor Person, and the Person instance frameAPersonInstance in frame A is passed into frame B, the following results will be:
console.log(frameAPersonInstance instanceof frameAPerson) // ture
console.log(frameAPersonInstance instanceof frameBPerson) // false
Although the definitions of the two Persons are exactly the same, they are considered to be different types in different frames. 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 speaking, functions in JavaScript are reference types, and there is also Function constructor. Each function is an example, for example:
function myFunc() {}// Bad writing method console.log(myFunc instanceof Function); // trueHowever, this method cannot be used across frames, because each frame has its own Function constructor. Fortunately, the typeof operator can also be used for functions, returning "function".
function myFunc() {}// Good writing method console.log(typeof myFunc === "function"); // trueThe best way to detect a function is to use typeof because it can be used across frames.
There is a limitation to using typeof to detect functions. In IE 8 and earlier IE browsers, typeof is used to detect that functions in DOM nodes all return "object" instead of "function". for example:
// IEconsole.log(typeof document.createElement); // "object"console.log(typeof document.getElementById); // "object"console.log(typeof document.getElementByTagName); // "object"console.log(typeof document.getElementByTagName); // "object"
This weird phenomenon occurs because browsers have differences in implementation of DOM. In short, these earlier versions of IE did not implement the DOM as a built-in JavaScript method, resulting in the built-in typeof operator identifying these functions as objects. Because the DOM is clearly defined, knowing that an object member exists means that it is a method, developers often use the in operator to detect the DOM 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, use this method. Although not the ideal method, it is the safest way to detect whether the DOM method exists in IE 8 and earlier browsers. In all other cases, the typeof operator is the best choice for detecting JavaScript functions.
Detect array
One of the oldest cross-domain problems in JavaScript is passing arrays back and forth between frames. The developer soon discovered that instanceof Array cannot return the correct result in this scenario. As mentioned above, each frame has its own Array constructor, so instances in one frame will not be recognized in another frame.
There has been a lot of research on how to detect array types in JavaScript, and finally Kangax gave an elegant solution:
function isArray(value) {return Object.prototype.toString.call(value) === "[object Array]";}Kangax found that calling a value's built-in toString() method returns standard string results in all browsers. For arrays, the returned string is "[object Array]", and there is no need to consider which frame the array instance is constructed. This method is often very useful when identifying built-in objects, but please do not use this method for custom objects.
ECMAScript5 officially introduces Array.isArray() into JavaScript. The only purpose is to accurately detect whether a value is an array. Like Kangax's functions, Array.isArray() can also detect values passed across frames, so many JavaScript class libraries currently implement this method similarly.
function isArray(value) {if (typeof Array.isArray === "function") {return Array.isArray(value);} else {return Object.prototype.toString.call(value) === "[object Array]";}}IE 9+, FireFox 4+, Safari 5+, Opera 10.5+, and Chrome all implement the Array.isArray() method.
Detect properties
Another scenario where null (and undefined) is when detecting whether an attribute exists in an object, such as:
// Bad writing: detect false values if (object[propertyName]) {// Some code}// Bad writing: compare with null if (object[propertyName] != null) {// Some code}// Bad writing: compare with undefined if (object[propertyName] != undefined) {// Some code}Each judgment in the above code actually checks the value of the attribute by the given name, rather than judging whether the attribute referred to by the given name exists. In the first judgment, the result will be errored when the property value is a false value, such as: 0, "" (empty string), false, null and undefined, after all, these are the legal values of the property.
The best way to determine if an attribute exists is to use the in operator. The in operator simply judges whether the property exists without reading the value of the property. If the property of the instance object exists or inherits from the object's prototype, the in operator will return true. for example:
var object = {count: 0,related: null};// Good writing if ("count" in object) {// The code here will be executed}// Bad writing: Detect false values if (object["count"]) {// The code here will not be executed}// Good writing if ("related" in object) {// The code here will be executed}// Bad writing, check if (object["related"] != null) {// The code here will not be executed}If you just want to check if a certain property of the instance object exists, use the hasOwnProperty() method. All JavaScript objects inherited from Object have this method. If this property exists in the instance, it returns true (if this property exists only in the prototype, it returns false). It should be noted that in IE 8 and earlier versions of IE, DOM objects do not inherit from Object, so this method does not include. That is, you should check whether the DOM object's hasOwnProperty() method exists before calling it.
// This is a good way to write if (object.hasOwnProperty("related")) {// Execute the code here}// If you are not sure whether it is a DOM object, then write if ("hasOwnProperty" in object && object.hasOwnProperty("related")) {// Execute the code here}Because there are IE 8 and earlier versions of IE, when judging whether the attributes of the instance object exist, I prefer to use the in operator. HasOwnProperty() will only be used when judging the instance properties.
Regardless of when you need to detect the existence of a property, use the in operator or hasOwnProperty() . Doing this can avoid many bugs.
The above is the JavaScript detection of original values, reference values, and attributes introduced by the editor. I hope it will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to everyone in time. Thank you very much for your support to Wulin.com website!