JS(中) 第一部分 类型和语法

114 阅读4分钟

第一章 类型

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' //truetypeof 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 隐式强制类型转换为布尔值

下面的情况会发生布尔值隐式强制类型转换

  1. if
  2. for
  3. whiledo while
  4. 三元运算符
  5. 逻辑或 || 和逻辑与 && 左边的操作数

4.4.5 ||&&

JS 中的这两个符号有点小别致:

exp1 || exp2exp1 && exp2

C、Java等对于上述结果为 true 或 false;但是 JS、Python 等对于上述结果却返回一个

在 JS 中,俩符号的作用大致如下:

a || b
大致相当于
a ? a : ba && 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 == 和 ===

常见的误区时:==检查值是否相等,===检查值和类型是否相等。

正确的解释:==允许在相等比较中进行强制类型转换,而 ===不允许

两者都会检查类型。 =====只会慢一点,慢在类型转换的时间上。

== 算法:检查两个值是否相等,如果相等,就比较值是否相等.

注意

  1. NaN 不等于 NaN
  2. +0 = -0
  3. 对象比较时,两个对象指向同一个值时即视为相等,不发生强制类型转换

=====工作原理一样,只不过前者在比较两个不同类型的值时会发生隐式类型转换。

==如何转换类型?

  • string == number 时 ,字符串会转成数字
  • boolean == else类型时(没人会这么用),boolean 会转成数字 0 或 1
  • null == undefined 结果为 true