JS基础语法与数据类型

JS基础语法与数据类型

2026年9月29日·#编程学习/javaweb学习笔记JavaWeb/JavaScript/前端·5178 字 26 分钟
浏览量加载中...
AI 摘要- DeepSeek

JS 用 let 声明变量、const 声明常量,是弱类型语言;这篇把基本数据类型、typeof、模板字符串、运算符与流程控制一次讲清,并逐条对照 Java 找异同

封面图
JS基础语法与数据类型 - 封面图

上一篇解决了”JS 代码写在哪里”,从这篇开始写代码本身。JS 的基础语法和 Java 很像(所以学过 Java 会觉得眼熟),但它是弱类型语言——变量不挑类型、条件不要求布尔值、除法不做整除……这些差异正是最容易写错的地方,这篇把每一条都和 Java 对照着写。

变量:let#

JS 中用 let 关键字来声明变量——最大的特点是:

JS 是弱类型语言,变量可以存放不同类型的值。

课程代码 02. JS-基础语法.html 里就是这么演示的:

//1. 声明变量
let a = 10;
a = "Hello"; // 同一个变量,换成字符串也行
a = true; // 换成布尔值也行
alert(a); //弹出框 —— 最后弹出的是 true

PPT 版本更简短:

<script>
//变量
let a = 20;
a = "Hello";
alert(a);
</script>
Important

这就是”弱类型”的含义:Java 里 int a = 10; 之后 a = "Hello" 直接编译不过,而 JS 里没有类型检查,变量装什么就是什么。好处是写法灵活,代价是类型错了编译器不会提醒你——只能靠输出语句自己检查(后面马上讲)。

常量:const#

JS 中用 const 关键字来声明常量。一旦声明,常量的值就不能改变(不可以重新赋值)。

//2. 声明常量
const PI = 3.14;
//PI = 5.0; // 取消注释再刷新,看控制台报错
console.log(PI); //输出到控制台
// document.write(PI); //输出到body区域(不常用)

PPT 上把这个错误演示了一遍:去掉 PI = 3.5; 的注释,浏览器控制台会报:

Uncaught TypeError: Assignment to constant variable.
Tip

常量名习惯全大写(PI、MAX_COUNT),和 Java 的 final 常量一个约定。改常量的错误是运行时报错——页面会停在这一行报错(控制台里一条红色信息),后面的代码不再执行,这一点比 Java 的编译期报错更”晚”。

变量名规则#

PPT 给了三条硬规则:

规则说明
只能用字母、数字、下划线(_)、美元符号($)组成,且数字不能开头user_name、userName、$price 都可以;1name 不行
变量名严格区分大小写name 和 Name 是两个不同的变量
不能用关键字如 let、var、if、for 等
Warning

早期的 JS 里声明变量还可以用 var,但并不严谨、不推荐:var 声明的变量没有块级作用域(在 if、for 的 {} 里声明会”漏”到外面)、还能重复声明同名变量,很容易写出隐蔽的 bug。现在统一用 let 声明变量、const 声明常量。

输出语句:程序员的”打印”#

写 Java 时用 System.out.println() 看结果;JS 里有三种输出方式(课程代码里都出现了):

输出语句效果说明
window.alert()弹出警告框使用频次较高;window. 可以省略,直接写 alert()
console.log()写入浏览器控制台使用频次较高;浏览器按 F12(或右键”检查”)打开开发者工具,切到 Console 面板看
document.write()向 HTML 的 body 内输出内容不常用(课程代码里就注释掉了)
Tip

调试时首选 console.log():它不像 alert() 那样会拦住页面(每弹一次都要点”确定”),而且能连续打印多条、看到顺序。浏览器控制台应该成为你写 JS 时最常开着的面板。

数据类型#

JavaScript 的数据类型分为:基本数据类型和引用数据类型(对象)。

基本数据类型一共五种,PPT 逐个给了说明:

类型说明例子
number数字(整数、小数、NaN(Not a Number))let a = 20;、let b = 1.5;
boolean布尔。true、falselet flag = true;
null对象为空。JavaScript 是大小写敏感的,因此 null、Null、NULL 是完全不同的let obj = null;
undefined当声明的变量未初始化时,该变量的默认值是 undefinedlet x;
string字符串,单引号、双引号、反引号皆可,推荐使用单引号'JS'、"JS"、`JS`

