【Web前端】JavaScript(一)—— JS 基础语法
本文介绍了JavaScript的基础知识,主要包括以下内容: JavaScript概述:解释JS作为脚本语言的特点、应用场景(网页开发、游戏、服务器等)以及与HTML/CSS的关系(分别负责结构、表现和行为)。 运行机制:说明JS在浏览器中的执行过程,包括JS引擎的工作原理和浏览器渲染流程。 基本语法: 三种引入方式(行内式、内嵌式、外部式) 输入输出方法(prompt、alert、console
文章目录
1.初识JavaScript
1.1 JavaScript 是什么
JavaScript(简称JS)
- 是世界上最流行的编程语言之一
- 是一个脚本语言,通过解释器运行
- 主要在客户端(浏览器)运行,现在也可以基于 node.js 在服务器端运行
JavaScript能做的事
- 网页开发(更复杂的特效和用户交互)
- 网页游戏开发
- 服务器开发(node.js)
- 桌面程序开发
- 手机 app 开发
1.2 JavaScript 和 HTML 和 CSS 之间的关系
- HTML:网页的结构
- CSS:网页的表现
- JavaScript:网页的行为
1.3 JavaScript 运行过程
JS通常是运行在浏览器上的
- 编写的代码是保存在文件中的,也就是存储在硬盘(外存)上
- 双击 .html 文件浏览器(应用程序)就会读取文件,把文件内容加载到内存中(数据流向:硬盘 => 内存)
- 浏览器会解析用户编写的代码,把代码翻译成二进制的,能让计算机识别的指令(解释器的工作)
- 得到的二进制指令会被 CPU 加载并执行(数据流向:内存 => CPU)

浏览器分成渲染引擎+JS引擎 - 渲染引擎:解析 html + CSS,俗称“内核”
- JS 引擎:也就是 JS 解释器
JS 引擎逐行读取 JS 代码内容,然后解析成二进制指令,再执行
1.4 JavaScript 的组成
- ECMAScript(简称 ES): JavaScript 语法
- DOM: 页面文档对象模型, 对页面中的元素进行操作
- BOM: 浏览器对象模型, 对浏览器窗口进行操作
光有 JS 语法,只能写一些基础的逻辑流程
但是想要完成更复杂的任务,完成和浏览器以及界面的交互,就需要 DOM API 和 BOM API
这主要指在浏览器端运行的 JS. 如果是运行在服务端的 JS , 则需要使用 node.js 的 API,
就不太需要关注 DOM 和 BOM
重要概念: ECMAScript
这是一套“标准”,无论什么样的 JS 引擎都要遵守这个标准来实现
2.前置知识
2.1 第一个程序
<script>
alert("你好!");
</script>
- JavaScript代码可以嵌入到 HTML 的 script 标签中
2.2 JavaScript 的书写形式
2.2.1 行内式
直接嵌入到 html 元素内部
<input type="button" value="点击按钮" onclick="alert('哈哈')">
注意,JS 中的字符串常量可以使用单引号表示,也可以使用双引号表示
HTML 中推荐使用双引号,JS 中推荐使用单引号
2.2.2 内嵌式
写到 script 标签中
<script>
alert("你好!");
</script>
2.2.3 外部式
写到单独的 js 文件中
<script src="js/test01.js"></script>
alert("你好!");
注意,这种情况下 script 标签中间不能写代码,必须空着(写了代码也不会执行)
适合代码多的情况
2.3 注释
单行注释 // (建议使用)
多行注释 /* */ (多行注释不能嵌套)
2.4 输入输出
输入:prompt
弹出一个输入框
// 弹出一个输入框
prompt("请输入您的姓名");
输出:alert
弹出一个警示对话框,输出结果
// 弹出一个输出框
alert("你好!");
输出:console.log
在控制台打印一个日志(供程序员查看)
// 向控制台输出日志
console.log("这是一条日志");
console 是 js 中的“对象”
. 表示取对象中的某个属性或者方法
3.语法概览
3.1 变量的使用
基本用法
创建变量(变量定义/变量声明/变量初始化)
var name = 'zhangsan';
var age = 20;
var 是 JS 中的关键字,表示这是一个变量
= 在 JS 中表示“赋值”,相当于把数据放到内存的盒子中, = 两侧建议有一个空格
每个语句最后带有一个 ; 结尾。JS 中可以省略但是建议加上
注意,此处的 ; 为英文分号。 JS 中的标点都是英文标点
初始化的值如果是字符串,那么就需要使用单引号或者双引号引起来
初始化的值如果是数字,直接赋值即可
在 JS 中的数字只有一种类型:数值类型(包括整数和小数)
JS 中定义一个变量时不需要对该变量指定类型
创建变量也可以使用 let。
let 出现时间比 var 出现的晚,意味着避免了一些 var 定义变量时的缺陷。
如果使用 let 定义变量,此变量的生命周期、作用域基本和Java类似(推荐使用 let)
使用变量
console.log(age); // 读取变量内容
age = 30; // 修改变量内容
变量需要先声明才能使用
代码示例: 弹框提示用户输入信息, 再弹框显示.
let name = prompt("请输入姓名");
let age = prompt("请输入年龄");
let score = prompt("请输入分数");
alert("您的姓名是" + name);
alert("您的年龄是" + age);
alert("您的分数是" + score);
也可以把三个输出内容合并成一次弹框
let name = prompt("请输入姓名");
let age = prompt("请输入年龄");
let score = prompt("请输入分数");
alert("您的姓名是" + name + "\n" + "您的年龄是" + age + "\n" + "您的分数是" + score);
+表示字符串拼接,也就是把两个字符串首尾相接变成一个字符串\n表示换行
理解 动态类型
(1)JS 的变量类型是程序运行过程中才确定的(运行到 = 语句时才会确定类型)(弱类型)
let a = 10; // 数字
let b = "hehe"; // 字符串
(2)随着程序运行,变量的类型可能会发生改变(动态类型)
let a = 10; // 数字
a = "hehe"; // 字符串
- 强类型变量/弱类型变量
强类型变量意味着不同类型变量进行赋值时需要进行一定的手段(如强制类型转换)
弱类型变量在不同类型的变量之间进行赋值的时候可以直接赋值- 动态类型变量/静态类型变量
动态类型意味着代码在执行过程中,变量类型可以随时发生变化
静态类型变量意味着变量定义的时候是什么类型,程序运行是该变量就是什么类型
3.2 基本数据类型
JS 中内置的几种类型
- number:数字,不区分整数和小数
- boolean:true 真, false 假
- string:字符串类型
- undefined:只有唯一的值 undefined,表示未定义的值
- null:只有唯一的值 null,表示空值
number 数字类型
JS 中不区分整数和小数,统一都使用“数字类型”表示
数字进制表示
计算机中使用二进制表示数据,人用十进制
因为二进制在使用过程中不太方便
所以在日常使用二进制数字时会用 八进制 和 十六进制 来表示二进制数字
let a = 0b10; // 二进制,以 0b 开头
let b = 0o7; // 八进制,以 0o 开头
let c = 0x10; // 十六进制,以 0x 开头
注意:
- 一个八进制数字对应三个二进制数字
- 一个十六进制数字对应四个二进制数字(两个十六进制数字就是一个字节)
特殊的数字值
- Infinity:无穷大,大于任何数字,表示数字已经超过了JS能表示的范围
- -Infinity:负无穷大,小于任何数字,表示数字已经超过了JS能表示的范围
- NaN:表示当前的结果不是一个数字
let max = Number.MAX_VALUE;
// 得到 Infinity
console.log(max * 2);
// 得到 -Infinity
console.log(-max * 2);
// 得到 NaN
console.log("haha" - 10);
注意:
- 负无穷大 和 无穷小 不一样。无穷小指的是无限趋近于0,值为
1 / Infinity'haha' + 10得到的结果不是 NaN,而是 ‘haha10’,计算时会把数字隐式转换成字符串,再进行字符串拼接- 可以使用 isNaN 函数判定是不是一个非数字
console.log(isNaN(10)); // false console.log(isNaN('haha' - 10)); // true
string 字符串类型
基本规则
字符串字面值需要使用引号引起来,单引号双引号均可
let a = "haha";
let b = "hehe";
// let c = hehe // 运行出错
如果字符串中本来已经包含引号:
// let msg = "My name is "zhangsan""; // 报错
let msg = "My name is \"zhangsan\""; // 正确,使用转义字符 \" 来表示字符串内部的引号
let msg = "My name is 'zhangsan'"; // 正确,搭配使用单双引号
let msg = 'My name is "zhangsan"'; // 正确,搭配使用单双引号
转义字符
有些字符不方便直接输入,于是要通过一些特殊方式来表示
\n\\\'\"\t
求长度
使用 String 的 length 属性即可
let a = "haha";
console.log(a.length);
let b = "哈哈";
console.log(b.length);
结果
4
2
单位为字符的数量
字符串拼接
使用 + 进行拼接
let a = "My name is ";
let b = "zhangsan";
console.log(a + b);
数字和字符串也可以进行拼接
let c = "My score is ";
let d = 100;
console.log(c + d);
要认准进行拼接的变量是字符串还是数字
console.log(100 + 100); // 200
console.log('100' + 100); // 100100
boolean 布尔类型
表示“真”和“假”
boolean 原本是数学中的概念(布尔代数)
在计算机中 boolean 意义重大,往往要搭配条件/循环完成逻辑判断
boolean 参与运算时当做 1 和 0 看待
console.log(true + 1);
console.log(false + 1);
这样的操作实际上是不科学的,实际开发中不应该这样写
boolean 参与运算后类型变为 number
undefined 未定义数据类型
如果一个变量没有被初始化过,结果就是 undefined,是 undefined 类型
let a;
console.log(a);
undefined 和字符串进行相加,结果进行字符串拼接
console.log(a + "10");
undefined 和数字进行相加,结果为 NaN
console.log(a + 10);
null 空值类型
null 表示当前的变量是一个“空值”
let b = null;
console.log(b + 10); // 10
console.log(b + "10"); // null10
注意:
null 和 undefined 都表示取值非法的情况,但侧重点不同
null 表示当时的值为空(相当于有一个空盒子)
undefined 表示当前的变量未定义(相当于连盒子都没有)
3.3 运算符
算术运算符
+-*/%
赋值运算符 & 复合赋值运算符
=+=-=*=/=%=
自增自减运算符
++:自增1--:自减1
比较运算符
<><=>===:比较相等(会进行隐式类型转换,只比较内容)!====:比较相等(不会进行隐式类型转换,比较内容和类型)!==
逻辑运算符
&&与||或!非
位运算
&按位与|按位或~按位取反^按位异或
移位运算
<<左移>>有符号右移(算术右移)>>>无符号右移(逻辑右移)
3.4 条件语句
if 语句
基本语法格式
// 形式1
if (条件1) {
语句;
}
// 形式2
if (条件1) {
语句;
} else {
语句2;
}
// 形式3
if (条件1) {
语句;
} else if (条件2) {
语句2;
} else if (...) {
语句···;
} else {
语句N;
}
例:判断输入的数字是奇数还是偶数
let num = prompt("请输入数字");
if(num % 2 == 0){
alert("输入的数字" + num + "是偶数");
}else if(num % 2 == 1 || num % 2 == -1){
alert("输入的数字" + num + "是奇数");
}else{
alert("非法输入");
}
三元表达式
是 if else 的简化写法
条件 ? 表达式1 : 表达式2;
条件为真返回表达式1,条件为假返回表达式2
注意:三元表达式的优先级是比较低的
例:三元表达式判断奇偶
let num = prompt("请输入数字");
num % 2 == 0 ? alert("输入的数字" + num + "是偶数") : alert("输入的数字" + num + "是奇数");
switch
更适合多分支的场景
switch(表达式){
case 值1:
语句1;
break;
case 值2:
语句2;
break;
default:
语句N;
}
例:用户输入一个整数,提示今天星期几
let day = prompt("请输入今天星期几");
day = parseInt(day); // 用户输入的 day 为字符串形式,需要将字符串转换成数字
switch(day){
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;
default:
alert("输入有误");
}
3.5 循环语句
重复执行某些语句
while 循环
while(条件){
循环体;
}
执行过程:
- 先执行条件语句
- 条件为 true,执行循环体
- 条件为 false,直接结束循环
continue
结束本次循环
break
结束整个循环
for 循环
for (表达式1: 表达式2: 表达式3){
循环体;
}
- 表达式1:用来初始化循环变量
- 表达式2:循环条件
- 表达式3:更新循环变量
执行过程
- 先执行表达式1,初始化循环变量
- 再执行表达式2,判断循环条件
- 如果条件为 false,结束循环
- 如果条件为 true,则执行循环体代码
- 执行表达式3,更新循环变量
3.6 数组
创建数组
使用 new 关键字创建
// Array 的 A 要大写
let arr = new Array();
使用字面量方式创建[常用]
let arr = [];
let arr2 = [1, 2, 3, '4']; // 数组中保存的内容称为“元素”
注意: JS 中的数组不要求元素是相同类型
获取数组元素
通过下标的方式获取数组元素(数组下标从 0 开始)
let arr = [1, 2, 3, '4'];
console.log(arr);
console.log(arr[0]);
console.log(arr[1]);
console.log(arr[2]);
console.log(arr[3]);
arr[2] = "123";
console.log(arr);

如果下标超出范围读取元素,则结果为 undefined
console.log(arr[5]); // undefined
console.log(arr[-1]); // undefined

**注意:**不要给数组名直接赋值
let arr = [1, 2, 3, '4'];
console.log(arr);
arr = "12345";
console.log(arr);

相当于本来 arr 是一个数组,重新赋值之后变成了字符串
新增数组元素
通过修改 length 新增
相当于在末尾新增元素,新增的元素默认值为 undefined
let arr = [1, 2, 3, 4];
console.log(arr);
arr.length = 10;
console.log(arr);
console.log(arr[6]);

通过下标新增
如果下标超出范围赋值元素,则会给指定位置插入新元素
let arr = [];
arr[2] = 10;
console.log(arr);

此时这个数组的 [0] 和 [1] 都是 undefined
使用 push 进行追加元素
代码示例:将 arr 中的奇数放到 newArr 中
let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let newArr = [];
for(let i = 0; i < arr.length; i++){
if(arr[i] % 2 != 0){
newArr.push(arr[i]);
}
}
console.log(arr);
console.log(newArr);

删除数组中的元素
使用 splice 方法删除元素
let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(arr);
arr.splice(1, 1);
console.log(arr);
第一个参数表示从下标为 1 的位置开始删除,第二个参数表示要删除的元素个数是 1 个
属性和方法
arr.length:length 使用的时候不带括号,此时 length 就是一个普通的变量(称为成员变量,也叫属性)
arr.push()、arr.splice():使用的时候带括号,并且可以传一个参数,此时是一个函数(也叫方法)
3.7 函数
语法格式
function 函数名(形参列表){
函数体;
return 返回值;
}
// 函数调用
函数名(实参列表); // 不考虑返回值
返回值 = 函数名(实参列表); // 考虑返回值
- 函数定义不会执行函数体中的内容,必须调用才会执行,调用几次就执行几次
function hello(){
console.log("hello");
}
function hello2(name){
console.log(name + ",hello");
return 1;
}
// 将没有返回值的函数赋值给一个变量,该变量是 undefined
let a = hello();
// 将有返回值的函数赋值给一个变量,该变量的类型就是函数返回值的类型
let b = hello2("123");
- 调用函数的时候进入函数内部执行,函数结束时回到调用位置继续执行
- 函数的定义和调用的先后顺序没有要求
// 调用函数
hello();
// 定义函数
function hello(){
console.log("hello");
}
关于参数个数
实参和形参之间的个数可以不匹配,但实际开发中一般要求形参和实参个数要匹配
(1)如果实参个数比形参多,则多出的参数不参与函数运算
function sum(num1, num2){
return num1 + num2;
}
sum(10, 20, 30); // 30
(2)如果实参个数比形参个数少,则此时多出的形参值为 undefined
function sum(num1, num2){
return num1 + num2;
}
sum(10); // undefined
函数表达式
另一种函数的定义方式
let add = function(){
let sum = 0;
// arguments 参数列表
for(let i = 0; i < arguments; i++){
sum += arguments[i];
}
return sum;
}
console.log(add(10, 20)); // 30
console.log(add(1, 2, 3, 4)); // 10
console.log(typeof add); // function
此时形如 function(){} 这样的写法定义了一个匿名函数,然后这个匿名函数用一个变量来表示,后面就可以通过这个 add 变量来调用函数了
JS 中函数是一等公民,可以用变量保存,也可以作为其他函数的参数或者返回值
作用域
某个表示符名字在代码中的有效范围
在 SE6 标准之前,作用域主要分为两个:
- 全局作用域:在整个 script 标签中或单独的 js 文件中生效
- 局部作用域/函数作用域:在函数内部生效
let num = 10; // 全局变量
function test01(){
let num = 100; // 局部变量
console.log(num);
}
function test02(){
let num = 200; // 局部变量
console.log(num);
}
console.log(num);
test01();
test02();
创建变量时如果不写 var 也不写 let,就会得到一个全局变量
function test() { num = 100; } test(); console.log(num);很多语言的局部变量作用域是按照代码块(大括号)来划分的, 在 ES6 之前的JS,var 没有块级作用域,只有函数作用域
作用域链
- 函数可以定义在函数内部
- 内部函数可以访问外层函数的局部变量
内部函数可以访问外部函数的变量,采取的是链式查找的方式,从内到外依次查找
3.8 对象
基本概念
对象指一个具体的事物
在 JS 中,字符串、数值、数组、函数都是对象
每个对象中包含若干属性和方法
- 属性:事物的特征
- 方法:事物的行为
使用 字面量 创建对象[常用]
使用 {} 创建对象
let a = {}; // 创建了一个空对象
let student = {
name : "小明",
height : 175,
weight : 70,
sayHello : function(){
console.log("hello");
}
};
- 使用 {} 创建对象
- 属性和方法使用 键值对 的形式来组织
- 键值对之间使用 ‘,’ 分隔,最后一个属性后面可以不加 ‘,’
- 键和值之间使用 ‘:’ 分隔
- 方法的值是一个匿名函数
使用对象的属性和方法
// 1.使用 . 成员访问运算符来访问属性
console.log(student.name);
// 2.使用 [] 访问属性,此时属性需要加上引号
console.log(student['height']);
// 3.调用方法,不要忘记()
console.log(student.sayHello());
使用 new Object 创建对象
let student = new Object(); // 和创建数组类似
student.name = "小明";
student.height = 175;
student.weight = 70;
student.sayHello = function(){
console.log("hello");
}
console.log(student.name);
console.log(student["height"]);
student.sayHello();
注意:使用 {} 创建的对象也可以随时使用 student.name = "小明"; 这样的方式新增属性
使用 构造函数 创建对象
前面两个创建方式只能创建一个对象,而使用构造函数可以很方便的创建多个对象
function 构造函数名(形参){
this.属性 = 值;
this.方法 = function ...
}
let obj = new 构造函数名(实参);
注意:
- 在构造函数内部使用 this 关键字来表示当前正在构建的对象
- 构造函数的函数名首字母一般大写
- 构造函数的函数名可以是名词
- 构造函数不需要 return
- 创建对象的时候必须使用 new 关键字
使用构造函数创建两个 Person 对象
function Person(name, height, weight){
this.name = name;
this.height = height;
this.weight = weight;
this.say = function(){
console.log(name + "正在说");
}
}
let xiaoming = new Person("小明", 175, 70);
let zhangsan = new Person("张三", 175, 70);
console.log(xiaoming);
console.log(zhangsan);
class
ES6中引入了 class,可以使用 class 构造对象
class Person{
constructor(name, height, weight){
this.name = name;
this.height = height;
this.weight = weight;
}
say(){
console.log(this.name + "正在说");
}
static other = "other";
}
let xiaoming = new Person("小明", 175, 70);
xiaoming.say();
console.log(Person.other);
- constructor:构造函数
- class 中定义方法直接写 方法名(){}
- class 中可以定义 static 属性或方法,这个属性或方法不属于对象,属于整个类
class Student extends Person{
constructor(name, height, weight, number){
super(name, height, weight);
this.number = number;
}
// 重写 say 方法
say(){
console.log("学生" + this.name + "正在说话")
}
}
let student = new Student("张三", 175, 70, 1);
console.log(student);
- 使用 extends 实现类继承, super() 用于调用父类构造方法
- 子类可重写父类方法
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)