外观
JavaScript基础
JavaScript书写位置
JavaScript需要包含在HTML的script标签中,也可以通过script标签的src属性引入一个单独的js文件。
JavaScript的结束符
JavaScript的结束符为英文分号,若JavaScript的每一行只有一个语句,那么这个分号可以省略,但最好还是添加分号,因为某些情况下会报错(比如自执行函数)。
注释
JavaScript的注释和其他语言类似,分为块注释和行注释。块注释使用//,行注释用/* */。
// 行注释
/* 块注释 */输出
JavaScript的输出方式有以下几种:
- console.log,用于在控制台打印,不直接在页面中出现,需要在浏览器中打开开发者模式并转到控制台才能看到。
- document.write,直接在页面中打印,一般适合初学者输出表达式的值使用,不推荐用于开发环境中。
- alert,用于在浏览器中打开弹窗提示,用于提示用户信息。
JavaScript字面量
字面量是常量的一种,它的值就是字面意思的值。最常用的就是整数、浮点数、布尔值、字符串。
1 // 整数
1.2345 //浮点数
true // 布尔值
'Hello World' // 字符串声明变量和赋值
JavaScript使用let声明局部变量,使用const声明常量。let已经不再使用,推荐使用前两种关键字。
let a = 1; // 声明变量,可更改
a = 2; // 正确
const b = 'constant'; // 声明常量,不能更改
b = 'others'; // 错误运算符
JavaScript的运算符和其他语言很相似,可以进行加减乘除、字符串相加、使用括号扩大表达式优先级、比较大小与判断是否等于。
算术运算符
- 加法运算符(
+):用来求两个数值的和,或者连接两个字符串。 - 减法运算符(
-):用来计算两个数值之间的差值。 - 乘法运算符(
*):用来计算两个数值的乘积。 - 除法运算符(
/):用来计算两个数值相除的结果。 - 取余运算符(
%):用来计算两个数值相除的余数。
比较运算符
- 等于(
==):检查两个值是否相等,会进行类型转换。 - 全等于(
===):检查两个值是否相等,不进行类型转换,类型也必须相同。 - 不等于(
!=):检查两个值是否不相等,会进行类型转换。 - 不全等于(
!==):检查两个值是否不相等,不进行类型转换,类型也必须不同。 - 大于(
>):检查左侧值是否大于右侧值。 - 大于等于(
>=):检查左侧值是否大于或等于右侧值。 - 小于(
<):检查左侧值是否小于右侧值。 - 小于等于(
<=):检查左侧值是否小于或等于右侧值。
逻辑运算符
- 逻辑与(
&&):仅当两边的表达式都为真时,结果为真。 - 逻辑或(
||):两边的表达式有一个为真时,结果为真。 - 逻辑非(
!):将布尔值反转,true变为false,false变为true。
赋值运算符
- 基本赋值(
=):将右侧的值赋给左侧的变量。 - 加法赋值(
+=):将右侧值加上左侧变量的值,然后将结果赋给左侧的变量。 - 减法赋值(
-=):将左侧变量的值减去右侧的值,然后将结果赋给左侧的变量。 - 乘法赋值(
*=):将右侧值与左侧变量的值相乘,然后将结果赋给左侧的变量。 - 除法赋值(
/=):将左侧变量的值除以右侧的值,然后将结果赋给左侧的变量。
其他运算符
- 条件(三元)运算符(
? :):表达式条件 ? 表达式1 : 表达式2,如果条件为真,返回表达式1的结果,否则返回表表达式2的结果。 - 递增(
++):将数值增加1。 - 递减(
--):将数值减少1。 - 展开运算符(
...):用于数组或对象中,将数组元素或对象属性展开。 - 类型运算符(
typeof):返回变量或表达式的类型。
这里特别说一下展开运算符。
展开运算符(...)是ES6中引入的一项功能,可以在数组或对象字面量中使用,以表达式的形式将数组元素或对象属性"展开"。这个运算符非常灵活,可以用在多种场合,比如函数调用参数列表、数组字面量、对象字面量等。以下是一些常见的使用场景和示例:
数组中使用展开运算符
合并数组
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let mergedArr = [...arr1, ...arr2]; // 结果:[1, 2, 3, 4, 5, 6]复制数组
let arr = [1, 2, 3];
let arrCopy = [...arr]; // 结果:[1, 2, 3]将字符串转换为字符数组
let str = "hello";
let chars = [...str]; // 结果:['h', 'e', 'l', 'l', 'o']在函数调用时展开数组元素
function sum(x, y, z) {
return x + y + z;
}
let numbers = [1, 2, 3];
console.log(sum(...numbers)); // 结果:6对象中使用使用展开运算符
对象合并
let obj1 = { foo: 'bar', x: 42 };
let obj2 = { foo: 'baz', y: 13 };
let mergedObj = { ...obj1, ...obj2 };
// 结果:{ foo: "baz", x: 42, y: 13 }
// 注意:相同的属性名,后面的属性会覆盖前面的。复制对象
let obj = { foo: 'bar', x: 42 };
let objCopy = { ...obj }; // 结果:{ foo: "bar", x: 42 }添加或修改对象属性
let obj = { foo: 'bar', x: 42 };
let newObj = { ...obj, foo: 'baz', y: 13 }; // 结果:{ foo: "baz", x: 42, y: 13 }展开运算符提供了一种简洁的方式来扩展和构建数组或对象,使得代码更加清晰和易于理解。在处理复杂的数据结构时,这个运算符显得尤为有用。
基本类型
JavaScript是弱类型语言。
JS数据类型共有九个:Null、Number、Boolean、String、Object、Reference、List、Completion、Undefined。
Null表示空值,用于定义空的或不存在的引用,但是Null不等同于0或空字符串。Undefined表示未定义变量。
let let1;
document.write('let1的类型:' + let1 + '<br\>'); //undefined
let let2=null;
document.write('let2的类型:' + let2 + '<br\>'); //null布尔型和其他类型可以相互转换,非空或非0数字就是True。
字符串可以使用引号引起来定义,也可以使用newString('value')定义。
let let3='hello'+'world';字符串可以进行相加运算,结果等于两个字符串首尾连接。
document.write('let3的值:' + let3 + ', let3的长度:' + let3.length + '<br\>');使用字符串对象的length()方法可以获取字符串的长度。
使用以下四个方法可以转换字符串的大小写:s.toLocaleLowerCase()、s.toLowerCase()、toLocaleUpperCase()、toUpperCase()。
JS的数值类型Number,包含整数和小数,内部使用64位浮点数。
数组
- 创建数组 如我们像创建一个具有'张三' '李四' '王五'三个元素的数组
//第一种方式
let arr1 = new Array();
arr1[0] = '张三';
arr1[1] = '李四';
arr1[2] = '王五';
//第二种方式
let arr2 = new Array('张三', '李四', '王五');
//第三种方式
let arr3 = ['张三', '李四', '王五'];- 访问数组
//通过下标访问数组
for (item in arr1) {
document.write(item + ',');
};- 数组属性
length表示长度、prototype是所有JS对象的共有属性,通过原型可以给数组对象添加属性和方法,在创建方法后所有数组都可以使用此方法。
document.write('arr2的长度:' + arr2.length);- 数组方法
concat():连接两个或更多的数组
every() 检验数组的每个元素是否都符合条件
filter() 检测数值元素,并返回符合符合条件而定元素组成的数组
find() 返回符合传入测试(方法)的数组元素
findIndex() 返回符合传入测试(方法)的数组元素索引
forEach() 数组每一个元素都执行一次回调方法
indexOf() 搜索元素,并返回它所在的位置
join() 将数组的所有元素放入一个字符串中
lastIndexOf() 返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后往前搜索
map() 通过指定方法处理数组的每个元素,返回处理后的数组
pop() 删除数组的最后一个元素并返回处理后的数组
push() 在数组后面添加新的一个或多个元素并返回新的长度
reduce() 将数组计算为一个值(从左到右)
reduceRight() 将数组计算为一个值(从右到左)
reverse() 反转数组的元素顺序
slice() 选取数组的一部分并返回新的数组
some() 检测数组元素中是否有元素符合指定条件
sort() 排序
splice() 从数组中添加或删除元素
toString() 把数组转化为字符串,并返回
valueOf() 返回数组对象的原始值
流程控制 - if
JavaScript使用if、else两个关键字进行流程控制,与其他语言类似。
let flag = true;
let flag2 = false;
if (flag) {
console.log(1);
} else if (flag) {
console.log(2);
} else {
console.log(3);
}if内也能嵌套其他if,和其他语言类似。
JavaScript也支持三元运算符flag?a:b,在计算单个表达式的值时最常用,使用if则会显得很冗余。
let flag = true;
console.log(flag ? 'TRUE' : 'FALSE');流程控制 - switch
若条件选择过多,使用多个else if会让代码非常难看,这时就可以使用switch关键字达到多次判断的效果,使用方法和其他语言类似。
let el = 'el2';
switch el:
case 'el1':
console.log('el1');
case 'el2':
console.log('el2');
case 'el3':
console.log('el3');流程控制 - for和while
JavaScript的for关键字和while关键字和其他语言类似,都是进行循环控制。也可以使用continue进行下一次循环,或使用break跳出此循环。
let arr = ['el1', 'el2', 'el3'];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
let i = 0;
while (i < arr.length) {
console.log(arr[i]);
i++;
}let arr = ['el1', 'el2', 'break', 'el3'];
for (let i = 0; i < arr.length; i++) {
if (arr[i] == 'break'){
break;
} else {
console.log(arr[i]);
}
}JavaScript支持快速遍历列表或对象,若遍历对象则相当于遍历Object.keys()。结构是for (let el {in|of} arr),其中for、in、of是关键字,el是每次遍历后得到的元素,arr是列表或对象,in和of可以二选一。
let arr = ['el1', 'el2', 'el3'];
for (let el of arr) {
console.log(el);
}方法/函数
基础
JS定义方法的语法如下:
function func1(a, b) { //声明式方法定义
return a * b;
}
document.write('a * b = ' + func1(3, 4) + '<br\>');
let func2 = function (a, b) { //方法表达式定义
return a * b;
}
document.write('a * b = ' + func2(3, 4) + '<br\>');
let func3 = new Function('a', 'b', 'return a*b;');
document.write('a * b = ' + func3(3, 4) + '<br\>');运行结果:
a * b = 12
a * b = 12
a * b = 12方法的调用:
和其他编程语言类似,当方法在外部单独定义而没有用其他形式(如作为成员方法),直接调用即可。
function func4(a) {
return 'a = ' + a;
}
document.write(func4(3) + '<br\>'); //作为普通方法调用
let myObj = {
name: '张三',
age: 18,
getAge: function () {
return this.name + '是' + this.age + '岁';
}
};
document.write(myObj.getAge() + '<br\>'); //作为对象方法调用运行结果:
a = 3
张三是18岁若使用new关键字则是创建了一个对象:
function Person() {
this.name = '王五';
this.age = 20;
};
let person = new Person();
document.write(person.name + '的年龄是' + person.age + '<br\>'); //王五的年龄是20在JS中,方法也是对象,他有自己的属性和方法:
//call() 和 apply() 是预定义的方法方法,可用于调用方法,两个方法的第一个参数必须是方法本身
function myFunc(a, b) {
return a + b;
}
result = myFunc.call(null, 3, 4);
document.write(result + '<br\>'); //7
result = myFunc.apply(null, [3, 4]); //7
document.write(result + '<br\>');函数可以通过属性访问不定长参数。在函数内部作用域有一个伪数组arguments,通过访问它可以获取到函数被调用时传入的所有参数。
function func() {
console.log('函数的参数');
for (let i of arguments) {
console.log(arguments[i]);
}
}
func(1, 2, 3, 4, 5, 6)函数参数可以带一个...,代表它接受不定长度的参数,它在函数内部是一个数组,它一般放在函数参数列表的最后。
function func(a, b, ...c) {
console.log('函数的剩余参数');
for (let i of c) {
console.log(c[i]);
}
}
func(1, 2, 3, 4, 5, 6)箭头函数
箭头函数基本定义:(params) => { function_body }。
const func = () => {console.log(1)}
func();若箭头函数只有一个形参,可以省略小括号。
const func = x => { console.log(x); }
func(1);若箭头函数的函数体只有一个语句,可省略大括号。
const func = () => console.log(1);
func();只有一个return语句,则直接简化为return的具体内容。
const func = x => x + x;
console.log(func(1));普通函数的this指向的是调用者对象,箭头函数没有this语法,只会向上级传递。
内置方法
eval()将读取字符串并把它作为JS语句运行。
eval('document.write("我是eval()函数执行语句")' + '<br\>');isFinite()用于检验参数是否为无穷大。若参数是正负无穷大或非数字则返回false。
document.write('isFinite(NaN):' + isFinite(NaN) + '<br\>');isNaN()检验参数是否为非数字。
document.write('isNaN("a"):' + isNaN(123) + '<br\>');parseInt(value,radix)将字符串读取为对应的整数。radix是基数,可选。
document.write('parseInt("123"):' + parseInt('123') + '<br\>');parseFloat(value) 将字符串解析为浮点数。
document.write('parseFloat("123。456"):' + parseInt('123.456') + '<br\>');escape(string) 将字符串转换为编码。
document.write('escape("Hello"):' + escape('Hello') + '<br\>');unescape(string) 解码字符串。
特殊类型的函数
JavaScript除了使用function关键字定义的,具有名称,能调用的函数之外,还有其他类型的特殊类型的函数。
- 匿名函数
匿名函数就是不具有名称的函数,它一般作为作为回调函数使用。
let data = 1234;
function execute(data, func) {
func(data);
}
execute(data, function () {
console.log(data);
})- 箭头函数
箭头函数和匿名函数功能相同,定义是(params) => {function_body}
- 自执行函数
若页面的JS文件过多,有些JS文件中会重复定义一些变量,这些变量直接会引起混淆,因此就引入了一个自执行函数的概念。由于函数作用域的缘故,自执行函数内变量的作用域仅限于该函数,因此它们直接不会互相干扰。
(function (a, b) {
console.log(a, b);
})(123, 'str');