使用 typeof 运算符可以获取数据类型(课程代码 03. JS-数据类型.html 前半部分,注释里直接写了结果):

//1. 数据类型
alert(typeof 10); // number
alert(typeof 1.5); // number
alert(typeof true); // boolean
alert(typeof false); // boolean
alert(typeof "Hello"); // string
alert(typeof 'JS'); // string
alert(typeof `JavaScript`); // string —— 三种引号都是字符串
alert(typeof null); // object ← 课程注释里标了问号:null 的类型是 object ?
let a;
alert(typeof a); // undefined
Warning

课程代码在 typeof null 后面专门标了个问号,这个结果确实是”反直觉”的:typeof null 返回 'object'。这是 JS 最早实现时的历史遗留问题,后来被标准固化了(改了会影响老代码,所以一直留着)。判断一个值是不是 null,别用 typeof,直接用相等判断:a === null。

Note

“引用数据类型(对象)“就是后面要学的自定义对象、数组这些——它们的 typeof 结果都是 object;而函数比较特殊,typeof 会返回 function(函数、自定义对象都在 15 篇讲)。

模板字符串#

字符串拼接是写页面时最频繁的操作。先看”笨办法”——用 + 把字符串和变量连起来;再看 JS 提供的模板字符串:

模板字符串语法: ` `(反引号,英文输入模式下按键盘的 Tab 键上方波浪线 ~ 那个键) 内容拼接变量时,使用 ${} 包住变量。

//2. 模板字符串 - 简化字符串拼接
let name = 'Tom';
let age = 18;
// 传统写法:+ 号拼接(引号会被切断、加号容易漏)
console.log('我是' + name + ', 我今年' + age + '岁');
// 模板字符串:整句话用反引号包住,变量用 ${} 嵌进去
console.log(`我是${name}, 我今年${age}岁`);

PPT 上还有一版更长的对比,效果一样:

console.log('大家好, 我是新入职的' + name + ', 今年' + age + '岁了, 请多多关照');
console.log(`大家好, 我是新入职的${name}, 今年${age}岁了, 请多多关照`);

两种写法输出完全相同:我是Tom, 我今年18岁。

Tip

这条经验往后会一直用:字符串 + 变量 + 字符串这种拼接,一律改成模板字符串——少写一堆引号和加号,也不容易把空格、逗号漏掉。

补充:运算符#

PPT 把”流程控制”列在 ECMAScript 的范围里但没展开,这里补上写页面必须会用的部分(写法大多和 Java 一样,标 ★ 的是差异点):

类别运算符说明
算术+ - * / %★ + 只要两边有字符串就是拼接,不是加法;★ / 是普通除法,5 / 2 得 2.5(不像 Java 的整数除法得 2)
赋值= += -= *= /=同 Java
比较== != > < >= <=★ == 会先做类型转换再比较:'10' == 10 结果是 true
全等=== !==★ 类型和值都相同才为 true:'10' === 10 是 false。判断相等推荐用 ===
逻辑&& || !短路特性同 Java
自增自减++ --同 Java
三元条件 ? 值1 : 值2同 Java
// + 的两副面孔
console.log(10 + 20); // 30 —— 两边都是数字,做加法
console.log('10' + 20); // 1020 —— 有字符串,做拼接
// == 和 === 的区别
console.log('10' == 10); // true —— 先把字符串转成数字再比较
console.log('10' === 10); // false —— 类型不同,直接不等
// 除法没有"整除"
console.log(5 / 2); // 2.5
Warning

== 的隐式类型转换是 JS 里最经典的”坑”(0 == '' 也是 true)。判断相等一律用 ===——和 Java 里”引用类型比地址”的坑不同,JS 的坑是”类型被偷偷换掉”。

补充:流程控制#

if、for、while、switch 的写法与 Java 几乎一样,逐个过一遍:

