前端技术中对JavaScript语法的学习
JavaScript语法
变量及数据类型
变量
变量的定义有多种方式
1.使用var关键字
var
关键字用于在函数作用域或全局作用域中声明变量,这意味着使用var
声明的变量,其作用域为声明该变量的函数内部(如果是函数内部声明)或整个脚本(如果是在函数外部声明)。
2.使用let关键字
let
关键字用于在块级作用域中声明变量,这意味着let
声明的变量只在它所在的块或子块中可用(例如if
语句、for
循环或任何由大括号{}
包围的代码块)。
3.使用const关键字
const
关键字用于声明一个只读的常量,一旦声明,其值就不能被重新赋值。const
声明的变量也必须被初始化。与let
一样,const
也具有块级作用域。
注意事项
- 尽量避免在全局作用域中使用
var
,因为它会导致变量提升(hoisting),这可能会使得代码的行为难以预测。 - 使用
let
和const
可以提供更好的作用域控制和代码封装,推荐在ES6及更新版本的JavaScript中使用它们来声明变量。 - 尽管
const
声明的变量不能重新赋值,但如果变量是一个对象或数组,则可以修改对象或数组内部的属性或元素。
数据类型
基本数据类型
- Undefined:当变量被声明但未被赋值时,它的值是
undefined
。 - Null:
null
是一个表示“无”或“空”的原始值。它通常用于表示尚未赋值的对象变量。 - Boolean:布尔类型,只有两个值:
true
和false
。 - Number:数字类型,包括整数和浮点数。JavaScript 中的所有数字都是以 64 位浮点数形式存储的,即使是整数。
- String:字符串类型,用于表示文本数据。在 JavaScript 中,字符串是不可变的,即一旦创建,就不能更改字符串中的字符。
- BigInt(ES2020 引入):提供了一种方法来表示大于
2^53 - 1
的整数。BigInt 是一种内置对象,不是原始数据类型,但在这里与原始数据类型一起提及,因为它提供了一种新的数字表示方式。 - Symbol(ES6 引入):用于创建唯一的标识符。Symbol 是一种原始数据类型,但它与其他原始类型不同,因为它是一个对象实例的包装器。
引用数据类型
- Object:JavaScript 中的通用对象类型,用于存储键值对集合。
- Array:数组是特殊的对象,用于存储有序的元素集合。
- Function:函数是 JavaScript 中的一等公民,可以像任何其他值一样被传递、赋值、引用等。函数对象封装了可执行的代码。
运算符和操作符
常用运算符和操作符
JavaScript 算术运算符
与/或值之间的算术运算。
y=5,下面的表格解释了这些算术运算符:
运算符 | 描述 | 例子 | x 运算结果 | y 运算结果 | 在线实例 |
---|---|---|---|---|---|
+ | 加法 | x=y+2 | 7 | 5 | 实例 » |
- | 减法 | x=y-2 | 3 | 5 | 实例 » |
* | 乘法 | x=y*2 | 10 | 5 | 实例 » |
/ | 除法 | x=y/2 | 2.5 | 5 | 实例 » |
% | 取模(余数) | x=y%2 | 1 | 5 | 实例 » |
++ | 自增 | x=++y | 6 | 6 | 实例 » |
x=y++ | 5 | 6 | 实例 » | ||
-- | 自减 | x=--y | 4 | 4 | 实例 » |
x=y-- | 5 | 4 | 实例 » |
JavaScript 赋值运算符
赋值运算符用于给 JavaScript 变量赋值。
给定 x=10 和 y=5,下面的表格解释了赋值运算符:
运算符 | 例子 | 等同于 | 运算结果 | 在线实例 |
---|---|---|---|---|
= | x=y | x=5 | 实例 » | |
+= | x+=y | x=x+y | x=15 | 实例 » |
-= | x-=y | x=x-y | x=5 | 实例 » |
*= | x*=y | x=x*y | x=50 | 实例 » |
/= | x/=y | x=x/y | x=2 | 实例 » |
%= | x%=y | x=x%y | x=0 | 实例 » |
JavaScript关系比较运算符
运算符 | 描述 | 示例 |
---|---|---|
> |
大于 | 5 > 3 // true |
< |
小于 | 3 < 5 // true |
>= |
大于等于 | 5 >= 5 // true |
<= |
小于等于 | 3 <= 3 // true |
操作符的常用方式
数据类型隐式转换
1.字符串和数字之间的转换
-
字符串到数字的转换:在算术运算中,如果字符串包含有效的数字序列,则JavaScript会尝试将该字符串转换为数字。如果字符串不能转换为数字(如包含非数字字符),则结果为
NaN
。console.log("10" + 2); // "102"(字符串连接) console.log("10" - 2); // 8(字符串转换为数字) console.log("hello" * 2); // NaN(无法转换为数字)
-
数字到字符串的转换:在需要字符串的上下文中(如使用
+
运算符进行字符串连接时),数字会被转换为字符串。javascript复制代码 console.log(10 + " pixels"); // "10 pixels"
- 布尔值到数字的转换
-
在需要数字的上下文中,
true
会被转换为1
,而false
会被转换为0
。console.log(3 * true); // 3 console.log(3 * false); // 0
- 对象到原始值的转换
-
对象在需要原始值(如数字、字符串或布尔值)的上下文中会被转换为原始值。这通常通过调用对象的
valueOf()
和toString()
方法来实现,具体取决于上下文。let obj = { valueOf: function() { return 10; }, toString: function() { return "obj"; } }; console.log(+obj); // 10(调用valueOf()) console.log(`${obj}`); // "obj"(调用toString())
- 比较操作中的转换
-
在比较操作中,如果操作数的类型不同,JavaScript会尝试将它们转换为相同的类型,然后再进行比较。
console.log(0 == "0"); // true(数字转换为字符串或字符串转换为数字) console.log(0 === "0"); // false(严格比较,不转换类型)
数组和对象的字面量的定义方法
数组:数组的字面量定义是通过方括号[]
包围一系列的值(元素)来实现的,元素之间用逗号,
分隔。数组可以包含任意类型的值,包括数字、字符串、布尔值、对象、数组(即数组可以嵌套)等。
对象:对象的字面量定义是通过花括号{}
包围一系列的键值对来实现的,每个键值对之间用逗号,
分隔。键(也称为属性名)通常是字符串(但也可以是Symbol),而值可以是任意类型,包括数字、字符串、布尔值、对象、数组等。
条件判断和循环语句
条件判断
if语句
if (*condition*)
{
*当条件为 true 时执行的代码*
}
if (condition)
{
当条件为 true 时执行的代码
}
else
{
当条件不为 true 时执行的代码
}
if (condition1)
{
当条件 1 为 true 时执行的代码
}
else if (condition2)
{
当条件 2 为 true 时执行的代码
}
else
{
当条件 1 和 条件 2 都不为 true 时执行的代码
}
switch...case...
switch(n)
{
case 1:
执行代码块 1
break;
case 2:
执行代码块 2
break;
default:
与 case 1 和 case 2 不同时执行的代码
}
循环语句
for循环
for (语句 1; 语句 2; 语句 3)
{
被执行的代码块
}
var person={fname:"Bill",lname:"Gates",age:56};
for (x in person) // x 为属性名
{
txt=txt + person[x];
}
while循环
while (条件)
{
需要执行的代码
}
do...while循环
do
{
需要执行的代码
}
while (条件);
函数
变量与变量的作用域
局部变量
局部变量是在函数内部或代码块(如if
、for
、while
等控制结构)中声明的变量。局部变量的作用域限制在其被声明的函数或代码块内部。一旦离开这个作用域,该变量就不能被访问了。局部变量有助于减少命名冲突,并提高代码的可读性和可维护性。
声明局部变量:
function myFunction() {
var localVar = "我是一个局部变量";
console.log(localVar); // 正确:在函数内部可以访问
}
console.log(localVar); // 错误:localVar 在此处不可见,因为它是一个局部变量
全局变量
全局变量是在函数外部声明的变量,或在函数内部但没有使用var
、let
或const
关键字声明的变量(这种做法通常不推荐,因为它可能导致意外的命名冲突)。全局变量的作用域是整个脚本,即在整个脚本的任何地方都可以访问和修改它。
声明全局变量:
var globalVar = "我是一个全局变量";
function anotherFunction() {
console.log(globalVar); // 正确:在函数内部可以访问全局变量
}
console.log(globalVar); // 正确:在全局作用域中可以访问
注意:在ES6(ECMAScript 2015)及以后的版本中,推荐使用let
和const
来声明变量,因为它们提供了块级作用域(block scope),有助于减少全局命名冲突,并提高代码的安全性。var
仍然被支持,但新的开发应尽量避免使用。
使用let
和const
的例子:
function exampleFunction() {
let blockScopedVar = "我仅在函数内的这个块中可见";
console.log(blockScopedVar); // 正确
{
let anotherBlockScopedVar = "我仅在这个更小的块中可见";
console.log(anotherBlockScopedVar); // 正确
}
// console.log(anotherBlockScopedVar); // 错误:超出作用域
}
const PI = 3.14; // 全局常量,但通常推荐在模块级别或函数级别声明常量
变量的作用域
全局作用域中的变量可以在代码的任何地方被访问,包括函数内部。在全局作用域中声明的变量会成为全局对象(在浏览器中是window
对象)的属性。
局部作用域或函数作用域中的变量只能在函数内部被访问。每次函数被调用时,都会创建一个新的作用域,这个作用域中声明的变量只在该次函数调用期间存在。
作用域链
当JavaScript引擎需要查找一个变量时,它会从当前执行的作用域开始查找。如果当前作用域中没有找到该变量,引擎会继续向上查找父级作用域,直到找到全局作用域。这个逐级向上查找的过程就构成了作用域链。
作用域链的顶端是全局作用域,底部是当前执行的作用域。在函数执行时,会创建一个新的作用域(称为执行上下文或活动对象),并将其添加到作用域链的底部。如果函数内部还调用了其他函数,那么这些内部函数也会有自己的作用域,并且它们的作用域链会包含外部函数的作用域。
示例
var globalVar = "全局变量";
function outerFunction() {
var outerVar = "外部函数变量";
function innerFunction() {
var innerVar = "内部函数变量";
console.log(innerVar); // 查找当前作用域 -> 内部函数变量
console.log(outerVar); // 查找当前作用域未找到,继续向上查找 -> 外部函数变量
console.log(globalVar); // 继续向上查找 -> 全局变量
// 尝试访问不存在的变量会导致ReferenceError
// console.log(nonExistentVar); // ReferenceError: nonExistentVar is not defined
}
innerFunction();
}
outerFunction();
在这个例子中,innerFunction
的作用域链包含了它自己的作用域、outerFunction
的作用域以及全局作用域。当innerFunction
尝试访问一个变量时,它首先在自己的作用域中查找,如果找不到,则继续在其父作用域(outerFunction
的作用域)中查找,如果还找不到,则继续在全局作用域中查找。如果最终在所有作用域中都找不到该变量,则会抛出一个ReferenceError
。
函数的声明与使用
函数的定义
函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。
声明函数的语法
function functionname()
{
// 执行代码
}
函数调用
当调用该函数时,会执行函数内的代码。
可以在某事件发生时直接调用函数(比如当用户点击按钮时),并且可由 JavaScript 在任何位置进行调用。
带参数的函数
function myFunction(var1,var2)
{
代码
}
不定参数-arguments
function sum() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
console.log(sum(1, 2, 3)); // 输出: 6
// 使用 Array.from 或 ... 扩展运算符将 arguments 转换为数组
function sumWithArray() {
const argsArray = Array.from(arguments);
// 或者使用 ES6 的剩余参数语法: const [...argsArray] = arguments; 但实际上应直接使用剩余参数
let total = 0;
argsArray.forEach(num => total += num);
return total;
}
console.log(sumWithArray(1, 2, 3, 4)); // 输出: 10
// 更好的方式是使用 ES6 的剩余参数
function sumES6(...numbers) {
let total = 0;
numbers.forEach(num => total += num);
return total;
}
console.log(sumES6(1, 2, 3, 4, 5)); // 输出: 15
数组
创建数组
new Array()
var myCars=new Array();
myCars[0]="Saab";
myCars[1]="Volvo";
myCars[2]="BMW";
字面量的创建
遍历数组
for
let arr = [1, 2, 3, 4, 5];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
forEach
let arr = [1, 2, 3, 4, 5];
arr.forEach(function(element) {
console.log(element);
});
// 使用箭头函数
arr.forEach(element => console.log(element));
for ...in...
for (x in person) // x 为属性名
{
txt=txt + person[x];
}
数组中常用的方法
-
push()
:在数组的末尾添加一个或多个元素,并返回新的长度。 -
unshift()
:在数组的开头添加一个或更多元素,并返回新的长度。 -
shift()
:删除并返回数组的第一个元素。 -
pop()
:删除并返回数组的最后一个元素。 -
sort()
:对数组的元素进行排序,并返回数组。排序可以是数字或字符串。 -
reverse()
:颠倒数组中元素的顺序,返回颠倒后的数组。 -
join()
:把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。 -
slice()
:返回一个新的数组对象,这一对象是一个由begin
到end
(不包括end
)选择的数组的部分浅拷贝。原始数组不会被修改。 -
splice()
:通过删除现有元素和/或添加新元素来更改一个数组的内容。 -
concat()
:用于合并两个或多个数组。此方法不会改变现有的数组,而仅仅会返回被合并数组的一个副本。 -
length()
:用于求数组长度。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