Reproduced: JavaScript data types and their detection

 

 

First, the data type classification

Javascript There are two types of data, namely, the basic data types and the reference data type.

Wherein the basic data types including Undefined, Null, Boolean, Number, String, Symbol (ES6 added, represents a unique value)

Object type referred to as reference data objects, including objects, arrays, and functions

 

Second, the basic data types

1. The values ​​are immutable

var name = 'java';
name.toUpperCase(); // 输出 'JAVA'
console.log(name); // 输出  'java'

Thus can be obtained, the value of the basic data types are immutable

2. stored in the stack area

Simple data types directly to the original data segment stored on the stack (Stack) is, occupies a small space, a fixed size, are frequently used data, it is stored into the stack.

3. Comparison of values

var a = 1;
var b = true;
console.log(a == b);    // true
console.log(a === b);   // false

==: were only compare values, will conduct data type conversion.
===: not only worthy comparison, the type of comparative data should be.

Third, the reference data types

1. The value of the variable

var a={age:20};
a.age=21;
console.log(a.age)//21

Reference code above described type can have properties and methods, and can be changed dynamically.

2. Meanwhile stored in the stack memory and heap memory

Reference data type stored in the object heap (heap), and occupies a large space, the size is not fixed, if the stack, will affect the storage performance running; reference data type is stored in the stack pointer, the stack pointer points the start address of the entity. When the interpreter to find reference value, it will first retrieve its address on the stack, obtained from the heap after obtaining the address of the entity.

3. The comparison is relatively cited

When the reference value is assigned to another type of a variable from the variable value of the object it will also be stored in a variable copy into the space allocated for the new variable.

var a={age:20};
var b=a;
b.age=21;
console.log(a.age==b.age)  //true

Above we talked about the basic types and reference types are stored in different memory location, the type of reference objects stored on the heap, while the pointer is stored on the stack, and this stack pointer to what the starting position of the entity. When a variable is initialized, a pointer to an object {age: 20} address, a post assigned to b, b to point to the object and {age: 20} addresses, these two variables point to the same object. Therefore, any change in one variable will affect each other.

At this point, if a variable is a reference to a cancellation of the original object does not affect the other variables.

var a={age:20};
var b=a;
a = 1;
b // {age:20}

The above code, a and b refer to the same object, and then becomes the value of a 1, then no effect on b, b or that point to the original object.

四、检验数据类型

1.typeof  (数组和对象都是返回object)

typeof返回一个表示数据类型的字符串,返回结果包括:number、boolean、string、symbol、object、undefined、function等7种数据类型,但不能判断null、array、object对象等

typeof Symbol(); // symbol 有效
typeof ''; // string 有效
typeof 1; // number 有效
typeof true; //boolean 有效
typeof undefined; //undefined 有效
typeof new Function(); // function 有效
typeof null; //object 无效
typeof [] ; //object 无效
typeof new Date(); //object 无效
typeof new RegExp(); //object 无效

数组和对象返回的都是object,这时就需要使用instanceof来判断

2.instanceof  (不能判断null和undefined)

instanceof 是用来判断A是否为B的实例,表达式为:A instanceof B,如果A是B的实例,则返回true,否则返回false。instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。

[] instanceof Array; //true
{} instanceof Object;//true
new Date() instanceof Date;//true
new RegExp() instanceof RegExp//true

关于数组的类型判断,还可以用ES6新增Array.isArray()

Array.isArray([]);   // true

instanceof 三大弊端:

  • 对于基本数据类型来说,字面量方式创建出来的结果和实例方式创建的是有一定的区别的
console.log(1 instanceof Number)//false
console.log(new Number(1) instanceof Number)//true

从严格意义上来讲,只有实例创建出来的结果才是标准的对象数据类型值,也是标准的Number这个类的一个实例;对于字面量方式创建出来的结果是基本的数据类型值,不是严谨的实例,但是由于JS的松散特点,导致了可以使用Number.prototype上提供的方法。

  • 只要在当前实例的原型链上,我们用其检测出来的结果都是true。在类的原型继承中,我们最后检测出来的结果未必准确。
var arr = [1, 2, 3];
console.log(arr instanceof Array) // true
console.log(arr instanceof Object);  // true
function fn(){}
console.log(fn instanceof Function)// true
console.log(fn instanceof Object)// true
  • 不能检测null 和 undefined

对于特殊的数据类型null和undefined,他们的所属类是Null和Undefined,但是浏览器把这两个类保护起来了,不允许我们在外面访问使用。

3.严格运算符===

只能用于判断null和undefined,因为这两种类型的值都是唯一的。

var a = null
typeof a // "object"
a === null // true

undefined 还可以用typeof来判断

var b = undefined;
typeof b === "undefined" // true
b === undefined // true

4.constructor

constructor作用和instanceof非常相似。但constructor检测 Object与instanceof不一样,还可以处理基本数据类型的检测。

var aa=[1,2];
console.log(aa.constructor===Array);//true
console.log(aa.constructor===RegExp);//false
console.log((1).constructor===Number);//true
var reg=/^$/;
console.log(reg.constructor===RegExp);//true
console.log(reg.constructor===Object);//false 

constructor 两大弊端:

  • null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。

  • 函数的 constructor 是不稳定的,这个主要体现在把类的原型进行重写,在重写的过程中很有可能出现把之前的constructor给覆盖了,这样检测出来的结果就是不准确的

function Fn(){}
Fn.prototype = new Array()
var f = new Fn
console.log(f.constructor)//Array

5.Object.prototype.toString.call()

Object.prototype.toString.call() 最准确最常用的方式。首先获取Object原型上的toString方法,让方法执行,让toString方法中的this指向第一个参数的值。

关于toString重要补充说明:

  • 本意是转换为字符串,但是某些toString方法不仅仅是转换为字符串
  • 对于Number、String,Boolean,Array,RegExp、Date、Function原型上的toString方法都是把当前的数据类型转换为字符串的类型(它们的作用仅仅是用来转换为字符串的)
  • Object上的toString并不是用来转换为字符串的。

Object上的toString它的作用是返回当前方法执行的主体(方法中的this)所属类的详细信息即"[object Object]",其中第一个object代表当前实例是对象数据类型的(这个是固定死的),第二个Object代表的是this所属的类是Object。

Object.prototype.toString.call('') ;   // [object String]
Object.prototype.toString.call(1) ;    // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window是全局对象global的引用

如果觉得文章对你有些许帮助,欢迎在我的GitHub博客点赞和关注,感激不尽!

参考资料

【文章】[ JS 进阶 ] 基本类型 引用类型 简单赋值 对象引用(推荐)

JS判断数据类型的三种方法

JS中的数据类型及判断

Javascript 判断变量类型的陷阱 与 正确的处理方式

判断JS数据类型的四种方法

Guess you like

Origin www.cnblogs.com/zjx304/p/10252031.html