一、基本数据类型
Number、String、Boolean、null、undefined、Symbol(ES6)、BigInt(ES10)
二、引用数据类型
Object(包含Array、Function、Date)
三、基本数据类型和引用数据类型的区别
1.声明变量时内存分配不一样
基本数据类型:存储在栈中,因为占据空间是固定的,可以将他们存在较小的内存——栈,这样便于迅速查询变量的值。
引用数据类型:存储在堆中,栈中存储的变量,只是用来查找堆中的引用地址。
理由:引用值的大小会改变,所以不能把它放在栈中,否则会降低变量查寻的速度。相反,放在变量的栈空间中的值是该对象存储在堆中的地址。地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响
2.不同的内存分配带来不同的访问机制
在javascript中是不允许直接访问保存在堆内存中的对象的,所以在访问一个对象时,首先得到的是这个对象在堆内存中的地址,然后再按照这个地址去获得这个对象中的值,这就是按引用访问。 而基本数据类型的值则是可以直接访问到的。
3.复制变量时的不同
基本数据类型:将一个保存着原始值的变量复制给另一个变量时,会将原始值的副本赋值给新变量,此后这两个变量是完全独立的,他们只是值相同。
引用数据类型:在将一个保存着对象内存地址的变量复制给另一个变量时,会把这个内存地址赋值给新变量, 也就是说这两个变量都指向了堆内存中的同一个对象,他们中任何一个作出的改变都会反映在另一个身上。 (这里要理解的一点就是,复制对象时并不会在堆内存中新生成一个一模一样的对象,只是多了一个保存指向这个对象指针的变量)
4.参数传递的不同
基本数据类型:只是把变量的值传递给参数,之后这个参数和变量互不影响
引用数据类型:传递是对象在堆内存里面的地址,他们指向同一个对象。
四、数据类型的判断方式
1.typeof
var s = "Nicholas";
var b = true;
var i = 22;
var u;
var n = null;
var o = new Object();
function aa(){ console.log(1)}
alert(typeof s); //string
alert(typeof i); //number
alert(typeof b); //boolean
alert(typeof u); //undefined
alert(typeof n); //object
alert(typeof aa); //function
alert(typeof o); //object
typeof的返回值共有7种,分别为:number、boolean、string、symbol、object、undefined、function。但是当遇到null和array时都会返回Object。
2.instanceof
instanceof 用来检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。 语法:object(实例对象) instanceof constructor(构造函数)。是的话返回 true,否则返回 false。所以, instanceof 运算符只能用作对象的判断。 针对 typeof 不能判断的引用型数据,我们可以使用 instanceof 运算符。
let arr1 = [1, 2, 3];
let obj1 = {
name: '小明'
};
function Persion() { }
let persion1 = new Persion();
console.log(arr1 instanceof Array); // true
console.log(arr1 instanceof Object); // true,Array 是Object的子类
console.log(obj1 instanceof Object); // true
console.log(obj1 instanceof Array); // false
console.log(Persion instanceof Function, Persion instanceof Object); // true true
console.log(null instanceof Object); // false
console.log(persion1 instanceof Persion, persion1 instanceof Function, persion1 instanceof Object); // true false true
// String对象和Date对象都属于Object类型
let str1 = 'Hello';
let str2 = new String();
let str3 = new String('你好');
let myDate = new Date();
console.log(str1 instanceof String, str1 instanceof Object); // false, false
console.log(str2 instanceof String, str2 instanceof Object); // true, true
console.log(str3 instanceof String, str3 instanceof Object); // true, true
console.log(myDate instanceof Date, myDate instanceof Object); // true, true
其实 instanceof 主要的实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的prototype,如果查找失败,则会返回 false,告诉我们左边变量并非是右边变量的实例。instanceof 只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型。
3.constructor
constructor 在其对应对象的原型下面,是自动生成的。当我们写一个构造函数的时候,程序会自动添加:构造函数名.prototype.constructor = 构造函数名
var str = 'hello';
alert(str.constructor == String);//true
var bool = true;
alert(bool.constructor == Boolean);//true
var num = 123;
alert(num.constructor ==Number);//true
var nul = null;
alert(nul.constructor == Object);//报错
var und = undefined;
alert(und.constructor == Object);//报错
var oDate = new Date();
alert(oDate.constructor == Date);//true
var json = {};
alert(json.constructor == Object);//true
var arr = [];
alert(arr.constructor == Array);//true
var reg = /a/;
alert(reg.constructor == RegExp);//true
var fun = function(){};
alert(fun.constructor ==Function);//true
var error = new Error();
alert(error.constructor == Error);//true
注意:undefined和null是不能够判断出类型的,并且会报错。因为null和undefined是无效的对象,并不存在constructor,同时使用constructor是不准确的,constructor属性是可以被修改的,会导致检测出的结果不正确。
4.Object.prototype.toString
toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object x] ,其中 x就是对象的类型。 对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。
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]
5.总结
- typeof适用于基本类型的判断(除开null)
- instanceof适用于引用数据类型的判断
- constructor基本可以检测所有的类型(除开null和undefined),结果不准确,容易被修改
- Object.prototype.toString.call可以判断出所有的类型(推荐使用)
五、数据类型的转换
1.主动转换
(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 布尔值。
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()
-
如果是 Boolean 值,true 和 false 将分别被转换为 1 和 0。
-
如果是数字值,只是简单的传入和返回
-
如果是 null 值,返回 0
-
如果是 undefined,返回 NaN。
-
如果是字符串,遵循下列规则:
- 如果字符串中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值,即"1" 会变成 1,"123"会变成 123,而"011"会变成 11(注意:前导的零被忽略了);
- 如果字符串中包含有效的浮点格式,如"1.1",则将其转换为对应的浮点数值(同样,也会忽 略前导零);
- 如果字符串中包含有效的十六进制格式,例如"0xf",则将其转换为相同大小的十进制整 数值;
- 如果字符串是空的(不包含任何字符),则将其转换为 0;
- 如果字符串中包含除上述格式之外的字符,则将其转换为 NaN。
-
如果是对象,则调用对象的 valueOf()方法,然后依照前面的规则转换返回的值。如果转换 的结果是 NaN,则调用对象的 toString()方法,然后再次依照前面的规则转换返回的字符 串值。
Number(null); //0 Number(undefined); //NaN Number(true); //1 Number(false); //0 Number('1'); //1 Number('a'); //NaN
(5)String()
null、undefined、true、false都加上引号,数字加上引号,只有0不区分正负,溢出则改为指数或者无穷大加引号
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
2.隐式转换
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!