如题,读小红书时,说到的特殊字面量、特殊返回值、特殊属性等特殊情况太多了,我这脑子能记住就见鬼了。比如:
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;