目录
1、JS简介
1.1、JavaScript的运行过程
1.2、了解浏览器的开发人员工具
2、JavaScript的书写形式
2.1、行内式
2.2、内嵌式
2.3、外部式
3、JavaScript的输入输出函数
4、JavaScript语法
4.1、变量声明
4.1.1、动态类型
4.2、基本数据类型
4.2.1、数字类型
4.2.2、字符串类型
4.2.3、布尔类型
4.2.4、undefined类型和null类型
4.3、运算符
4.3.1、+和-运算符
4.3.2、==和!=运算符与===和!==运算符
4.4、条件语句(只了解switch)
5、数组
5.1、数组的创建
5.2、获取数组元素
5.3、数组的的越界访问
5.4、插入、修改、删除元素
5.4.1、插入元素
5.4.2、修改元素
5.4.3、删除元素
6、函数
7、作用域
8、对象
1、JS简介
JavaScript简称JS,JS是一种动态类型,弱类型的脚本语言,通过解释器运行,主要运行在客户端和浏览器上。JavaScript可以进行网页开发,服务器的开发 、手机app的开发等.....
JS主要在前端中可以完成用户在网页和Web服务器的交互,HTML描述了网页的结构(框架),CSS描述了网页的样式(美化),JavaScript则是让网页动起来了。
1.1、JavaScript的运行过程
我们编写的JavaScript代码是保存在文件中的,也就是存储在硬盘(外存上);双击.html文件浏览器(应用程序)就会读取文件,把文件内容加载到内存中(数据流向:硬盘—>内存);浏览器会解析用户编写的代码,把代码翻译成二进制的,能让计算机识别的指令(解释器的工作);得到的二进制指令会被CPU加载并执行(数据流向:内存—>CPU)。
浏览器分成渲染引擎+JS引擎;渲染引擎的作用就是解析html+CSS ,俗称"内核";JS引擎的作用也就是JS解释器,典型的就是Chrome中内置的V8引擎;JS引擎逐行读取JS解释器,然后解析成二进制指令再执行。
1.2、了解浏览器的开发人员工具
这里我们以哔站的页面为例进行演示。
我们使用F12打开这个工具。出现下面的页面,先从第一个了解。
第一个按钮(元素的选择),点击之后,就可以用鼠标点击页面上的任何地方,点击的元素就会在代码的相应部分显示。
第二个按钮,点击之后,可以显示当前的页面在手机/平板上显示的样式了。
元素模块,可以显示当前页面的所有代码(html+CSS+JS),我们查看的哔站上的页面很多,我只想查看页面某一部分的代码这里个时候就可以搭配元素的选择按钮,点击页面上的某个部分,就会显示这个部分所有的代码。然后可以在当前显示的代码中进行修改、删除等的操作,调试样式,这里调试的样式,在页面刷新之后,不会保存。
控制台模块,可以打印js代码的输出信息,比如我们的代码出错了,我们可以点击控制台,他就会显示错误信息。与我们的idea一样,可以很快的知道我们哪一行的js代码出错。点击错误信息就可以打开源代码模块,将代码中出错的位置标注出来。
控制台上也可以直接执行JS的代码,我们将alert方法写在控制台上,按回车之后,就会在当前页面显示效果。
源端码模块,这里可以调试js代码,调试的方式,在JS书写方式的内嵌式中有说到用源代码模块调试JS代码的操作。
网络模块,这是一个抓包作用,可以查看网络请求,当我们在访问一个页面的时候,显示加载这个页面调用的资源、访问花费的时间等等。
2、JavaScript的书写形式
下面演示的三种JavaScript书写方式,我们都使用alert()函数来弹出一个对话警示框,来显示alert函数中输出的内容,我们在JS中字符串常量可以使用单引号表示,也可以使用双引号表示。HTML中更推荐使用单引号,JS中推荐使用双引号。
2.1、行内式
行内式的写法就是直接将嵌入到html标签内部。这里是通过单击事件将alert方法写在html元素中。
<body>
<input type="button" value="点我一下" onclick="alert('你好')">
</body>
上面说到HTML中建议使用单引号,因为我们在html中使用行内式写JS代码的时候,就像上述的在alert函数中写字符串的时候,如果使用双引号那么,那么这里的双引号就会和之前的双引号匹配,在vscode中这样写的时候编译器会报错。
2.2、内嵌式
写在script标签内部,如果不写在script标签中,在页面中显示的时候,浏览器并不知道alret是JS的代码,他会将alret作为普通文本显示。
<script >
alert("你好世界!");
</script>
🌈 注意:
在使用内嵌式写法的时候,script标签可以写在body标签中也可以写在head标签中,但是不建议写在head标签中,更建议写在body标签中,并且写在body结束标签的前面(写在</body>之前一行)。下面我们通过一段代码演示。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js demo</title>
<script>
// alert中表示的意思是从当前的html文档中,根据id获取元素
alert(document.getElementById("one").value);
</script>
</head>
<body>
<input id="one" type="button" value="点我一下" onclick="console.log('你好');">
</body>
</html>
可以看到的是alert方法并没有让页面弹出对话警示窗口,并且在控制台中可以看见报错了,提示无法获取到空的元素内容。原因就是我们将script写在了head中,所以当代码执行到这里的时候,后面的body中的代码还没有执行,所以这里的script中的内容获取不到想要的内容。我们可以通过调试的方式看一下。但我们打开开发者工具后,点击源代码,对出现问题的代码打断点并按ctrl+R,在监视中填入你想知道的信息,然后敲回车。
2.3、外部式
写到单独的.js文件中,使用下面的代码将这个.js文件引入到html中来。
<script src="文件名.js"></script>
引入.js文件的代码可以写在head标签内,因为这里的js文件是一个工具js,有很多的html代码都有可能引用这个js文件,这个引入的js文件中的内容,并不会有操作当前操作页面的信息,所以不会产生上面说到的问题。引入js文件更建议写在head标签中,如果在body中的某个标签需要使用工具js,这个时候就需要先将这个工具js,先加载完,所以写在head标签内,在代码开始执行的时候就将这个工具js加载完了。
HTML文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js demo2</title>
<script src="tools.js"></script>
</head>
<body>
</body>
</html>
js文件
alert("你好 世界!!!")
3、JavaScript的输入输出函数
🍂输入
prompt("字符串提示信息");
这个prompt函数中写的字符串需要使用一个变量接收。当我们在弹出的提示框中输入数字的时候,这个时候接收到的数字是一个字符串类型的数据。
var num = prompt("请输入一个数字");
console.log(num+10);
🍂输出
使用alert函数,弹出一个警示对话框,输出结果。
alert("弹出的内容");
使用console.log函数,向控制台输出日志(供程序员看)
console.log("日志信息");
console是一个JS中的"对象";.表示取对象中的某个属性或者方法。
🌈示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js demo</title>
</head>
<body>
<script>
var name = prompt("请输入你的名字");
console.log("用户输入的信息 ->"+name);
alert("结束");
</script>
</body>
</html>
4、JavaScript语法
4.1、变量声明
🌈语法格式
//第一种定义方式
var 变量名 = 值;
//第二种定义方式
let 变量名 = 值;
使用var和let这两种方式定义变量他们的作用域是不同的,var适合定义全局的变量,let适合定义局部的变量;还有一个是var和let的诞生时机不同,var诞生的更早,而let比较晚。在定义变量的时候,我们还是更建议使用var的,因为有的用户使用的电脑是win7、winxp等等的系统,由于let诞生的比较晚,使用let不能识别。
🌈示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js demo</title>
</head>
<body>
<script>
var name = prompt("请输入你的名字");
var age = prompt("请输入你的年龄");
var sex = prompt("请输入性别");
alert("姓名:"+name+"\n年龄:"+age+"\n性别"+age);
</script>
</body>
</html>
4.1.1、动态类型
JS是一个弱类型的语言,像Java和C++都是强类型的语言,Java和C++是在代码编写的时候,就确定了变量的类型,但是JS的变量类型是在程序运行过程中才能确定的(运行到 = 语句才会确定类型),随着程序的运行,变量的类型可能发生改变。
🌈示例
1、当定义的两个变量的值都是字符串的,这个时候var类型的变量就会在执行到 = 语句的时候就会确定这个变量是一个字符串类型的。
<body>
<script>
var num = "5";
var num2 = "5";
alert(num+num2)
</script>
</body>
2、当定义的一个var类型的变量开始赋值为int类型的值,但是在中途对这个变量赋值一个字符串类型的值,输出的结果就会是字符串,此时定义的var类型的变量为字符串类型的变量。
<script>
var num = 5;
num = "你好世界";
alert(num);
</script>
4.2、基本数据类型
JS中内置的几种类型
- number:数字,不区分整数和小数
- boolean:true真,false假
- string:字符串类型
- undefined:只是唯一的值undefined。表示未定义的值
- null:只有唯一的值null,表示空值。
4.2.1、数字类型
JS中不区分整数和浮点数,统一都使用number来表示。与Java一样,支持用二进制、八进制、十六进制表示数字。
var a = 07; //八进制整数,以0开头
var b = 0xa; //十六进制的整数,以0x开头
var c = 0b10; //二进制整数,以0b开头
✨注意:
- 一个八进制的数字对应三个二进制数字
- 一个十六进制的数字对应四个二进制数字(两个十六进制的数字就是一个字节)
🍂特数的数字值
- infinity:无穷大,大于任何数字,表示数字已经超过了JS能表示的范围
- -infinity:负无穷大,小于任何数字,表示数字已经超过了JS能表示的范围
- NaN:表示当前的结果不是一个数字。
<script>
var max = Number.MAX_VALUE;
// 得到 Infinity
console.log(max * 2);
// 得到 -Infinity
console.log(-max * 2);
// 得到 NaN
console.log('hehe' - 10);
</script>
注意:
- 负无穷大和无穷小不是一回事,无穷小值无线趋近于0,值为1/infinity
- 'haha'+10得到的不是NaN,而是'hehe10',会把数字隐式转换成字符串,在进行字符串的拼接
4.2.2、字符串类型
字符串字面值需要使用引号引起来,单引号和双引号都可以,JS中的字符串和Java一样,可以使用+运算符进行不同的字符串拼接操作,可以使用变量名.length求得字符串的长度。
1️⃣求字符串的长度
var a = 'hehe';
console.log(a.length);
var b = '哈哈';
console.log(b.length);
2️⃣字符串的拼接
数字和字符串可以拼接
var c = "my score is ";
var d = 100;
console.log(c + d);
当一个数字以字符串的形式与另一个数字相加,表示的意思就是字符串的拼接。
console.log(100 + 100);
console.log('100' + 100);
4.2.3、布尔类型
JS中的布尔类型和C语言类似,true和非0表示为真,false和0表示为假,JS的布尔类型支持与数字运算,运算时,true表示1,false表示0,本质上也是隐式类型转换,Java中使用数字不能表示真假,也不能让布尔类型的值和其他类型的值进行运算。
console.log(true+1);
console.log(false+1);
console.log(true+false);
4.2.4、undefined类型和null类型
如果一个变量没有被初始化过,那这个变量就具有唯一的值undefined,这个值是undefined类型,这个操作就是把其他语言中不合法的操作在JS中变得合法了,我们知道在Java中一个变量如果没有赋值,就打印结果,编译器是会报错的。
var a;
// 直接输出这个未被初始化的变量,显示的结果是一个undefined,是undefined类型的数据
console.log(a);
// 这个未被赋值的变量和字符串进行拼接 undefined10
console.log(a+"10");
// 这个现实的结果为NaN,因为undefined是undefined类型的数据,和10相加出现的结果不是一个数字
console.log(a+10);
null表示当前的变量值是一个"空值",实际上给创建的变量已经初始化了,初始化的值为null。null和undefined都表示取值非法的情况,但是侧重点不同,null表示当前的值为空(相当于一个空的盒子),undefined表示当前的变量未定义(相当于连盒子都没有)。
var b = null;
console.log(b+10);
console.log(b+"10");
4.3、运算符
JS中的绝大部分运算符和其他语言的运算符是差不多的,主要介绍和其他语言有差别的运算符。
- +和-:这里主要观察+在执行时的变化
- ==和!=:表示比较的两个变量的值是否相等
- ===和!==:表示比较变量的值与类型是否相等
4.3.1、+和-运算符
+运算符:这个运算符有两种含义,一个表示数值的相加,一个表示字符串的拼接。
-运算符:这个运算符表示数值的相减。由于隐式转换的问题,在使用数字像是的字符串和另一个数字进行减法运算时,将字符串形式的数字转换成number类型的数字,与另一个数字进行运算。
var b = "4";
console.log(b+10);
console.log(b+"10");
console.log(b-10);
console.log(10-b);
4.3.2、==和!=运算符与===和!==运算符
var a = 10;
var b = "10";
console.log(a==b);
console.log(a===b);
JS中a==b的判断触发了隐式类型转换,也就是说,JS中针对不相同的类型进行比较(==)运算的时候,会尝试尽可能的转成相同类型,而使用===不会触发隐式类型转换了,所以就出现了上面的结果。
4.4、条件语句(只了解switch)
由于隐式类型转换的问题,我们在使用switch的时候,用到了prompt输入函数,这个时候输入的值为一个字符串,但是我们要用这个输入的值进行判断对应的是那个case的时候,就需要确保这个进行判断的数值是一个number类型的数据。所以我们直接对这个值使用parseInt函数进行数据类型转换。
var num = prompt("请输入一个数字");
switch(parseInt(num)){
case 1: alert("星期一"); break;
case 2: alert("星期二"); break;
case 3: alert("星期三"); break;
case 4: alert("星期四"); break;
case 5: alert("星期五"); break;
case 6: alert("星期六"); break;
case 7: alert("星期天"); break;
}
5、数组
5.1、数组的创建
//使用new关键字创建
var arr = new Array();
//使用字面量的方式创建(常见)
var arr = [];
var arr2 = [1,2,'hello',false];//数组中保存的内容成为"元素"
JS中使用[ ]来表示数组,同时JS中数组的元素类型不要求是统一的,可以是任意类型的,动态类型的语言基本上都是如此。
5.2、获取数组元素
像Java一样通过数组下标位置输出数组元素,可以直接输出函数中指定输出某个下标的元素,也可以使用循环的方式将数组中的内容全部输出。
<script>
var arr = [1,2,3,false,'hello'];
console.log(arr[2]);
//这里的循环次数等于数组长度,就导致多循环了一次,数组下标越界了,此时这个元素的输出结果为undefined。
for(var i = 0;i <=arr.length;i++){
console.log(arr[i]);
}
</script>
使用for循环遍历数组还有这两种常用的方式
<script>
//写法二
var arr = [1,2,3,false,'hello'];
for(var i in arr){
//此处的i表示的数组的下标
console.log(arr[i]);
}
//写法三
for(var elem of arr){
//此处的elem表示的是数组元素
console.log(elem);
}
</script>
🌈注意:
JS中再写数组的时候,不要直接给数组名(arr)直接赋值,这样就会因为隐式类型转换,将arr转换成字符串。
5.3、数组的的越界访问
1️⃣上述中说了数组越界之后,输出的结果会是undefined,所以在JS中数组越界是合法的,不会像Java中报数组越界异常。
2️⃣除了越界访问,越界修改数组的值也是合法的,此时数组的长度也会随之发生改变。
<script>
var arr = [1,2,3,4,5,6,7,8];
arr[50] = 50;
console.log(arr);
console.log(arr.length);
</script>
可以看见,将数组越界访问的50位置的值修改为50时,数组的长度就变成了51,中间未初始化的元素的值就都是undefined了。
3️⃣JS在数组中可以将任意类型作为数组的下标像其中添加元素,比如负数,字符串等作为下标。
<script>
var arr = [1,2,3,4,5,6,7,8];
arr[-1] = -1;
arr['hello'] = 'world';
console.log(arr);
</script>
从上述图片中展示的结果中看到,我们虽然是将两个值添加到了数组中,但是数组的长度并没有发生变化,实际上,JS中的数组不仅仅只是一个传统意义上的数组(只能按下标来访问元素),当使用负数、字符串这些取访问数组时,会生成一个键值对添加到数组中,它更像是数组+Map的结合体,这就使得数组也能够按照Map键值对的方式来组织数据。
5.4、插入、修改、删除元素
5.4.1、插入元素
这里有两种方式添加元素。
- 使用push方法给数组进行尾插式的添加元素。
- 使用splice方法,这个方法是一个万能的方法,它可以对数组进行插入、修改、删除等的操作。
先来了解一下splice方法
array.splice(index,howmany,item1,....,itemX);
这些参数当howmany为0时,指定了index和itemx,那么就表示从index位置开始向后新增几个元素。
<script>
var arr = [1,2,3,4,5,6,7,8];
//在数组的末尾插入元素
arr.push('hello');
//在指定的位置开始插入元素
arr.splice(7,0,'你好','世界');
console.log(arr);
</script>
5.4.2、修改元素
1️⃣这里还是使用splice方法。当指定了index,howmany、item1....itemX这些参数,当item1~itemX 的个数与howmany指定的值相同并且小于从index位置开始到数组结尾的元素个数,就是对相应个数的元素进行修改。
<script>
var arr = [1,2,3,4,5,6,7,8];
console.log(arr);
arr.splice(3,2,111,222);
console.log(arr);
</script>
2️⃣当item1~itemX的个数和howmany指定的参数不相同时,item1~itemX的个数多,则这个时候进行的就是修改+插入。
<script>
var arr = [1,2,3,4,5,6,7,8];
console.log(arr);
arr.splice(3,2,111,222,333);
console.log(arr);
</script>
3️⃣当item1~itemX的个数小于howmany时进行的就是修改+删除。
<script>
var arr = [1,2,3,4,5,6,7,8];
console.log(arr);
arr.splice(3,2,111);
console.log(arr);
</script>
5.4.3、删除元素
使用splice方法,当指定了index和howmany两个参数的时候就表示删除。
<script>
var arr = [1,2,3,4,5,6,7,8];
console.log(arr);
arr.splice(3,2);//从3下标开始删除两个元素
console.log(arr);
</script>
6、函数
JS中需要使用function关键字来声明一个函数,结构包含函数名,形参列表(不必写参数类型),函数体;不必写返回值类型,但是可以有返回值。
// 创建函数/函数声明/函数定义
function 函数名(形参列表) {
函数体
return 返回值;
}
// 函数调用
函数名(实参列表) // 不考虑返回值
返回值 = 函数名(实参列表) // 考虑返回值
函数的定义和调用的先后顺序没有要求(函数的调用可以出现在函数声明之前,也可以时之后)
hello();
function hello(){
console.log("你好世界");
}
hello();
在JS中调用函数传入的实参个数比形参个数多或者少都是没有关系的,但是如果实参少的话没有收到传入参数值的变量默认值就是undefined,此时进行数值的运算结果就为NaN了;而如果实参个数多的话,形参就只能拿到函数设置时的参数个数,其余的就拿不到了。
<script>
function add(x,y){
return x+y;
}
console.log(add(5));
console.log(add(5,10));
console.log(add(5,10,15));
</script>
上述中传入一个参数,另一个参数默认就是undefined,这个时候进行相加操作,得到结果不是一个数字,所以输出结果为NaN。
我们想要避免上面的问题,在函数里面定义一个arguments变量,它是一个数组,其中包含了所有的实参,可以从arguments变量中拿到元素判断其的值是不是undefined,然后再进行运算。
<script>
function add(x,y){
var result = 0;
//arguments:得到所有的实参
for(var elem of arguments){
if(elem !== undefined){
result += elem;
}
}
return result;
}
console.log(add(5));
console.log(add(5,10));
console.log(add(5,10,15));
</script>
7、作用域
表示某个表示符名字在代码中的有效范围,在ES6标准之前,作用域主要分为两个。
- 全局作用域:在整个script标签中,或者单独的js文件中
- 全局作用域/函数作用域:在函数内部生效。
<script>
// 全局变量
var num = 10;
console.log(num);
function test() {
// 局部变量
var num = 20;
console.log(num);
}
function test2() {
// 局部变量
var num = 30;
console.log(num);
}
test();
test2();
console.log(num);
</script>
在函数内部创建变量的时候如果不写var,则得到的是一个全局的变量
<script>
function test() {
num = 100;
}
test();
console.log(num);
</script>
很多语言的局部变量作用域是按照代码块(大括号)来划分的,JS在ES6之前不是这样的。在一个代码块中用var定义一个变量,在这个代码块外也可以访问到。但是使用let在代码块中定义一个变量,只能在代码块中访问,不能再代码块之外访问不到。
<script>
if(true){
var a = 10;
}
console.log("第一个代码块外:"+a);
if(true){
let b = 10;
console.log("第二个代码块中:"+b);
}
console.log("第二个代码块外:"+b);
</script>
8、对象
JS不是面向对象的语言,但是存在对象的概念,JS中的对象设定和Java中的差异较大,JS中没有继承,封装多态,甚至没有类,JS中所有的对象的类型都是object,js的对象有属性也有方法,不过JS中的方法本质上也是属性。在JS中字符串、数组、数值、函数都是对象。在JS中对象是通过键值对的方式来组织的。下面介绍JS中对象的创建的方式。
1️⃣可以直接使用{ }来创建对象,{ } 里面可以写对象的属性、键值对之间使用","分割,键和值之间使用":"分割,方法的值是一个匿名函数。我们在将对象创建好之后可以使用student.sex = "男";的方式新增属性。
🌈示例:
<script>
var a = {};//创建了一个空的对象
var student = {
name:'张三',
height:170,
weight:140,
sayHello:function(){
console.log("你好");
}
};
//使用.成员访问运算符来访问属性'.'可以理解成"的"
console.log(student.name);
//使用[]访问属性,此时属性需要加上引号
console.log(student['height']);
//调用方法,别忘记加上()
student.sayHello();
//可以使用student.sex="男"这样的方式来新增属性。
student.sex = '男';
console.log(student.sex);
</script>
2️⃣可以使用new Object先创建对象,然后在添加属性。
<script>
var student = new Object();//和创建数组类似
student.name = '李四';
student.sex = '男';
student.height = '170';
student.sayHello = function(){
console.log("你好世界");
}
console.log(student.name);
console.log(student['sex']);
student.sayHello();
</script>
3️⃣使用构造函数创建对象 ,前面的创建对象的方式只能创建一个对象,而是用构造函数可以很方便的创建多个对象。
function 构造函数名(形参列表){
this.属性 = 值;
this.函数 = function(){
.....
}
}
var obj = new 构造函数名(实参);
🌈示例:
<script>
function Cat(name,type,sound){
this.name = name;
this.type = type;
this.miao = function(){
console.log(sound);
}
}
var mimi = new Cat('咪咪', '中华田园喵', '喵');
var xiaohei = new Cat('小黑', '波斯喵', '猫呜');
var ciqiu = new Cat('刺球', '金渐层', '咕噜噜');
console.log(xiaohei);
xiaohei.miao();
</script>