第一章 类型
JS 是一门动态语言,没有类型可言,我们这样来定义JS中的“类型”:类型是值的内部特征,定义了一部分值的行为,以使其区别于其他值。
1.2 内置类型
JS 有7种内置类型:①null②undefined③boolean④number⑤string⑥object⑦symbol
除了object之外,其他类型称为基本类型。
JS 中,我们使用 typeof 来查看值的类型,返回的是类型的字符串值。其中 null 似乎有点特殊
typeof undefined === 'undefined' //true
typeof true === 'boolean' //true
typeof 42 === 'number' //true
typeof "42" === 'string' //true
typeof { name:"xiaochen" } === 'object' //true
typeof Symbol() === 'symbol' //true
typeof null === "object" //true
对于 null 存在的 bug 由来已久,也许不会去修复,因为牵涉到太多 Web 系统,修复之后会产生更多的bug。如果我们想检测 null 值的类型,需要
let a = null
(!a && typeof a === 'object')
六种基本类型中,null 和 undefined 为 falsy 值
注意如下几种情况:
function foo() {}
typeof foo === "object" //false
typeof foo === "function" //true
let arr = [];
typeof arr === "object" //true
let obj = {};
obj === null //false
!obj //false
!null //true
这样看来,函数 function 也是 JS 的一个内置类型,然而规范中有提到:函数是 object 的一个“子类型”,具体来说,函数是“可调用对象”,它有一个内部属性 [[Call]](就像[[Prototype]]、[[Scope]]),使得其可以被调用。数组也是 object 的一个“子类型”。
函数和数组拥有属性:
function foo(){}
foo.length //参数的个数
foo.name//函数名
let arr = []
arr.length
第二章 值
2.5 值和引用
在 C++ 中,如果想要向函数传递一个数字并在函数中修改它的值,可以这样声明参数: int& num,如果传递的是变量 x,那么 x 和 num 着同一个值。实质上,num 和 x 就是互为别名的关系。
但如果这样声明参数:int num,意味着 x 和 num 会分别代表一个值。实质上,num 为x的一个副本,num 和 x 此时完全不相关。
JS 更类似于 Java 中,没有int&的语法,对于值或者引用的赋值/传递在语法上没有区别,完全根据值的类型来决定。
- 基本类型的变量总是通过值复制的方式来赋值/传递,包括null、undefined、字符串、数字、布尔、symbol
- 引用类型的变量总是通过引用复制的方式来赋值/传递,包括object及其子类型(数组、函数等)
JS 中的引用和 C++ 中的引用完全不同,JS 的引用类似于 C++ 的指针。
//值复制
let a = 2
let b = a
b++
console.log(a) //2
console.log(b) //3
//引用复制
let c = [1, 2, 3]
let d = c
d.push(4)
console.log(c) //[1, 2, 3, 4]
console.log(d) //[1, 2, 3, 4]
注意:a 和 b 是互为副本的关系,所以 a 和 b 没有任何关系。
注意:c 和 d 其实保存着同一个数组对象的地址,如果通过 d 修改对象,c会受到影响。但如果令 d 指向其他对象(保存另一个地址),c 不会受到任何影响。
let c = [1, 2, 3]
let d = c
d = [4, 5, 6]
console.log(c) //[1, 2, 3]
console.log(d) //[4, 5, 6]
如果我们想通过值复制的方式来传递一个引用类型变量,我们必须预先创建一个副本,比如数组我们可以这样创建: arr.slice()
如果我们想给基本变量来一个引用复制,我们需要把该值封装到一个对象中,然后通过该对象的引用复制,实现该值的引用复制
第四章 强制类型转换
4.4 隐式强制类型转换
4.4.4 隐式强制类型转换为布尔值
下面的情况会发生布尔值隐式强制类型转换
ifforwhile、do while- 三元运算符
- 逻辑或
||和逻辑与&&左边的操作数
4.4.5 || 和 &&
JS 中的这两个符号有点小别致:
exp1 || exp2、exp1 && exp2
C、Java等对于上述结果为 true 或 false;但是 JS、Python 等对于上述结果却返回一个值。
在 JS 中,俩符号的作用大致如下:
a || b
大致相当于
a ? a : b
a && b
大致相当于
a ? a : b
JS 开发中常用设置默认值的方式:
foo(color){
this.color = color || 'red'
}
React 中条件渲染常用:
<div> {friend && friend.name + " " + friend.desc} </div>
- 当 friend 有值时,渲染后面的 html
- 当 friend 无值时,渲染 friend (JSX 插入语法规定,直接传入对象不显示)
&&也可以用于替代 if 语句
foo(){}
var a = 42
a && foo()
等价于
if(a) { foo() }
4.5 == 和 ===
常见的误区时:==检查值是否相等,===检查值和类型是否相等。
正确的解释:==允许在相等比较中进行强制类型转换,而 ===不允许
两者都会检查类型。
==比===只会慢一点,慢在类型转换的时间上。
== 算法:检查两个值是否相等,如果相等,就比较值是否相等.
注意:
NaN 不等于 NaN+0 = -0- 对象比较时,两个对象指向同一个值时即视为相等,不发生强制类型转换
==、===工作原理一样,只不过前者在比较两个不同类型的值时会发生隐式类型转换。
==如何转换类型?
string == number时 ,字符串会转成数字boolean == else类型时(没人会这么用),boolean 会转成数字 0 或 1- null == undefined 结果为 true