// if / else if / else:和 Java 一样
let score = 85;
if (score >= 90) {
console.log('优秀');
} else if (score >= 60) {
console.log('及格');
} else {
console.log('不及格');
}
// for:和 Java 一样,计数变量用 let 声明
for (let i = 1; i <= 5; i++) {
console.log(i); // 依次输出 1 2 3 4 5
}
// while:先判断,再执行
let i = 1;
while (i <= 3) {
console.log(i);
i++;
}
// do…while:先执行一次,再判断(至少执行一次)
let j = 1;
do {
console.log(j);
j++;
} while (j <= 3);
// switch:和 Java 一样,每个 case 后面要 break,否则会"穿透"往下执行
let day = 3;
switch (day) {
case 1:
console.log('周一');
break;
case 3:
console.log('周三'); // 命中这一条
break;
default:
console.log('其它');
}

遍历数组时,JS 最常用的还是 for + 索引(课程案例里就是这么写的):

let arr = [10, 20, 30];
// 索引遍历:课程案例的标准写法
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
// for…of:直接拿元素(了解,类似 Java 的增强 for)
for (let item of arr) {
console.log(item);
}

和 Java 最大的差异在这里——JS 的条件不要求是布尔值:

let n = 0;
if (n) {
console.log('能进来'); // 不会执行
} else {
console.log('0 被当成 false'); // 会执行
}
Important

JS 会做隐式类型转换:0、''(空字符串)、null、undefined、NaN、false 都会被当成 false(这叫”假值”),其余的值都当成 true。Java 里 if (0) 直接编译报错,JS 里却能跑——所以判断”有没有值”时可以直接 if (name),但要清楚它把空字符串也当成了”没有”。

小结:和 Java 对照#

对比项JavaJavaScript
变量声明int a = 10; 必须写类型(Java 10+ 的 var 只是类型推断,仍是强类型)let a = 10; 不写类型,可以随时换类型(弱类型)
常量final double PI = 3.14;const PI = 3.14;
数据类型基本类型 int/double/boolean/char… 分得很细,有固定大小基本类型只有 number、boolean、null、undefined、string 五种;数字不区分整数小数,另有引用类型(对象)
字符串引号只能双引号 "abc"单引号、双引号、反引号都可以(推荐单引号)
字符串拼接+,复杂拼接用 String.format / StringBuilder+,更好用的是模板字符串 `${变量}`
相等判断== 比基本类型的值 / 引用类型的地址== 会先转换类型再比较;===(全等)类型和值都相同才为 true,推荐 ===
除法5 / 2 = 2(整数除法)5 / 2 = 2.5(都是浮点数)
打印输出System.out.println()console.log()(控制台)、alert()(弹窗)、document.write()(写 body)
if 的条件必须是 boolean不要求,0、''、null、undefined、NaN 等假值当 false
流程控制if / for / while / do-while / switch写法基本一致(for、switch、break、continue 都能直接照搬)
数组int[] arr = new int[5]; 长度固定let arr = [10, 20, 30]; 长度可变,能随意增删(15 篇)

相关#

练习题#

一、知识回顾(读完直接做下面的实践题)#

  1. JS 是弱类型语言:变量可以存放不同类型的值;声明变量用 let、声明常量用 const(一旦声明,常量的值不能改变、不可以重新赋值);早期还能用 var,但不严谨、不推荐(没有块级作用域、可以重复声明)
  2. 变量名规则:只能由字母、数字、下划线(_)、美元符号($)组成且数字不能开头;严格区分大小写(name 和 Name 是两个变量);不能使用关键字(let、var、if、for 等)
  3. 三种输出语句:window.alert() 弹出警告框(window. 可省略,频次高)、console.log() 写入浏览器控制台(频次高,F12 → Console)、document.write() 向 HTML 的 body 内输出内容(不常用)
  4. 数据类型分基本数据类型和引用数据类型(对象);基本类型五种:number(整数、小数、NaN)、boolean、null(对象为空)、undefined(声明未初始化时的默认值)、string
  5. 用 typeof 运算符获取数据类型;typeof null 的结果是 object(历史遗留问题,判断 null 要用 a === null,别用 typeof)
  6. 字符串单引号、双引号、反引号皆可,推荐单引号;模板字符串用反引号包住整句、变量用 ${} 嵌进去,可以完全替代 + 拼接
  7. == 会先做隐式类型转换再比较('10' == 10 为 true);===(全等)要求类型和值都相同才为 true,判断相等推荐用 ===
  8. 算术运算的两个差异:+ 两边只要有字符串就是拼接;/ 是普通除法,5 / 2 得 2.5(不像 Java 得 2)
  9. 流程控制 if / else if / else、for、while、do…while、switch 的写法和 Java 几乎一样(switch 的 case 照样要写 break);计数变量用 let 声明
  10. JS 的条件不要求布尔值:0、''、null、undefined、NaN、false 会被当成 false(假值),其余都当成 true——所以 if (n) 这种写法在 JS 里是合法的

