Usage of typeof in JavaScript

Source: Internet
Author: User

The typeof in JavaScript is actually very complicated. It can be used to do many things, but it also has a lot of weird performances.

This article lists its usage and points out the existing problems and solutions.

The premise of reading this article is that you should now know the difference between the original value and the object value.

Check whether a variable exists and has a value
Typeof will return "undefined" in two cases ":

1. variables are not declared

2. The variable value is undefined.

For example:
Copy codeThe Code is as follows:
> Typeof undeclaredVariable = "undefined"
True

> Var declaredVariable;
> Typeof declaredVariable
'Undefined'

> Typeof undefined
'Undefined'

There are other ways to check whether a value is undefined:

Copy codeThe Code is as follows:
> Var value = undefined;
> Value === undefined
True

However, if this method is used on an undeclared variable, an exception will be thrown, because only typeof can normally detect undeclared variables without returning an error:

Copy codeThe Code is as follows:
> UndeclaredVariable === undefined
ReferenceError: undeclaredVariable is not defined

Note: Non-initialized variables, input parameter parameters, and non-existent attributes will not cause the above problems, because they are always accessible and the values are always undefined:

Copy codeThe Code is as follows:
> Var declaredVariable;
> DeclaredVariable === undefined
True

> (Function (x) {return x === undefined }())
True

> ({}). Foo = undefined
True

Therefore, if you want to check whether a global variable that may not be declared exists, you can also use if (window. maybeUndeclaredVariable ){}.

Problem: typeof is complicated when such a task is completed.

Solution: this operation is not very common, so some people feel that there is no need to find a better solution. However, someone may come up with a special operator:

Copy codeThe Code is as follows:
> Defined undeclaredVariable
False

> Var declaredVariable;
> Defined declaredVariable
False

Alternatively, someone may need an operator that checks whether a variable is declared:

Copy codeThe Code is as follows:
> Declared undeclaredVariable
False

> Var declaredVariable;
> Declared declaredVariable
True

Note: In perl, the defined operator is equivalent to defined (), and the declared operator is equivalent to exists ().

Determines whether a value is not equal to undefined or null.
Problem: If you want to check whether a value has been defined (neither undefined nor null), you will encounter the most famous weird expression of typeof (considered a bug): typeof null returned "object ":

Copy codeThe Code is as follows:
> Typeof null
'Object'

Note: this can only be said to be the bug of the original JavaScript implementation, and the standard is as standard as it is now. V8 corrected and implemented typeof null = "null", but eventually proved unfeasible. Http://wiki.ecmascript.org/doku.php? Id = harmony: typeof_null.

Note: typeof returns "object" when the operation is null, which is a bug in the JavaScript language. Unfortunately, this bug will never be fixed, because too many existing code already depends on this performance. But is null an object? Stackoverflow about this issue: http://stackoverflow.com/questions/801032/null-object-in-javascript/7968470#7968470@justjavac)

Solution: Do not use typeof for this task. Use the following function instead:

Copy codeThe Code is as follows:
Function isDefined (x ){
Return x! = Null & x! = Undefined;
}

Another possibility is to introduce a "Default operator". When myValue is undefined, the following expression returns defaultValue:

Copy codeThe Code is as follows:
MyValue ?? DefaultValue

The above expression is equivalent:

Copy codeThe Code is as follows:
(MyValue! = Undefined & myValue! = Null )? MyValue: defaultValue

Or:

Copy codeThe Code is as follows:
MyValue ?? = DefaultValue

In fact, the following statement is simplified:

Copy codeThe Code is as follows:
MyValue = myValue ?? DefaultValue

When you access a nested attribute, such as bar, you may need the help of this operator:

Copy codeThe Code is as follows:
Obj. foo. bar

If obj or obj. foo is undefined, the above expression will throw an exception. An operator .?? When the above expression traverses a layer-by-layer attribute, the first attribute that is undefined or null is returned:

Copy codeThe Code is as follows:
Obj .?? Foo .?? Bar

The above expression is equivalent:

Copy codeThe Code is as follows:
(Obj = undefined | obj = null )? Obj
: (Obj. foo = undefined | obj. foo = null )? Obj. foo
: Obj. foo. bar

Distinguish between object Value and original value

The following function is used to check whether x is an object value:

Copy codeThe Code is as follows:
Function isObject (x ){
Return (typeof x = "function"
| (Typeof x = "object" & x! = Null ));
}

Problem: The preceding detection is complicated because typeof treats functions and objects as different types, and typeof null returns "object ".

Solution: the following method is often used to detect object values:

Copy codeThe Code is as follows:
Function isObject2 (x ){
Return x = Object (x );
}

Warning: You may think that instanceof Object can be used for detection. However, instanceof uses the prototype of an Object to determine the relationship between instances. What if there is no prototype Object:

Copy codeThe Code is as follows:
> Var obj = Object. create (null );
> Object. getPrototypeOf (obj)
Null

Obj is indeed an object, but it is not an instance of any value:

Copy codeThe Code is as follows:
> Typeof obj
'Object'
> Obj instanceof Object
False

In reality, you may rarely encounter such an object, but it does exist and has its purpose.

Note: Object. prototype is the only built-in Object without a prototype.

Copy codeThe Code is as follows:
> Object. getPrototypeOf (Object. prototype)
Null
> Typeof Object. prototype
'Object'
> Object. prototype instanceof Object
False

What is the type of the original value?
Typeof is the best way to view the type of an original value.

Copy codeThe Code is as follows:
> Typeof "abc"
'String'
> Typeof undefined
'Undefined'

Problem: you must know the weird performance of typeof null.

Copy codeThe Code is as follows:
> Typeof null // be careful!
'Object'

Solution: The following function can solve this problem (only for this case ).

Copy codeThe Code is as follows:
Function getPrimitiveTypeName (x ){
Var typeName = typeof x;
Switch (typeName ){
Case "undefined ":
Case "boolean ":
Case "number ":
Case "string ":
Return typeName;
Case "object ":
If (x = null ){
Return "null ";
}
Default: // The previous judgment fails.
Throw new TypeError ("the parameter is not an original value:" + x );
}
}

A better solution: implement a function getTypeName (). Besides returning the type of the original value, you can also return the internal [[Class] attribute of the object value. This article describes how to implement this function. (The $. type in jQuery is implemented in this way)

Whether a value is a function
Typeof can be used to check whether a value is a function.

Copy codeThe Code is as follows:
> Typeof function (){}
'Function'
> Typeof Object. prototype. toString
'Function'

In principle, instanceof Function can also detect such requirements. At first glance, it seems that the writing style is more elegant. However, the browser has a quirk: Every framework and window has its own global variables. Therefore, if you upload objects in a framework to another framework, instanceof will not work normally, because the two frameworks have different constructors. This is why the Array. isArray () method exists in ECMAScript5. If there is a method that can be used across frameworks to check whether an object is an instance of a given constructor, it will be good. The above getTypeName () is an available work und, but there may be a more fundamental solution.

Summary
As mentioned below, it should be the most urgent need in JavaScript, which can replace some functional features of typeof's current responsibilities:

• IsDefined () (such as Object. isDefined (): can be used as a function or an operator.

• IsObject ()

• GetTypeName ()

• Cross-Framework mechanism for detecting whether an object is an instance of a specified Constructor

Check whether a variable has been declared with such a requirement. It may not be necessary to have its own operators.

 

Related Article

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.