# JavaScript基础笔记01
# 1.这是JavaScript
HTML描述页面的结构,CSS展现页面的样式,JS在页面中描述行为、控制交互。
JavaScript里没有Java,就像老婆饼里没有老婆。
JavaScript是解释型语言,既是前端语言,又是后端语言,当它运行在浏览器中时是前端语言,后端语言运行在服务器中也称为服务端语言,NodeJS可以让JS运行在服务端。
JavaScript基础由三部分组成,ECMAScript是语法,DOM和BOM是浏览器提供的API
- ECMAScript: JavaScript的语法标准,至少要学习到ES6,它规定了JS最基础的语句、变量、函数、运算等等。
- DOM: 文档对象模型(Document Object Model),JS操控网页元素的API。
- BOM: 浏览器对象模型(Browser Object Model),JS操控浏览器的API。
# 2.使用JS
行内: 写在标签属性中。
<input type="button" value="点我" href="javascript:;" onclick="alert('你好')" />
1内嵌: 写在标签中。
<script type=”text/javascript”> alert('你好'); </script>
1
2
3外链: 在标签的src属性中写上js文件的链接。
<script type="text/javascript" src="main.js"></script>
# 3.执行顺序
浏览器默认从上至下解析网页,JS的加载默认会阻塞网页的解析,通过JS操控网页元素,需待网页解析完后执行、写在html的最后或写在对应元素后,否则就可能因为DOM树不完整,要操控的对象还未被加载而报出undefined错误。
<!-- 不等待后续网页的解析,到此就加载JS并执行 -->
<script src="main.js"></script>
<!-- 网页的解析与JS的加载异步,但JS在网页解析完后执行 -->
<script defer src="main.js"></script>
<!-- 网页的解析与JS的加载异步,JS加载完后立即执行 -->
<script async src="main.js"></script>
2
3
4
5
6
//待网页解析完、网页中所有资源(图片、css)都加载完毕,执行其中的代码
window.onload = function () {
//js代码
alert('你好');
}
2
3
4
5
# 4.输出语句
console.log(): 在控制台输出内容
console.log('日志'); //普通打印 console.warn('警告'); //警告打印 console.error('出错了'); //错误打印
1
2
3alert(): 警告对话框
confirm(): 确认对话框,返回true或false
var a = confirm('确认吗'); if(a){ alert('你确认了') }else{ alert('未确认') }
1
2
3
4
5
6prompt(): 输入对话框,返回输入内容或空字符串,点取消返回NULL
var a = prompt('输入内容'); if(a){ alert('你输入了:'+ a) }else if(a==''){ alert('你没输入任何东西') }else{ alert('取消') }
1
2
3
4
5
6
7
8# 5.常量、变量、标识符
数字常量、字符串常量、布尔常量
console.log(123); //123是数字 console.log('123'); //'123'是字符串,''空字符串 console.log('你好'); //''包裹起来的都是字符串 if(true){ //true、false布尔常量 console.log('true'); }
1
2
3
4
5
6
自定义常量const
const a = '123'; //定义a为常量
a = '321'; //不允许修改常量
const a = '321'; //不允许重新声明
2
3
定义变量var、let(ES6)
var a = '123';
let b = 321;
//重新定义
var a = '321'; //var允许重新定义
let b = 123; //let不允许重新定义
//不允许var和let之间重新定义
var c = 123;
let c = 123;
2
3
4
5
6
7
8
var可以在声明前使用,值为undefined,而let必须先声明再使用。
var是函数作用域,let是块作用域。
标识符(一切可自主命名的,如变量名、函数名)命名规则:
区分大小写
只能由字母(A-Z、a-z)、数字(0-9)、下划线(_)、美元符( $ )组成
不能以数字开头、不允许出现空格
不能出现中划线 ---
# 6.数据类型
JavaScript是弱类型语言(动态语言),无需声明变量的类型,在程序运行过程中,会根据等号右边的值自动确定类型。
var a = 123; console.log(typeof a);//输出number a = '123'//强制将变量a数据类型转换为字符串 console.log(typeof a);//输出string a = Number(a);//强制将字符串'123'转换为数字123 console.log(a);//输出123
1
2
3
4
5
6JS中数据类型分为基本数据类型和引用数据类型
基本数据类型(值类型): String字符串、Number数值、BigInt(ES6)大型数值、Boolean布尔值、Null空值、Undefined未定义、Symbol(ES6)。
引用数据类型(引用类型):Object 对象(除了基本数据类型之外,都可称之为Object类型)。
基本数据类型传数值,引用数据类型传地址。
var a = 23; var b = a;//将a的值23传给b a++; console.log(a); //24 console.log(b); //23,改变a的值不影响b
1
2
3
4
5var a = new Object();//a、b都是引用数据类型 b.name = '123'; var b = a;//传的是a的地址,a和b是同一个东西 a.name = '321'; console.log(a.name); //321 console.log(b.name); //321,修改a对象的属性也会修改b
1
2
3
4
5
6JS中,所有的变量都保存在栈内存中的。
基本数据类型直接保存在栈内存中。值与值之间独立存在。
对象Object保存在堆内存中,创建一个新的对象,在堆内存中开辟一个新的空间,变量在栈内存中保存了对象的内存地址(对象的引用)。
# 7.String字符串
字符串是双引号和单引号中的文本,不同类型引号可以嵌套使用。
var a = '123'; console.log(a);//123 var b = '1"2"3'; console.log(b);//1"2"3 var c = '12 3'; console.log(c);//12 3不忽略连续多个空格
1
2
3
4
5
6加入字符串进行拼接,可以被同化为字符串
console.log(typeof(123+''));//string
1
转义字符: **
双引号: ",单引号 '
\ 表示\
\r 回车,\n 换行
\t 缩进
\b 空格
字符的数量就是字符串的长度,获取字符串的长度
.length:
var a = "abc"; console.log(a.length);//3 a = "你好"; console.log(a.length);//2
1
2
3
4使用 + 进行字符串拼接:
var a = "你好"+"世界";
console.log(a);//你好世界
a = "你好"+ 1;
console.log(a);//你好世界1
a = "你好"+ null;
console.log(a);//你好null
a = "你好"+ true;
console.log(a);//你好true
2
3
4
5
6
7
8
ES6新增模板字符串:,可以使用${变量名}将其嵌入字符串,使用时需要反引号
包裹。
var a = 2022;
var b = '2023';
console.log(`去年是${a},今年是${b}`); //去年是2022,今年是2023,注意使用反引号
2
3
模板字符串中可以换行,不忽略连续的多个空格,保留原有格式。
可以调用函数:
function getHtml() {
return `<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>`;
}
console.log(`1${getHtml()}2`);
/*
1<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>2
*/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
可以嵌套使用,进行运算:
var a = 1;
var b = 2;
console.log(`${a+`${b}`}`);//12
console.log(`${a+b}`);//3
2
3
4
# 8.Number数值型
JS中整数和浮点数等所有的数值都是Number类型。
var a = 1;
var b = 1.2;
console.log(typeof a);//number
console.log(typeof b);//number
2
3
4
数值范围:
console.log(Number.MAX_VALUE);//1.7976931348623157e+308
console.log(Number.MIN_VALUE);//5e-324
2
数值变量超过了最大值,则会返回Infinity,Infinity也是一种数值,代表无穷大。
var a = Number.MAX_VALUE;
var b = Number.MIN_VALUE;
console.log(a*2);//Infinity
console.log(b/2);//0
console.log(a*(-2));//-Infinity
console.log(typeof Infinity);//number
2
3
4
5
6
NaN是一个特殊的数字,表示不是数值(Not a Number),当运算不出数值时就会返回NaN。
console.log(typeof NaN);//number
console.log('abc' / 2);//NaN
console.log('a' * '2');//NaN
2
3
Undefined和任何数值计算的结果均为NaN。NaN与任何值都不相等,包括NaN本身。
console.log(undefined + 1);//NaN
console.log(null + 1);//1
console.log(NaN==NaN);//false
2
3
隐式转换,当有字符串介入的运算,且字符串可被转换为数值,除了+表示字符串连接,其余都会自动将字符串转为数值后进行运算。
console.log('1' + '2');//12
console.log('1' * '2');//2
console.log('1' / 2);//0.5
console.log('1' - 2);//-1
console.log('1' + '2' * '3');//16
2
3
4
5
浮点数的运算精度并不足够准确,当需要进行高精度运算时,最好引入可靠的数学库。
var a = 0.1 + 0.2;
console.log(a); //0.30000000000000004
2
# 9.Null与Undefined
undefined实际上是由null衍生出来的。
undefined表示未定义,应该有值但还未赋值,连null这个值都没有赋予给它。 null代表空值,本身是一个具体的值或空引用。
null和undefined值上相等,但类型不一样。 null是引用类型Object,代表空对象,存的地址为空,而undefined的类型是undefined,代表未定义的值。
console.log(null == undefined);//true
console.log(null === undefined);//false
console.log(typeof null);//object
console.log(typeof undefined);//undefined
2
3
4
5
null转为数值是0,undefined转为数值是NaN。 任何值和null运算,null可看做0。任何数据类型和undefined运算,结果都是NaN。
console.log(Number(null));//0
console.log(Number(undefined));//NaN
console.log(null+1);//1
console.log(undefined+1);//NaN
2
3
4
5
出现undefined的情况:
变量被声明了,但是没有被赋值
变量未声明(未定义)时
调用函数时,未传参
函数无返回值时
访问一个对象中没有的属性
console.log(a);//undefined
var a;
console.log(a);//undefined
function Fun(item) {
console.log(item);
}
console.log(Fun());//undefined
Fun();//undefined
2
3
4
5
6
7
8
9
出现null的情况:
- 访问一个不存在的dom节点
- 作为对象原型链的终点出现
# 10.数据类型转换
变量的数据类型转换:将一种数据类型转换为另外一种数据类型。(通常在基本数据类型中互相转换)
显式类型转换
toString()
转换为字符串String()
强制转换为字符串Number()
转为数值,保留小数parseInt()
字符串转整数,直接舍去小数部分parseFloat()
在parseInt()的基础上可以获得小数部分Boolean()
隐式类型转换
isNaN()
自增/自减 正号/负号 加号(字符串拼接) 其它数值运算符 逻辑运算符:会先非布尔值转换为布尔值,再运算 关系运算符:运算结果都是布尔值
# 10.1.转为字符串
toString():
var a = 123;
console.log(a.toString());//"123"
a = true;
console.log(a.toString());//"true"
a = [1, 2, 3];
console.log(a.toString());//"1,2,3"
a = { name: 'qx', age: 18 };
console.log(a.toString());//"[object Object]"
2
3
4
5
6
7
8
null和undefined这没有toString()方法,调用会报错
var a = null;
console.log(a.toString());//Cannot read properties of null (reading 'toString')
a = undefined;
console.log(a.toString());//Cannot read properties of null (reading 'toString')
2
3
4
Number类型的变量,在调用toString()时,可以传入一个整数,把数字转换为指定的进制,默认转换为10进制。
var a = 8;
a = a.toString(2); //转换为二进制
console.log(a); //"1000"
console.log(typeof a);//string
2
3
4
数字不允许直接调用toString()
1.
var s = toString();//不允许,会把.看成小数点,小数点后面出现非数字是不允许的
1..toString()//允许
(1).toString()//允许
2
3
4
使用String()
强制转换为字符串。
对于非null和undefined的数据类型而言,实际上就是调用toString()。
对于null和undefined,直接转换为”null”和”undefined”。
var a = 123;
console.log(String(a));//"123"
a = null;
console.log(String(a));//"null"
a = undefined;
console.log(String(a));//"undefined"
2
3
4
5
6
字符串拼接,隐式转换:
var a = 123;
console.log(a+'');//"123"
2
# 10.2.转为数值
Number()转为数值类型
- 字符串转数字 字符串中是纯数字,直接将其转换为数字 空字符串或全是空格,转换为0 字符串中包含了非数字的内容,转为NaN
- 布尔值转数字:true —> 1,false —> 0
- null —> 0,undefined —> NaN
加上正负号隐式转换。规则和Number()一样,但是改变正负性,0也会带上负号:
var a = '123';
console.log(+a); //123
console.log(-a); //-123
console.log(typeof +a);//number
a = null
console.log(+a); // 0
console.log(-a); // -0
2
3
4
5
6
7
parseInt()
字符串转整数,布尔、null等非字符串、非数值类型都转为NaN,逐个字符转,碰见非数字字符就停止,没有提取到数值,就返回NaN。
parseInt('123abc'); //123
parseInt('abc123'); //NaN
parseInt(''); //NaN
parseInt(' '); //NaN
parseInt(null); //NaN
parseInt(undefined); //NaN
parseInt(true); //NaN
2
3
4
5
6
7
parseInt()会自动截断、舍弃小数,而Number()不会。
var a = parseInt('5.1') + parseInt(5.9);
console.log(a);//10
a = Number('5.1') + Number(5.9);
console.log(a);//11
a = parseInt(5.1 + 5.9);
console.log(a);//11
2
3
4
5
6
parseInt()可以多带一个进制参数,把数值看成对应进制,再转成10进制返回。无论parseInt()里面的进制参数是多少,最终的转换结果是十进制。
var a = parseInt('101', 2);
console.log(a);//5 二进制101就是十进制的5
a = parseInt('3', 2);
console.log(a);//二进制中没有3,所以转换失败返回NaN
2
3
4
5
parseFloat()
字符串转小数,与parseInt()相似。
parseFloat('123.321abc'); //123.321
parseFloat('12.1a3.321'); //12.1
parseFloat('12.13.321'); //12.13
2
3
# 10.3.转为Boolean
任何数据类型都可以转为 Boolean 布尔型。
- 数值型: 0 和 NaN的转为 false,其它都是 true
- 字符串: 空串转为 false,其它都是 true。全是空格的字符串,转换结果也是 true。”0”也是 true。
- null 和 undefined 都转为 false
- 引用数据类型都转为 true,因为地址永不为空或0。空数组[]和空对象{},也是 true
var a;
Boolean(a);//false,a未赋值,undefined
a = '';
Boolean(a);//false
a = [];
Boolean(a);//true
a = {};
Boolean(a);//true
2
3
4
5
6
7
8
使用!!或!显式转换为 Boolean 类型:
var a = 1;
a = !a
console.log(a);//false
a = !!2;
console.log(a);//true
2
3
4
5
isNaN()
判断是否是非数值类型,任何不能直接转为数值类型的数据类型都可以让这个函数返回true
isNaN('123');//可以转为123,返回false
isNaN(null);//转为0,false
isNaN('123abc');//true
isNaN(undefined);//true
2
3
4
# 11.运算符和运算
各种编程语言的运算符功能都大差不差,只介绍JS中比较特殊的运算或特例。
浮点数值的最高精度是 17 位小数,会有丢失精度的风险,不要直接判断两个浮点数是否相等
Boolean + 数字 = 数字,true按1来算,false按0。 null + 数字 = 0 + 数字 undefined + 数字 = NaN 任何值和 NaN 运算的结果都是 NaN 任何非数值类型进行除加法以外的运算-、*、/、%时,都会自动用Number()转成数值类型再参与运算
true + 1; //2
null + 1; //1
var a = 2 - '1'; //1
var a = '2'/'1'; //2
2
3
4
非布尔值进行与或运算(&&、||)时,会先将其转换为布尔值,然后再运算,但返回结果是原值。
与运算 &&的返回结果:从左到右依次运行语句,找到第一个为 false 的值,返回原值,不再往后执行。如果所有的值都为 true,则返回最后一个值。
var a = '' && 123;
console.log(a);//'',空字符串转为布尔型为false,只执行第一条语句并返回原值
var a = [] && 0;
console.log(a);//0,[]转为布尔型为true,直接返回第二个语句的值
var a = "0" && 0 && 1;
console.log(a);//0
2
3
4
5
6
或运算 ||的返回结果:从左到右依次运行语句,找到第一个为 true 的值,返回原值,不再往后执行。如果所有的值都为 false,则返回最后一个值。
var a = '' || null;
console.log(a);//null
var a = 0 || [];
console.log(a);//[]
var a = "0" || 0 || 1;
console.log(a);//"0"
2
3
4
5
6
比较运算符 >、<、==、!= 等,得到的结果都是布尔值:要么是 true,要么是 false,非数值进行比较,会将其转换为数值类型。
特殊情况:如果参与比较的都是字符串,则不会将其转换为数字进行比较,比较的是字符串的Unicode编码。 比较字符编码时,从左到右逐位进行比较,一样大则继续比较下一位,直到比较出大小。
console.log('100' > 9 );//true,将'100'转为数值100进行比较
console.log('100' > '9' );//false,两个字符串逐位比较,9比1大,返回false
2
== 、=== ==
进行比较时,会做隐式转换,将不同的数据类型,转为相同类型进行比较,而全等符号===不会进行转换,不同类型的数据比较一定是false。
console.log('1' == 1); //true
console.log('1' === 1); //false
console.log(1 == true); //true
console.log(1 === true); //false
console.log(undefined == null); //true
console.log('1a' > 1); // false。'1a'转成NaN
//NaN不和任何值相等,包括它本身
console.log(NaN == NaN); //false
console.log(NaN === NaN); //false
2
3
4
5
6
7
8
9
10
11
12
null与数字进行比较有一个Bug,不必在意,当特性就行:
console.log(null < 0); //false
console.log(null == 0); //false
console.log(null > 0); //false
console.log(null <= 0); //true。这是一个bug
console.log(null >= 0); //true。同上
2
3
4
5
6
日期大小比较
var date1 = new Date(2023, 3, 28)
console.log(date1);//Fri Sep 08 2023 00:00:00 GMT+0800 (中国标准时间)
var date2 = '2023-03-27';
var date3 = '2023/03/29';
console.log(date1 > date2);//false,date1和date2字符串格式很不相同,比较无意义
console.log(date3 > date2);//true,格式基本相同,分割位置一样,字符串逐位比较大小
2
3
4
5
6
# 12.if和switch
这部分各大语言也大差不差,只记录值得注意的点。
case的判断逻辑是===,不是==
switch中的default无论放到什么位置,都会等到所有case都不匹配再执行,但一般放在最后
当case或default匹配到一个值后,会执行后续所有的case,除非遇到break或执行到switch的末尾。
# 13.循环
这部分各大语言也大差不差,只记录值得注意的点。
break会立即终止离它最近的循环语句,continue跳过当次循环,继续下一次循环。
可以为循环语句创建一个label,来标识当前的循环。使用break、continue语句时,break label将会结束指定的循环,而不是最近的。
one: for (var i = 0; i < 100; i++) {
for (let j = 0; j < 100; j++) {
if(i>j) {
break one;
}
}
}
console.log(i);//1
2
3
4
5
6
7
8