(1)Number 数字javascript
(2)String 字符串html
(3)Boolean 布尔值前端
(4)null 空对象指针java
(5)undefined 为定义es6
(6)symbol (es6新增,表示独一无二的值)面试
(7)bigint(ES10新增,表示比number数据类型支持的范围更大的整数值)数组
注意:NaN是Number中的一种特殊数值,不是一种数据类型函数
object,array和function都是object的子类型性能
(1)声明变量时内存分配不同测试
基本数据类型:在栈中,由于占据空间是固定的,能够将他们存在较小的内存中-栈中,这样便于迅速查询变量的值
引用数据类型:存在堆中,栈中存储的变量,只是用来查找堆中的引用地址。
理由:引用值的大小会改变,因此不能把它放在栈中,不然会下降变量查寻的速度。相反,放在变量的栈空间中的值是该对象存储在堆中的地址。地址的大小是固定的,因此把它存储在栈中对变量性能无任何负面影响
(2)不一样的内存分配带来不一样的访问机制
在javascript中是不容许直接访问保存在堆内存中的对象的,因此在访问一个对象时,首先获得的是这个对象在堆内存中的地址,而后再按照这个地址去得到这个对象中的值,这就是传说中的按引用访问。 而基本数据类型的值则是能够直接访问到的。
(3)复制变量时的不一样
基本数据类型:在将一个保存着原始值的变量复制给另外一个变量时,会将原始值的副本赋值给新变量,此后这两个变量是彻底独立的,他们只是拥有相同的value而已。
引用数据类型:在将一个保存着对象内存地址的变量复制给另外一个变量时,会把这个内存地址赋值给新变量, 也就是说这两个变量都指向了堆内存中的同一个对象,他们中任何一个做出的改变都会反映在另外一个身上。 (这里要理解的一点就是,复制对象时并不会在堆内存中新生成一个如出一辙的对象,只是多了一个保存指向这个对象指针的变量罢了)
(4)参数传递的不一样
基本数据类型:只是把变量的值传递给参数,以后这个参数和变量互不影响
引用数据类型:传递是对象在堆内存里面的地址,他们指向同一个对象。
typeof返回一个表示数据类型的字符串,返回结果包括:number、boolean、string、symbol、object、undefined、function等7种数据类型,但不能判断null、array等
instanceof 是用来判断a是否为b的实例,表达式为:a instanceof b,若是a是b的实例,则返回true,不然返回false。instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性,但它不能检测null和 undefined
constructor做用和instanceof很是类似。但constructor检测 object与instanceof不同,还能够处理基本数据类型的检测。不过函数的 constructor 是不稳定的,这个主要体如今把类的原型进行重写,在重写的过程当中颇有可能出现把以前 的constructor给覆盖了,这样检测出来的结果就是不许确的。
代码示例:
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]
(1)toPrimitive(obj,type)转换为原始值
toPrimitive对基本数据类型不发生转换处理,只针对引用数据类型,做用是将引用数据类型转换为基本数据类型。ToPrimitive运算符有两个参数,第一个参数obj是须要转换的对象,第二个参数type是指望转换为的原始数据类型(可选)
对于参数2 type的说明:
type=String,首先调用obj的toString方法,若是为原始值则return,不然调用obj的valueOf方法,若是为原始值则return,不然抛出TypeError异常
type=Number,首先调用obj的valueOf方法,若是为原始值则return,不然调用obj的toString方法,若是为原始值则return,不然抛出TypeError异常
type参数为空,若是obj是Date对象,则type=String,其它状况把type=Number处理
(2)toString
返回一个表示该对象的字符串,每一个对象都有toString方法,当对象被表示为文本值时或者当以指望字符串的方式引用对象时,该方法自动调用
var obj={}
console.log(obj.toString())//[object Object]
var arr=[1,"111"]
console.log(arr.valueOf())//数组自己
console.log(arr.toString())//1,111
console.log(arr.toLocaleString())//1,111
(3)valueOf
Javascript调用valueOf方法来把对象转换成原始类型的值(数值、字符串、布尔值)。某些状况会被自动调用
array 数组的元素被转换为字符串,这些字符串由逗号分隔,链接在一块儿。其操做与 array.tostring 和 array.join 方法相同。
boolean boolean 值。
date 存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 utc。
function 函数自己。
number 数字值。
object 返回"[object object]",前一个object标记基础类型,后一个object标记子类型
string 字符串值。
math 和 error 对象没有 valueof 方法。
var str="我是string";
var num=5;
var date=new Date();
var obj={
name:"cc",
age:16
}
console.log(str.valueOf())//我是string
console.log(num.valueOf())//5
console.log(date.valueOf())//1574577999115
console.log(obj.valueOf())//{name: "cc", age:16}
(4)Number()
null==》0、undefined==》NaN、true==》一、false==》0
字符串转换时遵循数字常量规则,若是有不是数字的内容则转换失败返回 NaN
Number(null); //0
Number(undefined); //NaN
Number(true); //1
Number(false); //0
Number('1'); //1
Number('a'); //NaN
(5)String()
null、undefined、true、false都加上引号
数字转换遵循通用规则,溢出将以指数形式或者无穷大(Infinity)
String(null) //"null"
String(undefined) //"undefined"
String(true) //"true"
String(1) // '1'
String(-1) // '-1'
String(0) // '0'
String(-0) // '0'
String(Math.pow(1000,10)) // '1e+30'
String(1E+400) // 'Infinity'
String(-Infinity) // '-Infinity'
String({}) // '[object Object]'
String([1,[2,[3,4]],['a']) // '1,2,3,4,a'
String(function (){return 0}) //function({return 0})
(6)Boolean
undefined、null、0、+0、-0、NaN、空字符串转换为false,其他都为true
Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // false
Boolean({}) // true
Boolean([]) // true
Boolean(new Boolean(false)) // true
console.log(typeof 1);//Number
console.log(typeof NaN);//Number
console.log(typeof '1');//String
console.log(typeof null);//Object
console.log(typeof undefined);//undefined
console.log(typeof true);//Boolean
console.log(typeof false);//Boolean
console.log(typeof {});//Object
console.log(typeof []);//Object
console.log(typeof function(){var a=1});//function
特别注意,null、空对象、空数组的结果都是Object,function的结果就是function
一句话归纳:undefined是未定义的,null是定义了可是为空。若是对他俩进行==判断,结果为true。用===判断,结果为false
简单来讲: == 表明相同, ===表明严格相同
理解: 当进行双等号比较时候: 先检查两个操做数数据类型,若是相同, 则进行===比较, 若是不一样, 则愿意为你进行一次类型转换, 转换成相同类型后再进行比较(如何转换看上面的图片), 而===比较时, 若是类型不一样,直接就是false.
操做数1 == 操做数2, 操做数1 === 操做数2
比较过程:
双等号==:
(1)若是两个值类型相同,再进行三个等号(===)的比较
(2)若是两个值类型不一样,也有可能相等,需根据如下规则进行类型转换在比较:
1)若是一个是null,一个是undefined,那么相等
2)若是一个是字符串,一个是数值,把字符串转换成数值以后再进行比较
三等号===:
(1)若是类型不一样,就必定不相等
(2)若是两个都是数值,而且是同一个值,那么相等;若是其中至少一个是NaN,那么不相等。(判断一个值是不是NaN,只能使用isNaN( ) 来判断)
(3)若是两个都是字符串,每一个位置的字符都同样,那么相等,不然不相等。
(4)若是两个值都是true,或是false,那么相等
(5)若是两个值都引用同一个对象或是函数,那么相等,不然不相等
(6)若是两个值都是null,或是undefined,那么相等
console.log(1 + 'true')//‘1true’
console.log(1 + true)//2
console.log(1 + undefined)//NaN
console.log(1 + null)//1
console.log(1 + 'true')//‘1true’【字符串拼接,会把其余数据类型转为字符串而后拼接】
console.log(1 + true)//2 【加法运算会把其余数据类型转为数字再进行加法运算】
5.请说出如下代码的执行结果和理由(关系运算符)
console.log('2'>10)//false
console.log('2'>'10')//true
console.log('abc'>'a')//false
console.log('abc'>'aad')//true
console.log(NaN == NaN )//false
console.log(undefined == null )//true
console.log('2'>10)//false 【关系运算符只有一边是字符串时,会把其余数据类型转为数字,而后比较】
console.log('2'>'10')//true 【若是两边都是字符串,同事转成字符对应的编码值进行比较】
console.log('abc'>'a')//false 【若是是多个字符,从左到右依次比较,先比较‘a’和‘b’,若是不等直接出结果】ps:大小比较的是字符的ASCII码值
console.log('abc'>'aad')//true【若是相等,则比较第二个字符,根据相等于否得出结果】
console.log(NaN == NaN )//false 【NaN和任何数据比较都是false】
console.log(undefined == null )//true【undefined和null使用==断定相等,与自身断定也相等】
console.log([1,2] == '1,2')//true
console.log([1,2].valueOf())// [1,2]
console.log([1,2].toString())// 1,2
var a={}
console.log(a == '[object Object]')//true
console.log(a.valueOf().toString())//[object Object]
当对象和字符串比较时先调用valueOf()再调用toString方法,而后再进行比较
下面看一道进阶题:
var a=???
if(a == 1 && a == 2 && a == 3){
console.log(3)
}
如何填写a,使得函数打印出3
小炉:乍一看,a怎么可能等于一、二、3呢,这题有问题叭!
前端大佬:非也非也,要知道,在数据类型的比较中,有的能够执行valueOf、toString方法的,突破口就在这里,那么咱们重写他的方法,就能够实现改变a值。很少说了,直接上代码:(其余方案传送门)
var a={
i:0,
valueOf:function(){
return ++a.i
}
}
if(a == 1 && a == 2 && a == 3){
console.log(3)
}
代码(1)
console.log([]==0)//true console.log(![]==0)//true
代码(2)
console.log([]==![])//true console.log([]==[])//false
代码(3) console.log({}==!{})//false console.log({}=={})//false
首先,你要知道,关系运算符将其余数据类型转成数字,逻辑非:将其余数据类型使用boolean转为布尔类型。
代码(1)
[].valueOf.toString()获得空串,空串转为数字是0,因此判断[]==0是true
逻辑非优先级高于关系运算符,因此![]先是空数组转为布尔true,而后取反是false。0转为布尔也是false因此判断![]==0是true
代码(2)
逻辑非优先级高于关系运算符,因此![]先是空数组转为布尔true,而后取反是false。而后是空数组转变获得空串,字符串和布尔进行==比较,将他们两者转为数字进行比较。因此都为0,断定最后结果为true。
console.log([]==[])//false 由于是引用数据类型,栈中存的是地址,因此不相等
代码(3)
逻辑非优先级高于关系运算符,先执行{}.valueOf.toString()获得'[object Object]',对他取反为false,而后将他和空对象都数字化,而后获得0==0,断定他们相等,因此结果为true。
console.log({}=={})//false 由于是引用数据类型,栈中存的是地址,因此不相等
1.数据类型分为基本数据类型(7种,ES10新增bigint)和引用数据类型(Object和他的子类型array、function)
2.有四种判断方式,typeOf、instanceOf、constructor、object.prototype.tostring.call()
3.数据类型有强制转换和隐式转换(面试题考点)
4.整体来讲,须要记的东西不少。多练多作题才更熟悉
参考文档:https://www.cnblogs.com/c2016c/articles/9328725.html
https://blog.csdn.net/itcast_cn/article/details/82887895