js 数据类型

概念:

javaScript的数据类型目前有8种:


image.png
  1. 基础类型存储在栈内存,在引用或拷贝时,会创建一个完全相等的变量;先入后出。
  2. 引用类型存储在堆内存,存储的是地址,多个引用指向同一个地址,这里会涉及一个“共享”的概念。
  3. 栈内存中变量一般在它的当前执行环境结束就会被销毁被垃圾回收制回收, 而堆内存中的变量则不会,因为不确定其他的地方是不是还有一些对它的引用。 堆内存中的变量只有在所有对它的引用都结束的时候才会被回收。


    image.png

实例

let a = {name:'张三', age: 20}
function change(b){
  b.age = 22
  b = {
    name: '李四',
    age: 24
  }
  return b
}
let c = change(a)
console.log(c.age)
console.log(a.age)

答案:24,22
原因:函数传参的b,传递的是对象在堆中的内存地址值,执行b.age就改变了a.age的值,而b={...给参数b重新赋值,有了新的地址,最后返回给了c

数据类型检测

typeof(不能用来判断null和引用类型除function)

typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof console // 'object'
typeof console.log // 'function'

这里null返回了object,这只是 JS 存在的一个悠久 Bug,不代表 null 就是引用数据类型,可直接通过 ‘===null’来判断就好;

引用数据类型除了 function 会判断为 function以外,其余都是 'object',也是无法判断出来的。

instanceof

new 一个对象时,那这个对象就会成为它原型链上的对象,我们可以通过instanceof判断new的对象是否是之前构造函数生成的对象,这样就基本可以判断出这个新对象的数据类型

let Car = function() {}
let benz = new Car()
benz instanceof Car // true
let car = new String('Mercedes Benz')
car instanceof String // true
let str = 'Covid-19'
str instanceof String // false
let num = new Number('2')
num instanceof Number // true

封装一个instanceOf方法

function myInstanceof(target, dataType){
  if(typeof target !== 'object' || taget == null) return false
  // getProtypeOf是Object对象自带的API,能够拿到参数的原型对象
  let proto = Object.getPrototypeOf(dataType)
  while(true){
    if(proto == null) return false
    if(proto == dataType) return true
    proto = Object.getPrototypeOf(proto)
  }
}
console.log(myInstanceof(new Number(123), Number));    // true
console.log(myInstanceof(123, Number));

两种方法结合,typeof用来判断基础数据类型(null除外),instanceof用来判断引用类型

Object.prototype.toString

toString是Object原型上的一个方法,返回"[object Xxx]"格式的字符串,Xxx即数据类型
Object可以直接调用Object.prototype.toString()返回"[object Object ]"
而对于其他对象,则需要通过 call 来调用,才能返回正确的类型信息

Object.prototype.toString({})       // "[object Object]"
Object.prototype.toString.call({})  // 同上结果,加上call也ok
Object.prototype.toString.call(1)    // "[object Number]"
Object.prototype.toString.call('1')  // "[object String]"
Object.prototype.toString.call(true)  // "[object Boolean]"
Object.prototype.toString.call(function(){})  // "[object Function]"
Object.prototype.toString.call(null)   //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g)    //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([])       //"[object Array]"
Object.prototype.toString.call(document)  //"[object HTMLDocument]"
Object.prototype.toString.call(window)  

数据类型转换

强制类型转换

Number()、parseInt()、parseFloat()、toString()、String()、Boolean()。parseInt、parseFloat只转换数字,其它都返回NaN

Number() 方法的强制转换规则
  1. 布尔:false: 0, true: 1
  2. 数字:自身
  3. null: 0
  4. undefined: NaN
  5. 字符串:
    包含数字(或 0X / 0x 开头的十六进制,允许包含正负号)转换为十进制;
    包含有效的浮点格式,将其转换为浮点数值;
    空字符串,将其转换为 0;
    不是以上格式的字符串,均返回 NaN
Boolean()方法的转换规则
  1. false、0、“” 、undefined、null、NaN:‘false
  2. 其余:true

隐式类型转换

凡是通过逻辑运算符 (&&、 ||、 !)、运算符 (+、-、*、/)、关系操作符 (>、 <、 <= 、>=)、相等运算符 (==) 或者 if/while 条件的操作,如果遇到两个数据类型不一样的情况,都会出现隐式类型转换

'=='转换规则
  1. 类型相同,不用转换
  2. 有一个为null或undefined,另一个必须也是,否则返回false
  3. 有一个Symbol,返回false
  4. 一个string、number,转为number再对比
  5. 如果一个操作值是 boolean,那么转换成 number
  6. 如果一个操作值为 object 且另一方为 string、number 或者 symbol,就会把 object 转为原始类型再进行判断(调用 object 的 valueOf/toString 方法进行转换)
null == undefined       // true  规则2
null == 0               // false 规则2
'' == null              // false 规则2
'' == 0                 // true  规则4 字符串转隐式转换成Number之后再对比
'123' == 123            // true  规则4 字符串转隐式转换成Number之后再对比
0 == false              // true  e规则 布尔型隐式转换成Number之后再对比
1 == true               // true  e规则 布尔型隐式转换成Number之后再对比
var a = {
  value: 0,
  valueOf: function() {
    this.value++;
    return this.value;
  }
};
// 注意这里a又可以等于1、2、3
console.log(a == 1 && a == 2 && a ==3);  //true f规则 Object隐式转换
Object的转换规则

对象转换的规则,会先调用内置的 [ToPrimitive] 函数,其规则逻辑如下:

  1. 如果部署了 Symbol.toPrimitive 方法,优先调用再返回;
  2. 调用 valueOf(),如果转换为基础类型,则返回;
  3. 调用 toString(),如果转换为基础类型,则返回;
  4. 如果都没有返回基础类型,会报错。
var obj = {
  value: 1,
  valueOf() {
    return 2;
  },
  toString() {
    return '3'
  },
  [Symbol.toPrimitive]() {
    return 4
  }
}
console.log(obj + 1); // 输出5
// 因为有Symbol.toPrimitive,就优先执行这个;
// 如果Symbol.toPrimitive这段代码删掉,则执行valueOf打印结果为3;
// 如果valueOf也去掉,则调用toString返回'31'(字符串拼接)
// 再看两个特殊的case:
10 + {}
// "10[object Object]",注意:
// {}会默认调用valueOf是{},不是基础类型继续转换,调用toString,返回结果"[object Object]",
// 于是和10进行'+'运算,按照字符串拼接规则来,参考'+'的规则C
[1,2,undefined,4,5] + 10
// "1,2,,4,510",注意[1,2,undefined,4,5]
// 会默认先调用valueOf结果还是这个数组,不是基础数据类型继续转换,
// 也还是调用toString,返回"1,2,,4,5",
// 然后再和10进行运算,还是按照字符串拼接规则,参考'+'的第3条规则

总结

这篇文章是我学习拉勾的若离老师的小课CV的

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,192评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,858评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,517评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,148评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,162评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,905评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,537评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,439评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,956评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,083评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,218评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,899评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,565评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,093评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,201评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,539评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,215评论 2 358

推荐阅读更多精彩内容