javascript 中的零碎知识不要太多
如题,读小红书时,说到的特殊字面量、特殊返回值、特殊属性等特殊情况太多了,我这脑子能记住就见鬼了。比如:
javascript 包含以下几个部分
- 核心(ECMAScript)-- 核心功能
- 文档对象模型(DOM)-- 与网页内容交互
- 浏览器对象模型 (BOM)-- 与浏览器交互
script元素
包含8个属性,均是可选的,其中 :
-
async
和defer
两个属性在下载时异步,在执行时阻塞,defer
可延时执行,仅用在外部文件; -
type
默认值是text/javascript
,可以不写; - 为避免延迟和白屏,一般放在
</body>
上面;
<script>
function sayHi(){
console.log('hello world');
}
</script>
文档模式
HTML5以前有很多文档模式:标准模式和混杂模式;
HTML5以后,都用一种,且每个页面都要写,如下:
<!DOCTYPE html>
区分大小写
ECMAScript中的一切都区分大小写,不论是变量、函数名还是操作符;
即:变量test和变量Test是两个不同变量;
标识符
所谓标识符,就是变量、函数、属性或参数的名称;
规范:
- 首字符必须是字母、下划线(_)和美元符($);
- 其他字符可以是字母、下划线、美元符和数字,因为数字开头会引起歧义;
- 命名方式是驼峰大小写形式(不是强制的),如:
strName
、myCar
等; - 关键字、保留字、
true
、false
和null
不能作标识符;
变量声明
变量可以保存任何类型的数据,变量声明用:var 、let 和 const;
注意:
- var 声明的作用域;在函数内声明的var,在函数执行完后会被销毁;函数作用域;
- var 声明提升,所以多处声明会在作用域顶部自动合并;
- let 声明的范围是块作用域,且不会提升;
- let 在同作用域中不允许二次声明 会报: SyntaxError ;
- let 在全局声明的变量不会成为
window
对象的属性,var声明的会(window.name
); - const 声明时就要初始化变量,且不能修改;如果声明的是对象,那么修改对象的属性又是可以的;
- const 不能用来声明迭代变量(因为迭代变量会自增)
所以,声明风格:
- 不使用var ;用let 和 const 足够了;
- 优先使用 const ,let 次之;const强制保持变量不变,需要变量迭代时再使用let;
数据类型
ECMAScript 的数据类型很灵活,一种数据类型可以当作多种数据类型来使用,灵活反而容易糊涂;
- 六种简单数据类型:
Undefined
、Null
、Boolean
、Number
、String
和Symbol
(符号); - 一种复杂数据类型:
Object
(对象);
分解:
-
Undefined
类型只有一个值,就是特殊值:undefined
,使用var和let 声明了变量又没初始化时,就是这个值;没有声明的变量输出会报错,所以建议变量都要声明; -
Null
类型也只有一个值,就是特殊值:null
;null值表示一个空对象指针,所以typeof(null)
返回object
;undefined
由null
派生而来,所以(null == undefined)
返回true
; - undefined 和 null 都是假值,
Boolean(undefined)
和Boolean(null)
都是false
; -
Boolean
类型有两个字面值:true
和false
;任何数据类型的都能调用Boolean()
,除了上面的undefined
和null
外,''(空字符串)、0和NaN 调用Boolean()
时都为false
,其他都为true
; -
Number
类型表示整数和浮点数;3.125e7
是科学记数法;用二进制计算浮点数会不精确,导致 0.1+0.2不等于 0.3;有个特殊的数值是NaN
(意思是:Not a Number,即不是数值,例如:0/0 返回NaN
,而 5/0 返回Infinity
,即无穷),NaN
不等于自身,即(NaN == NaN)
返回false
; - 数值转换函数有三个:
Number()
、parseInt()
和parseFloat
;用法上有细微且明显的区别; -
String
类型表示 Unicode 字符序列,可用双引号("")、单引号(‘’)和反引号(``)标示;字符串一旦创建就不可变,要修改变量中的字符串值,须先销毁原始字符串,后将新值保存到该变量; - 字符串转换有两种方式:第一种是
toString()
方法 ,形如:abc.toString()
,几乎所有值都有toString()
方法,除了null
和undefined
;第二种是String()
函数,使用时,如果当前值有toString()
方法就调用该方法 ,如果没有,如null
和undefined
,则返回null
和undefined
。 -
symbol
符号,符号是原始值,且符号实例是唯一、不可变的。符号的用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险。这个类型不太好理解。 -
Object
类型,ECMAScript 中的对象是一组数据和功能的集合(很抽象);用new
操作符来创建;通过创建Object
类型的实例来创建对象,然后再给对象添加属性和方法,形如:let o= new Object();
; - Object 是派生其他对象的基类,Object类型的所有属性和方法在派生的对象上同样存在,这些属性和方法是:
constructor
、hasOwnProperty()
、isPrototypeOf()
、propertyIsEnumerable()
、toLocalString()
、toString()
和valueOf()
;因为Object
是所有对象的基类,所以任何对象都有这些属性和方法。
操作符
可用于操作数据值的操作符,包括数学操作符、位操作符、关系操作符和相等操作符;
操作符可用于各种值,包括:字符串、数值、布尔值甚至是对象;
在应用给对象时,操作符会调用valueOf()
和toString()
方法来取得可以计算的值;
分解:
- 一元操作符:前缀,++num 、--num;后缀,num++ 、num--;后缀在混合计算时的递增(或递减)会先计算后递增(或递减);
- 一元加和减:
+
还有拼接的意思;-
取负值;运算非数值时会先转换数据类型; - 位操作符:按位非(
~
)、按位与(&
)、按位或(|
)、按位异或(^
)、左移(<<
)和右移(>>
、>>>
); - 布尔运算符:逻辑非(
!
)、逻辑与(&&
)、逻辑或(||
),优先级!
>&&
>||
;有短路操作的情形; - 乘性操作符:乘法操作符(
*
)、除法操作符(/
)、取模操作符(%
)和指数操作符(**
); - 关系操作符:大于(
>
)、小于(<
)、小于等于(<=
)、大于等于(>=
)这些操作符返回布尔值; - 相等操作符:等于(
==
)、不等于(!=
)、全等(===
)和不全等(!==
); - 条件操作符:(
?:
),如:let max = (num1 > num2) ? num1 : num2;
; - 赋值操作符:赋值号
=
、+=
、-=
、*=
、/=
、%=
等等; - 逗号操作符:
let num1 = 1, num2 = 2, num3 = 3;
;
操作符的优先级
运算优先级从上往下,其中逻辑运算符
!
的优先级更高,且&&
优先级高于||
:
- 1,
()
优先级最高; - 2,一元运算符:
++
,--
,!
; - 3,算数运算符:先
*
,/
,%
,后+
,-
; - 4,关系运算符:
>
,<
,>=
,<=
; - 5,相等运算符:
==
,===
,!=
,!==
; - 6,逻辑运算符:先
&&
,后||
; - 7,赋值运算符:
=
;
if 语句: if -- else if -- else
只有一行代码也要用语句块;
if (i > 25) {
console.log("Greater than 25.");
} else if (i < 0) {
console.log("Less than 0.");
} else {
console.log("Between 0 and 25, inclusive.");
}
do while 语句
是一种后测试循环语句(至少执行一次),即循环体中的代码执行后才会对退出条件进行求值;
let i = 0;
do{
i+=2;
}while(i<10)
while 语句
是先测试循环语句,即先检测退出条件,再执行循环内的代码;
let i = 0;
while(i<10){
i+=2;
}
for 语句
先测试语句,增加了进入循环之前的初始化代码,和循环执行后要执行的表达式;
const count = 10;
for(let i=0; i<count; i++){
console.log(i);
}
无法通过while实现的逻辑,也无法使用for实现;
for - in
用于枚举对象中的非符号键属性;
for(const propName in window){
console.log(propName); // 多达224个
}
- ECMAScript 中对象的属性是无序的,所有可枚举的属性都返回一次,但顺序因浏览器而异;
- 循环要迭代的变量是
null
或undefined
,则不执行循环体;
for - of
用于遍历可迭代对象的元素;
for (const el of [1,2,3,4]){
console.log(el); // 1,2,3,4
}
上面例子,显示当前数组所有元素,for-of循环会按照可迭代对象的 next()
方法产生值的顺序迭代元素。
break 和 continue 语句
break
立即退出循环,强制执行循环后的下一条语句;
continue
立即退出循环,但会再次从循环顶部开始执行;
先看break实例
let num = 0;
for (let i = 1; i < 10; i++) {
if (i % 5 == 0) {
break;
}
num++
}
console.log(num); // 4
再看continue实例
let num = 0;
for (let i = 1; i < 10; i++) {
if (i % 5 == 0) {
continue;
}
num++
}
console.log(num); // 8
switch语句
case 控制分支条件,break跳出switch语句;如果没有break,代码会继续匹配下一个条件;default 关键字是在条件都不满足时指定默认执行的语句。
swicth(i){
case 25:
console.log('25');
break;
case 35:
console.log('35');
break;
case 45:
console.log('45');
break;
defalut:
cosole.log('other');
}
注意
- 最好给每个条件后加 break语句,否则会连续匹配多个条件,除非确实需要这样;
- switch 条件的值,可以不是数值,可以是所有数据类型,如:字符串甚至对象;
- switch 语句在比较条件时使用全等操作符,因此不会强制转换数据类型;
函数
可以封装语句,可在任何地方、任何时间执行;
function sayHi(name,msg){
console.log('hello' + name + ',' + msg);
}
sayHi('Jack','How r u today?')
function sum(num1,num2){
return num1 + num2;
}
const res = sum(5,10); // 15
注意
- 碰到
return
语句,函数会立即停止执行并退出,因此return
语句后面的代码不会执行; - 最佳实践是要么有返回值,要么没有返回值,在某个条件下返回值的函数会带来麻烦;
- 不返回值的函数,实际上会返回特殊值: undefined;