You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
typeofFunction;// 'function'typeofnewFunction();// 'function'typeoffunction(){};// 'function'typeofArray;// 'function'typeofArray();// 'object'typeofnewArray();// 'object'typeof[];// 'object'typeofBoolean;// "function"typeofBoolean();// "boolean"typeofnewBoolean();// "object"typeofMath;// 'object'typeofMath();// Math is not a functiontypeofnewMath();// Math is not a constructor
一、七种内置类型和常见引用类型
插个图,来自于《JavaScript语言精髓与编程实践》第三章P184页,后来想想有点多而杂,所以就自己画了些重点内容如上图,有需要的同学可以直接看下面这图
二、特殊的
null
用
typeof
来检查上述七种类型时,返回的是对应的类型字符串值但,有一个例外
null
是唯一一个用typeof
检测会返回object
的基本类型值(注意‘基本’两字)具体的原因,当面试官问到,可以这样吹一波
三、引用类型的子类型:typeof [引用类型] === what ?
上面的图中虽然列出了七种引用类型,但是
typeof ‘引用类型’ === ‘object’
一定成立吗?不,还有一种情况:
typeof ‘某些引用类型’ === ‘function’
还是先直接看一些测试吧,看下答案跟你预想的是不是一回事?
如果全都胸有成竹,那下面这一小节你可以跳过了
1、引用类型中的函数
先看前三句,原来typeof除了能判断
基本类型
和object
之外,还能判断function
类型,函数也属于对象2、引用类型的子类型
拿
Array
举例子Array
是个构造函数,所以直接打印出function但构造出来的
Array()
却又是另一回事了,构造出来的结果是个数组,自然属于引用类型,所以也就打印出了‘object’
3、引用类型中的基本包装类型
Boolean
是个构造函数,第一句没问题Boolean()
直接执行,得出了布尔值,所以得到了‘boolean’
而new出来的是个Boolean对象,具体来说就是:
通过构造函数创建出来的是封装了基本类型值的封装对象
,好好理解一下这句话这里用
String
来举个例子吧,看到了吗,一个封装对象但是,这里不推荐使用这种封装对象,看个例子
a是个对象,对象永远是真,所以……你懂了
个人建议不要轻易去碰包装类型,日常开发直接用字面量就好了(大牛自动忽略这段话)
4、Math到底是什么?
Math和Global(浏览器中替代为window)都是内置的对象,并不是引用类型的一种
不是函数,不是构造器,这个应该能理解了吧。
四、typeof的安全防范机制
首先,我们需要知道
underfined
和undeclared
的区别未定义与未声明
但是,对于typeof来说,这两者都一样,返回的都是underfined
很明显,我们知道b就是undeclared(未声明的),但在typeof看来都是一样
这个特性,可以拿来做些什么呢?
举个简单的例子,在程序中使用全局变量 DEBUG 作为“调试模式”的开关。在输出调试信 息到控制台之前,我们会检查 DEBUG 变量是否已被声明。顶层的全局变量声明 var DEBUG = true 只在 debug.js 文件中才有,而该文件只在开发和测试时才被加载到浏览器,在生产环 境中不予加载。
问题是如何在程序中检查全局变量 DEBUG 才不会出现 ReferenceError 错误。这时 typeof 的 安全防范机制就成了我们的好帮手:
这不仅对用户定义的变量(比如 DEBUG)有用,对内建的 API 也有帮助:
这样的安全防范机制在各式源码中非常常见,可见,大作们早已经把一些基础的东西弄得非常透彻并运用到实践中,所以说,看源码是我们快速提高的一个方式,应该错不了。
五、值
这一part引用自一、内存空间详解 · Sample GitBook
JS的执行上下文生成之后,会创建一个叫做变量对象的特殊对象(关于变量对象在我的其他文章中有讲到),JS的基础类型都保存在变量对象中
但引用数据类型的值是保存在堆内存中的对象。JavaScript不允许直接访问堆内存中的位置,因此我们不能直接操作对象的堆内存空间。
在操作对象时,实际上是在操作对象的引用而不是实际的对象。因此,引用类型的值都是按引用访问的。
这里的引用,我们可以理解为保存在变量对象中的一个地址,该地址与堆内存的实际值相关联。
看到这里,应该就能比较好的理解引用传参的相关问题了,这属于延伸思考,google去吧,学会自我思考和搜索也是一种技能。
六、强制类型转换
《you don’t know JS》中 第一部分第4章
1、抽象值操作
介绍显式和隐式强制类型转换之前,我们需要先掌握字符串、数字和布尔值之间类型转换的基本规则
1️⃣ToString
toString() 可以被显式调用,或者在需要字符串化时自动调用
null 转换为 "null",undefined 转换为 "undefined",true 转换为 "true"。
数字的字符串化则遵循通用规则
极小和极大的 数字使用指数形式:
数组的默认 toString() 方法经过了重新定义,将所有单元字符串化以后再用 "," 连接起 来
2️⃣ ToNumber
其中 true 转换为 1,false 转换为 0。undefined 转换为 NaN,null 转换为 0。
处理失败 时返回 NaN(处理数字常量失败时会产生语法错误)
3️⃣ ToBoolean
先看什么是假值
假值的布尔强制类型转换结果为 false。
从逻辑上说,假值列表以外的都应该是真值(truthy)
再看下假值对象(这东西太有意思了😂)
不是说规定所有的对象都是真值,怎么还会有假值对象呢?
看看d1和d2有什么不同?是不是特有意思?
最后再看真值是什么
真值就是假值列表之外的值
再来看一段有意思的代码
到目前为止,我们得出的一个结论是:[]、{} 和 function(){} 都不在假值列表中,因此它们都 是真值
看几个常用的吧
那是不是记住假值,就知道哪些是真值了?
理论上是的……
那实际上是什么?
真正掌握类型转换!
2、显式类型转换
这个其实很好理解
3、隐式强制类型转换
1️⃣字符串和数字之间的隐式转换
多的不谈了,简单来说就是,如果 + 的其中一个操作数是字符串(或者通过以上步骤可以得到字符串), 则执行字符串拼接;否则执行数字加法。
有个小坑,可以当做程序员饭后趣谈
《you don’t know JS 》中5.1.3章节是这样说的
但目前的chrome浏览器控制台是这样的
对此,你怎么看?😏
{} 其实应该当成一个代码块,而不是一个 Object,当你在console.log使用的时候,{} 被当成了一个 Object
这下是不是印象更深刻了?
2️⃣ 隐式强制类型转换为布尔值
下面的情况会发生 布尔值隐式强制类型转换。
3️⃣ || 与 &&
就一句话,理解了就万岁,称之为“操作数选择器”
只选择其中一个
4、== 与 ===
两个完全截然不同的理解方向,果然,看书还是要看权威的书好
这一段,看完后我只想总结一句,
放弃 == ,拥抱 ===
,其他的不谈了The text was updated successfully, but these errors were encountered: