1、关于文档
2、语法,
3、关键字 保留字,
4、变量,
5、数据类型,
6、操作符,
7、语句,
8、函数
9、***JS第一道难关:类型转换(隐式转换)***
1、关于文档
-
<script type="text/javascript" src="###" async defer />
async 异步下载脚本。
defer 延迟加载脚本文件,表示等文档完全解析和显示之后再运行脚本。
-
doctype 文档类型
混杂模式(quirks mode,不推荐)、标准模式(standards mode)
2、语法
区分大小写、标识符、语句、注释、严格模式(use strict
)。
3、关键字、保留字
4、变量(var、let、const)
var message;
// 正确,但不推荐。 message 为 undefined。var message = "hi"; message = 100;
//正确,但不推荐var message = "hi"; var message = 100;
// 正确,但不推荐。第二个var
会自动被忽略var message = "hi", title = 100;
//正确,但不推荐function test () { msg: 'hi'; }
// 正确,但不推荐。此时msg
为全局变量。var a = b = c = d = 10;
// 正确,但不推荐
// var a = b = c = d = 10; 等同于
var d;
var c;
var b;
var a;
d = 10;
c = d;
b = c;
a = b;
var
的变量声明提升
console(x); // undefined
var x = 10; // 变量声明提升 + x = 10
console(x); // 10
x = 20; // x = 20
console(x); // 20
// 上面的代码会发生变量声明提升
// 变量声明提升后为
var x;
console.log(x);
x = 10;
console.log(x);
x = 20;
console.log(x);
5. 数据类型
Undefined, Null, Boolean, Number, String, Object, Symbol
typeof ...
"undefined","boolean","number","string","object", "function"
instanceof...
// 判断数据是否为某个对象的实例,返回布尔值
// 无法判断基础类型
Object.prototype.toString.call(**)
// 对于判断一个数据的数据类型我们开发时应该用 Object.prototype.toString.call(**)
// 判断结果更精确,范围更广:
// "[object Undefined]", "[object Null]",
// "[object Boolean]","[object Number]","[object String]",
// "[object Object]"
// 能够区分原生引用类型
// "[object Function]","[object Array]","[object Date]", "[object RegExp]"
// 不能判断自定义引用类型的构造类,即不能判断自定义对象类型
// 关于检测数据类型是否为 数组,使用Array.isArray()更加简便实用,推荐。
-
Undefined, Null
在JavaScript中,
Undefined
因Null
而生,Null
没有Undefined
重要。
// Undefined
var message;
console.log(message); //undefined
console.log(title); //报错
alert(message); //undefined
alert(title); // 报错
alert(typeof message); // undefined
alert(typeof title); // undefined
//Null 表示为空
// 在JS中 null既是对象,也不是对象,史称【薛定谔的对象】
Boolean
Boolean() | false | true |
---|---|---|
Undefined | undefined | n/a(指不适用) |
Boolean | false | true |
Number | 0、NaN | 非0,非NaN数字 |
String | ""(空字符串) | 非空字符串 |
Object | null | 非null对象 |
Number
// 1. -Infinity,Number.MIN_VALUE...-0, +0...Number.MAX_VALUE,Infinity
// 2. 0.1 + 0.2 != 0.3 (54位2进制,第一位符号位,2-12位指数,13-64有效数字)
// 3. parseInt(ag1, ag2) 第二个参数为ag1的进制(10进制:默认;8进制:第一位需0开头 严格模式报错;16进制:第一位需0x), Number()指定第二个参数无效。
// ES5之后,parseInt()默认按10进制解析,会自动解析8进制(即parseInt("070")解析为70),0x会按照16进制解析(即parseInt("0xF")将解析为15)
// 4. parseFloat(ag1, ag2)
// 5. Number() 推荐, Number(null) 0 , Number(undefined) NaN
parseInt("1.33.33.33"); // 1 脏数据
parseFloat("1.33.33.33"); // 1.33 脏数据
Number("1.33.33.33") // NaN 推荐
String
// 1. ES中的字符串不可变的。也就是说字符串一旦创建,它们的值就不会发生改变。
// 2. 转义序列(非打印字符)
\n, \r, \t, \b, \f(换行,回车,制表,推格,进纸)
\\, \', \", \xnn, \unnnn (斜杠 \,单引号 ', 双引号 ", 十六进制码nn表示一个字符, 十六进制码nnnn表示一个Unicode字符)
// 3. toString() 一般不传参,传递一个参数表示转换为对应参数的进制:2、8、10、16 的字符串 "230"
toString() | String() | |
---|---|---|
Undefined | 报错 | "undefined" |
Null | 报错 | "null" |
Boolean | 十进制表示数值的字符串 | 十进制表示数值的字符串 |
Number | 。。。 | 。。。 |
String | 。。。 | 。。。 |
Object | 。。。 | 。。。 |
Object
// Object类型 是所有它的实例对象的基础,
constructor(); // 构造函数,用于创建对象实例
hasOwnProperty(propName); // 检测某项属性是否位于对象实例上,非原型上
isPrototypeOf(obj); // 传入的obj 是否为当前对象的原型
propertyIsEmmerable(propName); // 检测传入的某项属性是否能够通过for-in枚举出来
toString()
toLocaleString()
valueOf()
Symbol
6. 操作符
一元,位,布尔 | 乘性,加性 | 相等,关系,条件 | 赋值,逗号
- 一元操作符:
+
-
++
--
// + - 置于 常量数据 之前,即为一元操作符。此时会对后接数据进行Number()转化。
+false; // 0
-false; // -0
// ++ -- 操作 变量,会对数字型变量进行自增或自减操作,非数字型则会执行Number()操作转换
// 不论x放在 ++ -- 前面或后面,x的值都会变换,而整体表达式的值则不同。
// x++ 整体表达式的值为 x自增前的值,++x整体表达式为x自增后的值。
var x = false;
var y = x++; // y===0, x===1
var z = ++x; // z===2; x===2
- 位操作符:
&
|
~
^
<<
>>
>>>
// 按位与: &, 二进制码 按与结合。0 + 0 = 0、0 + 1 = 0、1 + 1 = 1
// 按位或:|, 二进制码 按或结合。0 + 0 = 0、0 + 1 = 1、1 + 1 = 1
// 按位非:~, 二进制码 按非转换。~n (-n-1: 负值减一, 向下取整), ~~n (向下取整)
~~3.22; // 3, ~~ 正数向下取整
~~-3.22; // -3, ~~ 负数向上取整
// 按位异或: ^, 二进制码 按异或结合。 0 ^ 0 = 0、0 ^ 1 = 1、1 ^ 1 = 0
a = 1; b = 2;
a ^= b; b ^= a; a ^=b; // a, b值交换
// 左移: <<, n << m, n * ( 2 的 m 次方)
// 右移: >>, n >> m, n / ( 2 的 m 次方) 会向下取整
9 >> 2; // 2, 向下取整
-9 >> 2; // -3, 向下取整
// 无符号右移: >>>, n >>> m, n / ( 2 的 m 次方) 向下取整,n为负数表现杂乱
-3 >>> 1; // 2147483646
- 布尔操作符:
&&
||
!
// 与, 或, 非
// JS有短路操作
// 即&&,前值为真,进行下一个值计算,整个判断语句的值为第二个值。
// 前值为假,不进行下一个值计算,整个判断语句的值为第一个值;
// || 操作符 类似于 &&,逻辑相反。
// 即&&,前值为假,进行下一个值计算,整个判断语句的值为第二个值。
// 前值为真,不进行下一个值计算,整个判断语句的值为第一个值;
- 乘性操作符:
*
/
%
// % 求取余数。
5 % 2; // 1
- 加性操作符:
+
-
// 置于两个 常量数据 之间时,为加性操作符。
- 相等操作符:
==
===
!=
!==
// ==, != 会对前后对比数据进行数据类型转换。
// ===, !== 不会转换,必须数据类型相同,并且值相同。
undefined == null; // true
undefined === null; // false
- 关系操作符:
<
>
<=
>=
"23" < "3"; // true, 均为字符串,比较字符串字符编码
"23" < 3; // false, "23"转化为数字
"a" < 3; // false, "a"转换为NaN
- 条件操作符:
*** ? ** : **
- 赋值操作符:
=
*=
/=
%=
+=
-=
- 逗号操作符:
num = (1,2,3,4,5) // num = 5
运算符优先级
()
++
--
|
- 先
*
/
, 后+
-
>
<
>=
<=
==
!==
===
!==
- 先
&&
, 后||
- 赋值运算符
- 默认从左到右,除了赋值与三目运算符及指数运算
7. 语句
for(ag1; ag2; ag3) { ag4 }
for(var i = 0; i < count; i++){}
// 执行顺序
// ag1
// ag2 - ag4 - ag3
// ag2 - ag4 - ag3
// ag2 - ag4 - ag3
8. 函数
- 参数
arguments
-
ECMAScript
函数内部使用一个数组来接收的。所以在使用函数时,传递参数与否,传递几个参数,都是无所谓的。(没有传递的参数会默认为undefined
)
-
- 函数内部用来接收传入参数的数组可以用
arguments
对象访问。
- 函数内部用来接收传入参数的数组可以用
function example( name, age) {} // arguments[0]可以访问到运行example函数时接受到的第一个参数; // arguments[1]可以访问到运行example函数时接受到的第二个参数; // 并且可以使用 arguments[0] + age这种组合方式,操作 // arguments[0] 和 函数的第一个参数(即name)变化同步,但他们并不是访问的同一个地址的变量 // arguments[n]的方式最好只是读取,改写操作在非严格模式下可以,并且变化同步name、age。但在严格模式下非但不能改变name、age的值,并且会报错。
-
arguments.length
值为运行时的值,即其结果不由定义函数时参数个数决定,而是运行时传递的参数数量决定。
-
- 没有重载
- 由于前面参数由一个数值所承接,所有函数没有重载。
- 如果在
ECMAScript
中定义了两个名字相同的函数,则该名字只属于后定义的函数。
9. 类型转换(隐式转换)
类型转换,就是转换数据类型。
Undefined
Null
Boolean
Number
String
Object
Symbol
(一)显式数据类型转换(工作中推荐使用方式)
Boolean()
parseInt(ag1, ag2)
parseFloat(ag1, ag2)
Number()
toString(10)
String()
这个三点转换方式,在前面的数据类型小结里面已经有描述。
(二)隐式数据类型转换(利用操作符进行转换)
学习隐式转换是为了在工作中避免。
1. 一元:+
-
++
--
,会先隐式对数据进行Number()
操作,再进行++
--
操作。
-false; // -0
-true; // -1
-""; // -0
-"dafsdf"; // NaN
- {}; // NaN
-[-1]; // 1
-[-1, ]; // 1, IE为undefined
-[-1,-2]; // NaN
+null; // 0
++null; // 报错
var x = null; ++x; // 1
2. 位:&
|
~
^
<<
>>
>>>
,会先隐式对数据进行Number()
操作,再进行相应操作。
// 虽然会隐式对数据进行Number()操作,但是这里暂时认为的-NaN为0,而非NaN,背后真实的原因,我也不是很清楚
~undefined; // -1
~NaN; // -1
// << >> >>> 同上
3. 布尔:&&
||
!
,会对前后两个进行布尔转换。但最后的值不是布尔值,而是对应表达式的值(将布尔操作符时有描述)
左 && 右; // Boolean(左) && Boolean(右)。
1 && null; // null
!!1; // true
4. 乘性 *
/
%
, 乘性操作符,会隐式对前后数据进行Number()
,然后再执行操作
5. 加性 +
-
, 基本原则是对数据进行隐式Number()
操作,然后执行操作。但+
有些特殊。
// - 操作符,对前后两个数据进行隐式的Number()转换,然后执行操作
// + 操作符,对前后两个数据进行隐式的Number()转换,然后执行操作
// ******* 当+操作符,前后某个数据都是字符串时,执行拼接操作 *******
// ******* 当+操作符,前后某个数据都是对象时,执行拼接操作 *******
"22" + undefined; // "22undefined"
"22" + null; // "22null"
"22" + false; // "22false"
"22" + true; // "22true"
"22" + 33; // "2233"
"22" + {a: "asdf"}; // "22[object Object]"
"22" + [1,2,4]; // "221,2,4"
"22" + function A(){return "33";}; // '22function A(){return "33";}'
"22" + new Date(); // '22Thu Mar 23 2023 09:11:55 GMT+0800 (中国标准时间)'
6. 条件:*** ? ** : **
const val = 1; `value is ${val != '0'}` ? 'defined' : 'undefined'; // defined
7. 关系:>
<
>=
<=
总是转换为
Number
进行比较,若均为字符串,则比较字符的Unicode
码值。
// 特例
null >= 0; //true
null == 0; // false
8. 相等:==
===
!=
!==
JS的怪异之处:
A == B
≠>A >= B
。因为最初设计思想是a > b
、a >= b
一组,a==b
与其他运算符一组(如a != b
,a !== b
)。
关系运算符和相等运算符并不是一个类别的。
关系运算符,在设计上,总是尝试转为一个
Number
。相等运算符没有这方面的考量。
9. 赋值:=
- 复制变量值:复制值 与 复制引用指针。
- 传递参数: 值传递 与 引用传递。