前端学习8:JavaScript数据类型|声明变量|函数定义|函数参数|作用域(多个小练习上手)
前言:适合有基础的同学入门尝试 / 复习回忆。
一、数据类型:
1. Number 数字类型
let age = 25; // 整数
let price = 99.8; // 小数
let temp = -10; // 负数
let inf = Infinity; // 无穷大
2. String 字符串
let name = "张三";
let msg = '我是"前端"大佬'; // 单双引号可以嵌套
3. Boolean 布尔值
let isOnline = true; // 都是小写
let hasLogin = false;
4. null 空值
let empty = null; // 表示"无"的对象
5. undefined 未定义
let x; // 自动赋值为undefined
let y = undefined;
区别:null表示"空值",undefined表示"未赋值"
6. Symbol 唯一值 (ES6引入)
let id = Symbol("唯一标识");
用途:创建对象的唯一属性名,避免冲突
7. BigInt 大整数
let bigNum = 9007199254740991n; // 数字后加n
二、变量声明:
1. var - 已逐渐淘汰
var count = 10;
存在变量提升(hoisting)
没有块级作用域
可以重复声明
2. let - 推荐使用
let username = "前端";
块级作用域( {}内有效 )
不能重复声明
不存在变量提升
3. const - 常量声明
const PI = 3.1415926;
必须立即初始化
不能重新赋值
但对象属性可以修改
三、实操练习:
打开浏览器控制台(按F12)--控制台:
// 数字运算
let a = 10, b = 3;
console.log(a % b); // 取余运算// 字符串拼接
let str1 = "Hello", str2 = "World";
console.log(`${str1}, ${str2}!`);// 布尔逻辑
console.log(5 > 3 && 2 < 4);
// let的块级作用域
{let y = 10;var z = 20;
}
console.log(z); // 20
console.log(y); // 报错
四、函数定义:
1. 函数声明(最传统的方式)
// 特征:function关键字开头,有函数名
function greet(name) {return `Hello, ${name}!`;
}
console.log(greet("师父")); // 调用
存在函数提升(可以在声明前调用)
有自己的
this
和arguments
this
值取决于调用方式(动态绑定)可作为构造函数使用
new
实例化
2. 函数表达式(灵活的方式)
// 特征:赋值给变量的函数
const sayHi = function(name) {return `Hi, ${name}`;
};
console.log(sayHi("徒儿"));
不存在函数提升(必须先定义后调用)
可以是匿名函数
※3. 箭头函数(ES6现代写法)
// 特征:"=>" 箭头符号
const add = (a, b) => a + b;
console.log(add(2, 3)); // 5
更简洁(单行可省略
return
和{}
)没有自己的
this
(继承外层作用域)this
值继承自定义时的上下文(静态绑定)不能用作构造函数
- 无参数或多个参数必须带括号:
() => {}
或(a, b) => {}
。- 无
arguments
对象,需用 rest 参数替代:(...args) => args
- 不能使用
new
五、函数参数:
1. 默认参数(防止undefined)
function order(item = "🍔", count = 1) {return `下单:${item} x ${count}`;
}
console.log(order()); // 下单:🍔 x 1
2. 剩余参数(替代arguments)
function showSkills(name, ...skills) {console.log(`${name}的技能:`);skills.forEach(skill => console.log("- " + skill));
}
showSkills("张三", "JS", "CSS", "React");
变量和参数必须以一致的顺序出现。
3. 参数解构(直接拆解对象/数组)
// 对象解构
function login({ username, password }) {console.log(`用户:${username},密码:${password}`);
}
login({ username: "admin", password: "123" });// 数组解构
function getFirst([first]) {console.log(first);
}
getFirst(["A", "B", "C"]); // A
六、作用域:变量的生存空间
1. 全局作用域(最外层)
let globalVar = "我在哪都能用"; // 全局变量function checkScope() {console.log(globalVar); // 可以访问
}checkScope();
2. 函数作用域(var的领地)
function test() {var innerVar = "我在函数内生存";console.log(innerVar); // 正常
}
console.log(innerVar); // 报错!
3. 块级作用域(let/const的特性)
if (true) {let blockVar = "我只在这个{}内有效";const PI = 3.14;
}
console.log(blockVar); // 报错!
七、实操练习:
1.作用域练习:
let outer = "外层";function parent() {let middle = "中层";function child() {let inner = "内层";console.log(inner); // 内层console.log(middle); // 中层 ← 向上查找console.log(outer); // 外层 ← 继续向上}child();console.log(inner); // 报错!不能向下查找
}
parent();
2.三种函数定义对比:
// 1. 尝试在函数声明前调用它(观察提升现象)
hello();
function hello() { console.log("Hi!"); }// 2. 尝试对函数表达式做同样操作(会报错)
greet(); // 先注释掉这行继续
const greet = () => console.log("Hey!");
3.参数解构实战:
// 解析以下用户对象
const user = {id: 1,info: {name: "小明",address: { city: "北京" }}
};function printUser({ id, info: { name, address: { city } }}) {console.log(`${id}-${name}-${city}`);
}
printUser(user); // 应该输出什么?
※4.作用域迷宫:
let a = 1;
function test() {console.log(a); // 猜猜输出什么?let a = 2;
}
test();
5.分析下面的代码,输出什么?为什么?
function fn(a = 1, b = a + 1) {console.log(a + b);
}
fn(undefined, 3);
解答:
- 第一个参数
a
:传入undefined
,触发默认值a = 1
,因此a
的值为1
。 - 第二个参数
b
:传入值3
,因此b
的值为3
,不使用默认值a + 1
。
最终,a + b
等于 1 + 3 = 4
,所以 console.log(a + b)
输出 4
。