原始数据类型与引用数据类型
存储形式
原始数据类型直接存储在栈中简单数据段,占据空间小,大小固定,属于被频繁使用的数据,所以存储在栈中;
引用数据类型直接存储在堆中,占据空间大,大小不固定,如果存储在栈中,将会影响程序运行的性能,引用数据类型在栈中存储了指针,该指针指向堆中实体的起始地址,当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后,从堆中获得实体。
如图所示:
传值方式
原始数据类型:按值传递 原始数据类型是不可变的,只有对象是可变的,有时我们会尝试改变字符串的内容,但是在js中任何看似对string值得修改操作,实际都是创建新的string值,任何方法都无法改变一个原始类型的值
引用数据类型:按引用传递 引用数据类型的值是可变的,引用数据类型的值是同时保存在栈内存和堆内存中的对象 在js中不允许直接访问内存中的位置,这个表示我们不能直接操作对象的内存空间,而我们操作的是对象的引用
在栈区内存保存变量的标识符和地址指针,在堆中保存值
实参与形参
什么是实参?
实参,可以说常量、变量、表达式、函数等,无论实参是什么类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参,因此应预先用赋值,输入等办法使实参获得确定值。
什么事形参?
形参是值形式参数,是定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传递的参数,形参的作用是实现主调函数与被调函数之间的联系,通常将函数所处理的数据,影响函数功能的因素或者函数处理的结果作为形参。
原始数据和引用数据作为实参的区别
若原始数据作为实参传入,则原始数据在函数执行后并不会发生改变。 若引用数据作为实参传入,则引用数据若遇到可改变自身的方法,则会发生改变。
js中的各个数据类型
原始数据类型:
数字/Number、布尔值/Boolean、字符串/String、null、undefined、symbol
引用数据类型:
Object、Function、Array、Date
js中如何判断数据的类型
使用typeof
使用typeof可判别数据是原始数据类型还是引用数据类型,同时可判别原始数据类型中单boolean、number、undefined、string、symbol、function但是在识别null的时候会识别为object类型
console.log(typeof 123) //number
console.log(typeof false) // boolean
console.log(typeof "name") //string
console.log(typeof undefined) // undefined
console.log(typeof function(){}) // function
console.log(typeof Symbol("name")) // symbol
console.log(typeof {name:"name"}) // object
console.log(typeof [1,2,3]) // object
console.log(typeof null) // object
使用instanceof
使用instanceof无法判别原始是可以检测引用数据类型,这是因为instanceof其实是判别数据的原型链上是否存在判别的数据类型,所以instanceof同样可以判别继承关系
class demo{}
let d = new demo()
console.log(d instanceof demo) // true
console.log({id:1} instanceof Object) // true
console.log(function(){} instanceof Function) // true
console.log([1,2,3] instanceof Array) // true
// 原始数据类型
console.log( 123 instanceof Number) // false
console.log(null instanceof Object) // false
使用constructor
除null与undefined之外其余的数据类型都存在constructor属性,因此除null与undefined外都可用constructor方法判断类型,但是该方法是不安全的,因为constructor的指向是可被改变的
console.log(bool.constructor === Boolean);// true
console.log(num.constructor === Number);// true
console.log(str.constructor === String);// true
console.log(arr.constructor === Array);// true
console.log(obj.constructor === Object);// true
console.log(fun.constructor === Function);// true
console.log(s1.constructor === Symbol);//true
使用Object.prototype.toString.call
使用prototype.toString.call是相对较全的判断js的数据类型
// 类型验证
export const typeCompar = (data,type)=>Object.prototype.toString.call(data) === type //类型检验
export const typeUndefined = (data)=>typeCompar(data, "[object Undefined]") // Undefined类型
export const typeFunction = (data)=>typeCompar(data,"[object Function]") // Function类型
export const typeBoolean = (data)=>typeCompar(data,"[object Boolean]") // Boolean类型
export const typeString = (data)=>typeCompar(data, "[object String]") // String类型
export const typeNumber = (data)=>typeCompar(data, "[object Number]") // Number类型
export const typeObject = (data)=>typeCompar(data, "[object Object]") // Object类型
export const typeArray = (data)=>typeCompar(data, "[object Array]") // Array类型
export const typeNull = (data)=>typeCompar(data,"[object Null]") // Null类型
代码调用检测如下:
console.log(typeUndefined(undefined)) // true
console.log(typeFunction(()=>{})) // true
console.log(typeBoolean(true)) // true
console.log(typeString("123")) // true
console.log(typeNumber(2333)) // true
console.log(typeObject({})) // true
console.log(typeArray([])) // true
console.log(typeNull(null)) // true
null与undefined
相似性
在某种程度上来说,在使用层面区分很小,实际业务场景都用来表示“无”,并且在if判断中两者都代表false
console.log(Boolean(null)) // false
console.log(Boolean(undefined)) // false
不同性
null代表此处不该有值,将null转换为数字时为0,在规范中更类似于引用数据类型的无 undefined代表此处该有值,但是未赋值,将undefined转换为数字时为NaN,在规范中更类似于原始数据类型的无
console.log(Number(undefined)) // NaN
console.log(Number(null)) // 0
隐式转换
js中不同的数据类型之间的比较可以进行隐式转换,规则如下:
对象与布尔值比较
对象与布尔值比较时,对象先转换为字符串,然后再转换为数字,布尔值直接转换为数字
[] == true; // false []转换为字符串'',然后转换为数字0,true转换为数字1,所以结果为false
对象和字符串比较
对象和字符串进行比较时,对象转换为字符串,然后两者进行比较
[1,2,3] == '1,2,3'; // true
对象和数字比较
对象和数字进行比较时,对象先转换为字符串,然后转换为数字,再和数字进行比较
[1] == 1; // true
字符串和数字比较
字符串和数字比较时,字符串转换为数字,二者再进行比较
'1' == 1 // true
字符串和布尔值比较
字符串和布尔值比较时,二者全部转换为数字进行比较
'1' == true // true
布尔值和数字比较
布尔值和数字比较时,布尔值转换为数字,二者比较
true == 1; // true
结语
javascript是一种弱类型脚本语言,在实际开发中,若要进行快速、高质量的开发,不能不了解其数据类型,只有在了解其数据类型及其相关知识,才能成为一名优秀的前端开发人员。