二、裸写题#

  • 2-1 变量与常量:看看弱类型和”改不动的常量” 按三步做,每步都用输出语句看结果:

    1. 声明一个变量存数字 10,然后把它依次改成字符串 "Hello"、布尔值 true,弹窗看看最后是什么
    2. 声明一个常量存圆周率 3.14,用控制台输出它
    3. 给这个常量重新赋值为 5.0(故意写错),保存后刷新页面,看控制台报了什么错;看完把这行改回注释 (练习文件 test_14_变量与常量.html 里已经给了骨架和写作区。)
    提示(先自己想,实在想不出再点开)

    一级 · 思路:变量用声明变量的关键字、常量用声明常量的关键字;“看结果”有两种办法——弹窗和控制台 二级 · 方法:let 声明变量、const 声明常量;alert(...) 弹窗、console.log(...) 输出到控制台 三级 · 骨架:let a = ____; a = "____"; a = ____; alert(a); / const PI = 3.14; console.log(____); / //PI = 5.0;

    参考答案(做完再点开)
    //1. 声明变量(弱类型:同一个变量可以换成别的类型)
    let a = 10;
    a = "Hello";
    a = true;
    alert(a); // 最后弹出 true
    //2. 声明常量
    const PI = 3.14;
    console.log(PI); // 输出到控制台
    //PI = 5.0; // 取消注释会报错:Uncaught TypeError: Assignment to constant variable.

    对照课程 02. JS-基础语法.html:变量那三行、常量那两行在课程代码里都是分开注释演示的(拆注释逐个看)。第 3 步的报错说明常量不可以重新赋值,而且页面会停在报错那一行。

  • 2-2 用类型检测给五个变量”验明正身” 声明五个变量,分别装:整数 10、小数 1.5、布尔值 true、字符串 'JS'、以及一个只声明不给初始值的变量;再用类型检测运算符把它们的类型逐个打印到控制台。另外顺手检测一下 null 的类型,看结果和你想的是否一样。 (练习文件 test_14_数据类型与typeof.html 里已经给了写作区。)

    提示(先自己想,实在想不出再点开)

    一级 · 思路:每种值用一个变量装;“类型检测”是一个运算符,直接放在值前面用 二级 · 方法:typeof 值 得到类型字符串(结果有 number、boolean、string、undefined、object);打印用 console.log() 三级 · 骨架:let a = 10; console.log(____ a); / let b; console.log(typeof ____); / console.log(typeof ____); // null 的类型

    参考答案(做完再点开)
    let a = 10;
    console.log(typeof a); // number —— 整数也是 number
    let b = 1.5;
    console.log(typeof b); // number —— 小数同样是 number(JS 不区分)
    let c = true;
    console.log(typeof c); // boolean
    let d = 'JS';
    console.log(typeof d); // string
    let e;
    console.log(typeof e); // undefined —— 声明了没初始化,默认 undefined
    console.log(typeof null); // object —— 反直觉,是历史遗留问题

    对照课程 03. JS-数据类型.html:课程代码把 typeof 的结果直接写在注释里了(//number、//boolean 等),最后一条 alert(typeof null); //null ? -> object 就是那个”问号”。null 的类型判断要用 a === null。

  • 2-3 把拼接写法改成模板字符串 已知两个变量:名字 'Tom'、年龄 18。先用加号拼接输出一句话:我是Tom, 我今年18岁;再用一种”不用加号”的写法输出完全相同的一句话。 (练习文件 test_14_模板字符串.html 里已经给了变量定义和写作区。)

    提示(先自己想,实在想不出再点开)

    一级 · 思路:JS 有一种字符串专门用来拼接:整句话被一对特殊引号包住,变量可以直接”嵌”在里面 二级 · 方法:模板字符串用反引号(键盘左上角 ~ 那个键)包住整句,变量写成 ${变量名} 三级 · 骨架:console.log('我是' + ____ + ', 我今年' + ____ + '岁'); / console.log(`我是${____}, 我今年${____}岁`);

    参考答案(做完再点开)
    let name = 'Tom';
    let age = 18;
    // 传统写法:+ 号拼接
    console.log('我是' + name + ', 我今年' + age + '岁');
    // 模板字符串:整句用反引号包住,变量用 ${} 嵌进去
    console.log(`我是${name}, 我今年${age}岁`);

    对照课程 03. JS-数据类型.html 后半部分(课程输出的句子是”我是Tom, 我今年18岁”)。注意:反引号是成对的,写成单引号 ' 就变成普通字符串、${} 会原样显示出来。

  • 2-4 用循环和判断打印 1~10(偶数做标记) 用循环把 1 到 10 依次打印出来;如果当前数字是偶数,就在数字后面跟上 (偶数),其余数字原样打印。输出示例:1、2(偶数)、3、4(偶数)…… 做完再想一句:如果改成打印 1~100,你的代码需要改几个字? (练习文件 test_14_循环与判断.html 里已经给了写作区。)

    提示(先自己想,实在想不出再点开)

    一级 · 思路:“重复 10 次”用循环;“是不是偶数”用取余运算符判断,再用 if 选择打印哪种内容 二级 · 方法:for (let i = 1; i <= 10; i++);偶数判断 i % 2 === 0;打印 console.log(...) 三级 · 骨架:for (let i = 1; i <= 10; i++) { if (i % 2 === 0) { console.log(i + '____'); } else { console.log(____); } }

    参考答案(做完再点开)
    // 打印 1~10,偶数后面加标记
    for (let i = 1; i <= 10; i++) {
    if (i % 2 === 0) {
    console.log(i + '(偶数)');
    } else {
    console.log(i);
    }
    }

    想改成 1~100 只需要把 i <= 10 改成 i <= 100——这就是循环的价值(对应课程 06. JS-案例-员工列表.html 里”遍历所有数据行”的写法:for (let i = 0; i < trList.length; i++))。

三、综合题#

  • 3-1 做一份”成绩单统计” 用变量和流程控制统计一个学生的成绩单(不用数组、不用函数,就用手上的语法):

    1. 用变量存三科成绩:语文 92、数学 85、英语 78(变量名自己起,见名知意)
    2. 用常量存学生名字:团子
    3. 计算总分和平均分(平均分 = 总分 ÷ 3)
    4. 用模板字符串输出一行:团子的总分是255,平均分是85
    5. 用条件判断给出等级再输出一行:平均分 ≥ 90 输出 优秀;≥ 80 输出 良好;≥ 60 输出 及格;否则输出 不及格
    6. 额外要求:把数学成绩改成 55(模拟补考),刷新页面检查等级有没有跟着变 (练习文件 test_14_综合_成绩单统计.html 里已经给了写作区。)
    提示(先自己想,实在想不出再点开)

    一级 · 思路:第 1~2 步是”存数据”,第 3 步是算术运算,第 4 步是字符串输出,第 5 步是多重条件判断;第 6 步只改一个变量的值,其它代码都不用动 二级 · 方法:let 存成绩、const 存名字;求和用 +、平均分用 /;输出用模板字符串 `…${值}…`;等级用 if / else if / else;打印用 console.log() 三级 · 骨架:let chinese = 92; … / const name = '团子'; / let total = chinese + math + english; / let avg = total / ____; / \name的总分是{name}的总分是{},平均分是${}`/if (avg >= 90) { … } else if (avg >= ____) { … }`

    参考答案(做完再点开)
    //1. 三科成绩
    let chinese = 92;
    let math = 85;
    let english = 78;
    //2. 学生姓名(常量)
    const name = '团子';
    //3. 总分、平均分
    let total = chinese + math + english;
    let avg = total / 3;
    //4. 模板字符串输出
    console.log(`${name}的总分是${total},平均分是${avg}`);
    //5. 等级判断
    if (avg >= 90) {
    console.log('优秀');
    } else if (avg >= 80) {
    console.log('良好');
    } else if (avg >= 60) {
    console.log('及格');
    } else {
    console.log('不及格');
    }

    输出结果:团子的总分是255,平均分是85 和 良好;把 math 改成 55 后平均分变成 75,等级变成 及格——只改变量的值,逻辑一行不用改。 三个检查点:① avg 用的是 total / 3,不是整数除法(JS 除出来是小数,255 / 3 刚好是整数 85);② 等级判断的顺序必须是从高到低,否则 avg >= 60 写在前面会把 92 分也判成”及格”;③ 第 4 步的引号是反引号,写成单引号 ${} 会原样显示。

评论区

[ 标签 ]
# AI37# AI 编程2# AI工具1# AI绘图1# AI辅助开发2# Ajax7# Apifox1# AstrBot3# Astro2# CC Switch1# CDN2# Claude Code1# claudecode2# ClaudeCode1# Cloudflare2# CloudFlare2# CloudFlare-ImgBed3# coc4# CSS10# DeepSeek6# deepseek2# DELETE1# Docker5# EdgeOne3# Gist1# git1# GitHub1# hexo-circle-of-friends1# HTML9# HTTP10# ImageManager1# Java23# java13# JavaScript11# JavaWeb113# JDBC7# JSON2# JUnit1# LangChain25# Linux4# Logback1# Maven17# Muse Spark1# Mybatis1# MyBatis18# MySQL45# MySql1# NapCat1# Node.js1# obsidian2# Obsidian5# OpenCode4# ORM1# PathVariable1# PicGo1# PyCharm1# Python70# RequestBody1# RequestMapping1# RESTful风格1# skills1# Slf4j1# SpringBoot37# SpringMVC5# SQL2# Streamlit5# Svelte2# TailwindCSS1# Telegram3# Tlias2# Vercel1# vscode2# Vue20# Waline3# Web3# WebDAV1# Web基础6# Web开发6# WinSCP1# YAML1# 三层架构1# 中二宣言1# 书籍1# 使用文档10# 写作1# 函数2# 刷步数1# 前端52# 动态1# 动漫1# 包1# 单词2# 博客8# 博客工作流1# 博客开发2# 参数接收1# 友链1# 反思2# 后端48# 图床6# 地图1# 备份2# 大模型1# 奇思妙想1# 存储1# 学习方法6# 学校1# 宝塔面板3# 宝宝10# 实战4# 对象1# 导航栏1# 工具2# 布局2# 开发1# 开发工具1# 开发规范1# 开心1# 异常处理1# 影视2# 微信1# 性能优化2# 总结1# 想法15# 感受1# 感悟11# 指南1# 提示词工程2# 插件5# 故障排除1# 效率工具2# 教程10# 数据分析9# 数据库27# 数据结构1# 文件操作2# 斩神1# 日常95# 日志框架1# 朋友圈1# 朱元璋1# 模块1# 模板1# 正则表达式2# 测试3# 游戏2# 爬虫7# 生活迁移1# 电影2# 电脑1# 碎碎念1# 视觉识别1# 类1# 类型注解1# 网络基础2# 网络教室1# 羊毛2# 脚本2# 脚本工具1# 自动化2# 蓝奏云1# 表单1# 订阅推荐2# 记录2# 评论系统1# 词根1# 词缀1# 说说1# 足迹1# 跑步2# 路径参数1# 转载2# 运动1# 部署11# 部落冲突1# 配置1# 随机图1# 面向对象5# 音乐3# 音标1# 项目实战11# 饮食1# 驼峰命名1# 高德地图1
[ 公告 ]

如果你喜欢,那么欢迎来到我的世界!

了解更多
[ 音乐 ]
封面

音乐

暂未播放

0:000:00
暂无歌词
找不到相关结果。
[ contents ]
[ 全部文章 ]