一、JavaScript有几种类型的值?
Javascript有两种数据类型,别离是根本数据类型和援用数据类型。其中根本数据类型包含Undefined、Null、Boolean、Number、String、Symbol (ES6新增,示意举世无双的值),而援用数据类型统称为Object对象,次要包含对象、数组和函数。接下来咱们别离看下两者的特点。
二、根本数据类型
1.值是不可变的
var name = 'java';name.toUpperCase(); // 输入 'JAVA'console.log(name); // 输入 'java'
由此可得,根本数据类型的值是不可扭转的
2.寄存在栈区
原始数据类型间接存储在栈(stack)中的简略数据段,占据空间小、大小固定,属于被频繁应用数据,所以放入栈中存储。
3.值的比拟
var a = 1;var b = true;console.log(a == b); // trueconsole.log(a === b); // false
== : 只进行值的比拟,会进行数据类型的转换。
=== : 不仅进行值得比拟,还要进行数据类型的比拟。
三、援用数据类型
1.值是可变的
var a={age:20};a.age=21;console.log(a.age)//21
下面代码阐明援用类型能够领有属性和办法,并且是能够动静扭转的。
2.同时保留在栈内存和堆内存
援用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能;援用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找援用值时,会首先检索其在栈中的地址,获得地址后从堆中取得实体。
3.比拟是援用的比拟
当从一个变量向另一个变量赋援用类型的值时,同样也会将存储在变量中的对象的值复制一份放到为新变量调配的空间中。
var a={age:20};var b=a;b.age=21;console.log(a.age==b.age)//true
下面咱们讲到根本类型和援用类型存储于内存的地位不同,援用类型存储在堆中的对象,与此同时,在栈中存储了指针,而这个指针指向正是堆中实体的起始地位。变量a初始化时,a指针指向对象{age:20}的地址,a赋值给b后,b又指向该对象{age:20}的地址,这两个变量指向了同一个对象。因而,扭转其中任何一个变量,都会相互影响。
此时,如果勾销某一个变量对于原对象的援用,不会影响到另一个变量。
var a={age:20};var b=a;a = 1;b // {age:20}
下面代码中,a和b指向同一个对象,而后a的值变为1,这时不会对b产生影响,b还是指向原来的那个对象。
四、测验数据类型
1.typeof
typeof返回一个示意数据类型的字符串,返回后果包含:number、boolean、string、symbol、object、undefined、function等7种数据类型,但不能判断null、array等
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
instanceof 是用来判断A是否为B的实例,表达式为:A instanceof B,如果A是B的实例,则返回true,否则返回false。instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
[] instanceof Array; //true{} instanceof Object;//truenew Date() instanceof Date;//truenew RegExp() instanceof RegExp//true
对于数组的类型判断,还能够用ES6新增Array.isArray()
Array.isArray([]); // true
instanceof 三大弊病:
- 对于根本数据类型来说,字面量形式创立进去的后果和实例形式创立的是有肯定的区别的
console.log(1 instanceof Number)//falseconsole.log(new Number(1) instanceof Number)//true
从严格意义上来讲,只有实例创立进去的后果才是规范的对象数据类型值,也是规范的Number这个类的一个实例;对于字面量形式创立进去的后果是根本的数据类型值,不是谨严的实例,然而因为JS的涣散特点,导致了能够应用Number.prototype上提供的办法。
- 只有在以后实例的原型链上,咱们用其检测进去的后果都是true。在类的原型继承中,咱们最初检测进去的后果未必精确。
var arr = [1, 2, 3];console.log(arr instanceof Array) // trueconsole.log(arr instanceof Object); // truefunction fn(){}console.log(fn instanceof Function)// trueconsole.log(fn instanceof Object)// true
- 不能检测null 和 undefined
对于非凡的数据类型null和undefined,他们的所属类是Null和Undefined,然而浏览器把这两个类爱护起来了,不容许咱们在里面拜访应用。
3.constructor
constructor作用和instanceof十分类似。但constructor检测 Object与instanceof不一样,还能够解决根本数据类型的检测。
var aa=[1,2];console.log(aa.constructor===Array);//trueconsole.log(aa.constructor===RegExp);//falseconsole.log((1).constructor===Number);//truevar reg=/^$/;console.log(reg.constructor===RegExp);//trueconsole.log(reg.constructor===Object);//false
constructor 两大弊病:
- null 和 undefined 是有效的对象,因而是不会有 constructor 存在的,这两种类型的数据须要通过其余形式来判断。
- 函数的 constructor 是不稳固的,这个次要体现在把类的原型进行重写,在重写的过程中很有可能呈现把之前的constructor给笼罩了,这样检测进去的后果就是不精确的
function Fn(){}Fn.prototype = new Array()var f = new Fnconsole.log(f.constructor)//Array
4.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的援用