JavaScript 快速从入门

一. 基础篇

1. 快速入门

  • 创建Html页面。
<!DOCTYPE html>
<html>
  <head>
      <meta charset="utf-8">
      <title>JS快速入门</title>
  </head>
  <body>
      <h1 class="wrap"></h1>
  </body>
</html>
  • 引入js
    • 引入js的方式有两种:内联定义和外部引入
    • 内联定义
      • 通过在网页上的一对script标签定义JavaScript代码片段。
      • 在Html页面的body标签之后编写JavaScript代码片段。
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>JS快速入门</title>
    </head>
    <body>
        <h1 class="wrap"></h1>
    </body>
    
    <script type="text/javascript">
        var div = document.querySelector(".wrap"); //通过class选择器获取对应的标签,
        div.innerHTML = 'Hello JavaScript!';//给对应的标签设置内容
    </script>
</html>
    • 外部引入
      • 在项目中创建js目录,在其中创建quickstart.js,文件内容如下:
var div = document.querySelector(".wrap"); //通过class选择器获取对应的标签,
div.innerHTML = 'Hello JavaScript!';//给对应的标签设置内容
      • 在Html页面的body标签之后使用以下方式引入外部的js文件
<!DOCTYPE html>
<html>
  <head>
      <meta charset="utf-8">
      <title>JS快速入门</title>
  
  </head>
  <body>
      <h1 class="wrap"></h1>
  </body>
  
  <script type="text/javascript" charset="UTF-8" src="js/quickstart.js"></script>
</html>
  • 通过浏览器查看效果

无论是内联定义还是外部引入,script标签书写的位置很重要,一般来说,需要确保放到你要操作的标签后边

2. 基础语法

  • JavaScript是区分大小写的
var age = 34;
var Age = 12;
// 这是两个单独的变量,互不影响
console.log(age == Age);  //浏览器打印台打印 false
  • 代码最后的分号不是必须的

如果一条语句独占一行的话,那么分号是可以省略的(不建议这样做)。但如果一行中有多条语句,那么这些语句必须以分号隔开。

// 一行一条语句的话,分号可以省略,但不建议这样做
var age = 34
console.log(age)
var sname = '张三'; console.log(sname);  // 分号不可省略

在一条语句的末尾加上分号是一个很好的习惯。这个习惯可以大大减少代码中产生 bug 的可能性。

  • 字符串不区分单双引号
var name = "张三";
var address = '郑州';
console.log(address+name);
  • 注释

JavaScript的注释方式和Java类似。

// 单行注释
/*
  这是一个,
  多行注释
 */

/* 然而, 你不能, /* 嵌套注释 */ 语法错误 */

2.1 输入和输出

2.1.1 输入
// 使用prompt()方法显示一个对话框,提示用户输入年龄
// prompt()方法会返回用户输入的值
let a = prompt('请输入你的年龄!');
// 输入:用户在弹出的对话框中输入年龄

// 注意:prompt()接收的是字符串类型
// 即使用户输入的是数字,a 的值也是字符串类型

// 使用alert()方法显示一个警告对话框,显示用户输入的年龄
alert(a);
// 输出:在浏览器中弹出一个警告框,显示用户输入的年龄

// 注意:如果用户点击了"取消"按钮或关闭了prompt对话框而不输入,
// a 的值将会是 null,此时 alert(a) 将显示 "null"
2.1.1 输出

注意:

  1. document.write() 的结果直接显示在浏览器页面上。
  2. alert() 的结果显示在浏览器的弹出警告框中。
  3. console.log() 的结果显示在浏览器的开发者工具控制台中,通常需要打开开发者工具才能看到
//输出
// 使用document.write()方法将文本直接写入HTML文档
document.write('输出到浏览器页面显示');
// 返回结果:在浏览器页面上显示文本 "输出到浏览器页面显示"

// 使用document.write()方法将HTML标签写入文档
document.write('<h1>我是标签</h1>');
// 返回结果:在浏览器页面上显示一个一级标题 "我是标签"

// 使用alert()方法显示一个警告对话框
alert('弹出警示框');
// 返回结果:在浏览器中弹出一个警告框,显示文本 "弹出警示框"

// 使用console.log()方法将信息输出到浏览器的控制台
console.log('输出到控制台');
// 返回结果:在浏览器的开发者工具控制台中显示文本 "输出到控制台

2.2 ES6新增--字符串拼接的两种方式

  1. 第一种方式使用 '+' 运算符进行字符串拼接。这是传统的JavaScript字符串拼接方法。
  2. 第二种方式使用ES6引入的模板字符串。它使用反引号(`)包裹整个字符串,并使用 ${} 来嵌入变量或表达式。

模板字符串的优点

  • 可读性更强,特别是在处理多行字符串时。
  • 不需要使用 '+' 进行拼接,代码更简洁。
  • 可以直接在 ${} 中插入复杂的表达式,而不仅仅是变量。
// 定义一个变量 age 并赋值为 18
let age = 18;

// 第一种字符串拼接方式:使用 + 号
document.write('我今年' + age + '岁了');
// 输出:在浏览器页面上显示文本 "我今年18岁了"

// 第二种字符串拼接方式:使用模板字符串(Template Literals)
// 注意使用反引号`,不是单引号'和双引号"
// 变量使用 ${} 包裹
document.write(`我今年${age}岁了`);
// 输出:在浏览器页面上显示文本 "我今年18岁了"

// 注意:两种方式的输出结果相同,但第二种方式(模板字符串)更简洁易读

3. 变量、基本数据类型

3.1. 变量命名规范

JavaScript中变量的命名规范和Java类似,一个 JavaScript 标识符必须以字母、下划线(_)或者美元符号($)开头;后续的字符也可以是数字(0-9)。因为 JavaScript 语言是区分大小写的,所以字母可以是从“A”到“Z”的大写字母和从“a”到“z”的小写字母。

3.2. 声明方式

JavaScript有三种声明方式。

  • var

声明一个变量,可选初始化一个值,全局变量。

  • let (ECMA6新增)

声明一个块作用域的局部变量,可选初始化一个值。

  • const (ECMA6新增)

声明一个块作用域的只读常量,不能更改

<script type="text/javascript">
        //1. var定义全局变量
        if(true){ //在JS中两个{}包裹的区域称之为块作用域,一般块作用域中的变量都是局部变量,不会是全局变量,从而避免影响
            var $name="张三";
        }
        console.log($name);
        
        //2. let定义局部变量,只能在定义的块作用域中使用,不能在块作用域之外使用
        if(true){
            let _age=30;
        }
        //console.log(_age);
        
        //3. const定义只读常量,如果没有明确块作用域,那这时块作用域就是全局
        const ADDRESS="河南郑州";
        ADDRESS="郑州";
        console.log(ADDRESS);
</script>

3.3. 全局变量

全局变量是全局对象的属性。在网页中,(译注:缺省的)全局对象是 window ,所以你可以用形如 window.variable 的语法来设置和访问全局变量。

//1. 全局变量,是全局对象的属性,全局对象:window
var name="李四";
console.log(name);
console.log(window.name);
        
//2. 局部变量,局部变量只是局部块作用域对象的属性
if(true){
    let sex="男";
    console.log(window.sex); //undefined
}
let age=30;
console.log(window.age);//undefined

3.4. 常量

你可以用关键字 const 创建一个只读的常量。常量标识符的命名规则和变量相同:必须以字母、下划线(_)或美元符号($)开头并可以包含有字母、数字或下划线。

注意:常量不能更改。

const PI=3.14;
PI=3.1415;
console.log(PI);//Uncaught TypeError: Assignment to constant variable.

常量的作用域和let类似,也就意味着即便你在函数之外定义的常量,也不会被绑定到全局对象window上

3.5. 数据类型

  • 布尔类型 (Boolean)
    • 和Java中类似,JS中的Boolean类型也有两个值:truefalse
  • 数字 (Number)
    • 在JS中整数和浮点数都是同一个类型,Number。例如:42、3.1415926
    • NaN(Not-a-Number)是一个特殊的数值类型,属于 Number 类型。它表示一个未定义或不可表示的数值结果。NaN运算最后都是NaN
  • 字符串 (String)
    • JS中字符串类型和Java语言类似,不同的是JS中不区分单引号和双引号
// 下面两行代码等同
var sname = '张三';  
var sname = "张三";

我们可以利用这一点很方便的完成单双引号的嵌套。

  • 空值 (Null)
    • 一个表明 null 值的特殊关键字。 JavaScript 是大小写敏感的,因此 nullNullNULL或变体完全不同。
  • 未定义 (undefined)
    • 和 null 一样是一个特殊的关键字,undefined 表示变量未定义时的属性。
  • 任意精度的大整数 (BigInt)
    • 可以安全地存储和操作大整数,甚至可以超过数字的安全整数限制。
NaN

NaN属于 Number 类型。它表示一个未定义或不可表示的数值结果。NaN运算最后都是NaN

  1. 任何涉及 NaN 的算术运算都会返回 NaN:
console.log(NaN + 1);  // 输出: NaN
console.log(NaN - 1);  // 输出: NaN
console.log(NaN * 2);  // 输出: NaN
console.log(NaN / 2);  // 输出: NaN
  1. NaN 与任何值比较都返回 false,包括它自己:
console.log(NaN == NaN);   // 输出: false
console.log(NaN === NaN);  // 输出: false
console.log(NaN < 1);      // 输出: false
console.log(NaN > 1);      // 输出: false
console.log(NaN <= 1);     // 输出: false
console.log(NaN >= 1);     // 输出: false
  1. 检测 NaN 的方法:
console.log(isNaN(NaN));  // 输出: true
console.log(Number.isNaN(NaN));  // 输出: true (ES6方法,更精确)
// 注意 isNaN 和 Number.isNaN 的区别
console.log(isNaN("hello"));  // 输出: true (因为 "hello" 不能被转换为数字)
console.log(Number.isNaN("hello"));  // 输出: false (因为 "hello" 不是 NaN)
  1. 一些会产生 NaN 的操作:
console.log(0 / 0);  // 输出: NaN
console.log(Math.sqrt(-1));  // 输出: NaN
console.log(parseInt("hello"));  // 输出: NaN
  1. NaN 在逻辑运算中被视为 falsy 值:
console.log(NaN && "test");  // 输出: NaN
console.log(NaN || "test");  // 输出: "test"
console.log(!NaN);  // 输出: true

3.6. 数据类型的转换

JavaScript是一种动态类型语言(dynamically typed language)。这意味着你在声明变量时可以不必指定数据类型,而数据类型会在代码执行时会根据需要自动转换。因此,你可以按照如下方式来定义变量:

var answer = 42;
// 因为 JavaScript 是动态类型的,这种赋值方式并不会提示出错。
answer = "Thanks for all the fish...";  
// 数值类型转成字符串
var i = 8;
var str_i = i+"1";
console.log(str_i); // 81
// 注意: 只有 + 号运算符可以将数字转成字符串,而 - 号运算符则不可以
var j = i-"2";
console.log(j);//6
    
// 字符串类型转成数字
var str_pi = "3.14";
var int_pi = parseInt(str_pi); 
console.log(int_pi);// 3
var float_pi = parseFloat(str_pi);  
console.log(float_pi);// 3.14
3.6.1 隐式转换
  1. + 号两边只要有一个是字符串,都会把另外一个转成字符串
  2. 除了+以外的算术运算符 比如 - * / 等都会把数据转成数字型
  3. +号作为正号解析可以转换成数字类型
  4. 任何数据和字符串相加结果都是字符串
  5. 空字符串转换为0,null转换为0,undefined转换为NaN
console.log(1 + 1)       // 2 (number)
console.log('1' + 1)     // "11" (string)
console.log('1' - 1)     // 0 (number)
console.log('1' * 1)     // 1 (number)
console.log('1' / 1)     // 1 (number)
console.log('1' % 1)     // 0 (number)
console.log(typeof '123')  // "string"
console.log(typeof +'213')  // "number"
console.log(+'123')    // 123 (number)
console.log(+'123' + '123')  // "123123" (string)
console.log(+'123' + 123)    // 246 (number)
3.6.2 显示转换
//2.1Number
console.log(Number('123'))  // 123 (number)
console.log(Number('abc'))  // NaN (number)

//2.2parseInt保留整数
console.log(parseInt('3.14'))  // 3 (number)

//2.3parseFloat保留小数
console.log(parseFloat('3.14'))  // 3.14 (number)

4. 运算符

4.1. 赋值运算符

名字

简写的操作符

含义

赋值(Assignment)

x = y

x = y

加法赋值(Addition assignment)

x += y

x = x + y

减法赋值(Subtraction assignment)

x -= y

x = x - y

乘法赋值(Multiplication assignment)

x *= y

x = x * y

除法赋值(Division assignment)

x /= y

x = x / y

求余赋值(Remainder assignment)

x %= y

x = x % y

求幂赋值(Exponentiation assignment)(求次方赋值)

x **= y

x = x ** y

左移位赋值(Left shift assignment)

x <<= y

x = x << y

右移位赋值(Right shift assignment)

x >>= y

x = x >> y

无符号右移位赋值(Unsigned right shift assignment)

x >>>= y

x = x >>> y

按位与赋值(Bitwise AND assignment)

x &= y

x = x & y

按位异或赋值(Bitwise XOR assignment)

x ^= y

x = x ^ y

按位或赋值(Bitwise OR assignment)

`x

= y`

4.2. 比较运算符

运算符

描述

返回true的示例

等于 Equal (==)

如果两边操作数相等时返回true。

3 == var1 "3" == var1 3 == '3'

不等于 Not equal (!=)

如果两边操作数不相等时返回true

var1 != 4 var2 != "3"

全等 Strict equal (===)

两边操作数相等且类型相同时返回true。 参见 Object.is and sameness in JS.

3 === var1

不全等 Strict not equal (!==)

两边操作数不相等或类型不同时返回true。

var1 !== "3" 3 !== '3'

大于 Greater than (>)

左边的操作数大于右边的操作数返回true

var2 > var1 "12" > 2

大于等于 Greater than or equal (>=)

左边的操作数大于或等于右边的操作数返回true

var2 >= var1 4 >= 3

小于 Less than (<)

左边的操作数小于右边的操作数返回true

var1 < var2 "2" < 12

小于等于 Less than or equal (<=)

左边的操作数小于或等于右边的操作数返回true

var1 <= var2 2 <= 5

4.3. 算术运算符

运算符

描述

示例

求余(%)

二元运算符. 返回相除之后的余数.

12 % 5 返回 2。

自增(++)

一元运算符. 将操作数的值加一. 如果放在操作数前面 (++x), 则返回加一后的值; 如果放在操作数后面 (x++), 则返回操作数原值,然后再将操作数加一.

var x=3;console.log(++x); //4console.log(x); //4var y=3;console.log(y++); //3console.log(y); //4

自减 (--)

一元运算符. 将操作数的值减一. 前后缀两种用法的返回值类似自增运算符.

var x=3; console.log(--x); //输入2,x=2var y=3;console.log(y--);//输出3,x=2;

一元负值符(-)

一元运算符,返回操作数的负值.

var x=3; console.log(-x); //输入-3

一元正值符 (+)

一元运算符,返回操作数,如果操作数在之前不是number,将其转换为number

console.log( +'3' ); // 3console.log( '3' ); // '3'console.log(+true); // 1

指数运算符(**)

计算 base(底数) 的 exponent(指数)次方, 表示为baseexponent

2 ** 3 returns 8. 10 ** -1 returns 0.1.

4.4. 逻辑运算符

运算符

范例

描述

逻辑与

(&&)

expr1 && expr2

(逻辑与) 如果expr1能被转换为false,那么返回expr1;否则,返回expr2。因此,&&用于布尔值时,当操作数都为true时返回true;否则返回false.

逻辑或

(||)

expr1 || expr2

(逻辑或) 如果expr1能被转换为true,那么返回expr1;否则,返回expr2。因此,||用于布尔值时,当任何一个操作数为true则返回true;如果操作数都是false则返回false。

逻辑非

(!)

!expr

(逻辑非) 如果操作数能够转换为true则返回false;否则返回true。

能被转换为false的值有null, 0, NaN, 空字符串("")和undefined

4.5. 条件(三目)运算符

和Java中类似,JavaScript中也提供了条件分支的三目运算符

// 当条件为真时,aa = 值1,否则 aa = 值2
var aa = 条件 ? 值1 : 值2;

4.6. delete操作符

delete操作符,删除一个对象或一个对象的属性或者一个数组中某一个键值。语法如下:

delete objectName; //删除对象
delete objectName.property;//删除对象属性
delete objectName[index];//删除数组中对应下标的元素

objectName是一个对象名,property 是一个已经存在的属性,index是数组中的一个已经存在的键值的索引值。

删除数组中的元素时,数组的长度是不变的,例如删除a[3], a[4]a[4]和a[3] 仍然存在的,但是值变成了undefined

4.7. typeof运算符

typeof操作符返回一个表示operand类型的字符串值。operand可为字符串、变量、关键词或对象,其类型将被返回。

var myFun = new Function("5 + 2"); //构建一个函数(方法)对象
        var shape = "round";
        var size = 1;
        var today = new Date(); //构建一个日期对象
        console.log(today);
        console.log(today.getFullYear()); //获取年
        console.log(today.getMonth()+1); //获取月  0-11
        console.log(today.getDay()); //获取周的某一天 0-6  0周日
        console.log(today.getDate()); //获取日
        console.log(today.getHours()); //获取时  HH:mm:ss
        console.log(today.getMinutes()); //获取分
        console.log(today.getSeconds()); //获取秒
        console.log(today.getMilliseconds()); //获取毫秒
        
        console.log(typeof myFun); // "function"
        console.log(typeof shape); // "string"
        console.log(typeof size);  // "number"
        console.log(typeof today); // "object"
        
        console.log("-------------------");
        
        console.log(typeof true); // "boolean"
        console.log(typeof null); // "object"
        
        console.log("-------------------");
        
        // 对于预定义对象, typeof将返回如下结果:
        console.log(typeof Date);     // returns "function"
        console.log(typeof Function); // returns "function"
        console.log(typeof Math);     // returns "object"
        console.log(typeof Option);   // returns "function"
        console.log(typeof String);   // returns "function"
        
        console.log("-------------------");
        
        var random = Math.random();  //获取[0,1)随机小数
        console.log(Math.floor(random*101)); // random: 0-0.99   (0-100)  (max-min+1)+min  (100-0+1)+0

4.8. instanceof运算符

判断对应的对象是否是指定的对象类型,如果是则返回true,不是则返回false,其语法如下:

objectName instanceof objectType

objectName 是需要做判别的对象的名称,而objectType是假定的对象的类型, 例如DateArray

使用示例:

var x = 1;
console.log(x instanceof Number); // false
var x = new Number(1);
console.log(x instanceof Number); //true

4.9. in运算符

in操作符,如果所指定的属性确实存在于所指定的对象中,则会返回true,语法如下:

propNameOrNumber in objectName

在这里 propNameOrNumber可以是一个属性名的字符串或者是一个数组索引的数值表达式,而objectName则是一个对象名。

示例:

// 属性名 in 对象名   索引 in 数组
var nums = ["Java", "PHP", "Python", "JavaScript", "C++"];
console.log(0 in nums); //true  判断0索引是否在nums数组中,在true,不在false
console.log(1 in nums);
console.log(5 in nums);
console.log("JavaScript" in nums); //此种写法不会报错,但是返回的是false
console.log("length" in nums); //true  判断length属性是否在nums数组对象中,在true,不在false
        
console.log("---------------------------------");
console.log("PI" in Math); //true  判断PI属性是否在Math预定义对象中,在true,不在false
var myString = new String("coral");
console.log("length" in myString);  // returns true
        
console.log("---------------------------------");
var mycar = {make: "本田", model: "雅阁", year: 1998}; //js中 {key:value}都表示对象,key称之为对象的属性
console.log("make" in mycar); // returns true
console.log("model" in mycar); // returns true

注意:in不能实现判断数据是否在数组或对象中。

4.10. void运算符

void运算符,表明一个运算没有返回值。expression是javaScript表达式,括号中的表达式是一个可选项。

你可以使用void运算符指明一个超文本链接。该表达式是有效的,但是并不会在当前文档中进行加载。

语法:

void (expression)
void expression

示例:

<a href="javascript:void(0)">点击不做任何操作</a>
// 示例1:使用 void 0 代替 undefined
let result = void 0;
console.log(result);
// 返回结果:undefined(输出到控制台)

// 示例2:使用 void 运算符执行表达式但不返回值
function sayHello() {
    console.log("Hello!");
}
let output = void sayHello();//没有返回结果
console.log(output);
// 返回结果:
// Hello!(输出到控制台)
// undefined(输出到控制台)

// 示例3:在超链接中使用 void
// HTML: <a href="javascript:void(alert('点击了链接'))">点击我</a>
// 当点击链接时,会显示警告框,但页面不会跳转
// 返回结果:弹出警告框显示 "点击了链接",但 href 不执行任何跳转

// 示例4:防止默认行为
// HTML: <a href="javascript:void(0)" onclick="console.log('点击了链接')">点击我</a>
// 点击链接时,不会发生默认的跳转行为,只会执行 onclick 中的代码
// 返回结果:在控制台输出 "点击了链接",页面不会跳转

// 示例5:立即执行函数表达式(IIFE)中使用 void
void function() {
    console.log("这是一个立即执行的函数");
}();
// 返回结果:在控制台输出 "这是一个立即执行的函数"

5. 流程控制语句

5.1. 语句块概念

最基本的语句块是用于组合语句的。该块由一对大括号界定,通常用于流程控制,如:ifforwhile

while (x < 10) {
  x++;
}

重要:在ECMAScript 6标准之前,Javascript没有块作用域。在一个块中引入的变量,其作用域是全局的,它们的效果会延续到块之外。换句话说,块语句不定义范围。JavaScript中的“独立”块会产生与C或Java中完全不同的结果。示例:

var x = 1;
{
  var x = 2;
}
alert(x); // 输出的结果为 2

从 ECMAScript 6开始,使用 letconst定义的变量作用域是块作用域的。 更多信息请参考 letconst

5.2. 分支语句

  • if ... else if ... else 语句
var num = 10;
if(num < 10){
  console.log("num小于10");
}else if(num == 10){
  console.log("num等于10");
}else{
  console.log("num大于10");
}
  • switch语句
var x = 5;
switch (x){
  case 1:
      console.log("一月份");
      break;
  case 2:
      console.log("二月份");
      break;
  case 3:
      console.log("三月份");
      break;
  case 4:
      console.log("四月份");
      break;
  case 5:
      console.log("五月份");
      break;
  case 6:
      console.log("六月份");
      break;
  case 7:
      console.log("七月份");
      break;
  case 8:
      console.log("八月份");
      break;
  case 9:
      console.log("九月份");
      break;
  case 10:
      console.log("十月份");
      break;
  case 11:
      console.log("十一月份");
      break;
  case 12:
      console.log("十二月份");
      break;
  default:
      console.log("输入错误");
      break;
}

5.3. 循环语句

  • for 语句

与Java中的for循环语法类似

for(let i=0; i<10; i++){
  console.log(i);
}
  • do ... while 语句

与Java中的do ... while循环语法类似

let i = 1;
do{
  console.log(i);
  i++
}while(i < 10);
  • while 语句

与Java中的while循环语法类似

let i=1;
while(i < 10){
  console.log(i);
  i++;
}
  • for ... in 语句

可循环对象、数组等,循环的每个元素对于对象来说是对象的属性,而对于数组来说,则是下标

var fruits = ["苹果", "香蕉", "橙子", "榴莲"];
for(let idx in fruits) {
  console.log('idx: ' + idx);
}
  • for ... of 语句

可循环对象包括:Array,Map、Set、arguments等,与for ... in 不同的是,循环的每个元素对于对象来说是对象每个属性的值,而对于数组来说,则是数组的每个元素

var fruits = ["苹果", "香蕉", "橙子", "榴莲"];
for(let fruit of fruits){
  console.log(fruit);
}

6. 异常处理语句

  1. throw 语句可以抛出各种类型的值作为异常,包括字符串、数字、布尔值、对象等。
  2. 使用 try...catch 结构可以捕获和处理异常。try 块中包含可能抛出异常的代码,catch 块用于处理这些异常。
  3. Error 对象是一种标准的错误对象,它包含错误信息和堆栈跟踪,使得错误处理更加规范和信息丰富。
  4. finally 块是可选的,它包含的代码无论是否发生异常都会执行。这对于清理资源或执行必要的结束操作很有用。
  • throw

和Java中不同的是,JavaScript中的throw可以抛出任意一个含有值的表达式而不用是一个特定的类型

// 示例1:使用 throw 抛出不同类型的异常
function throwExample(type) {
    switch(type) {
        case 'string':
            throw "这是一个字符串错误";
        case 'number':
            throw 42;
        case 'boolean':
            throw true;
        case 'object':
            throw {
                toString: function() { return "我是一个对象错误!"; }
            };
        default:
            throw new Error("这是一个Error对象");
    }
}

也可以抛出Error对象,让你的错误信息包含更多有用的信息

var name="zhangsan";
if(name === "lisi"){
  console.log(name);
}else{
  throw(new Error("用户名错误"));
}
  • try ... catch
  • try ... catch ... finally
var name="zhangsan";
try{
  if(name === "lisi"){
      console.log(name);
  }else{
      throw(new Error("用户名错误"));
  }
}catch(e){
  console.log(e); //获取抛出的异常,进行自定义解决
}finally{// finally块是可选的
  console.log("finally执行了");//无论是否有异常, finally块的语句都会执行
}

7. 字符串常用操作

下面列举了String对象的方法

方法

描述

charAt, charCodeAt, codePointAt

返回字符串指定位置的字符或者字符编码。

indexOf, lastIndexOf

分别返回字符串中指定子串的位置或最后位置(如果没找到,返回-1)。

startsWith, endsWith, includes

返回字符串是否以指定字符串开始、结束或包含指定字符串。

concat

连接两个字符串并返回新的字符串。

fromCharCode, fromCodePoint

从指定的Unicode值序列构造一个字符串。这是一个String类方法,不是实例方法。

split

通过将字符串分离成一个个子串来把一个String对象分裂到一个字符串数组中。

slice

从一个字符串提取片段并作为新字符串返回(推荐使用,替代substring、substr)。

substring, substr

分别通过指定起始和结束位置,起始位置和长度来返回字符串的指定子集。

match, replace, search

通过正则表达式来工作.

toLowerCase, toUpperCase

分别返回字符串的小写表示和大写表示。

normalize

按照指定的一种 Unicode 正规形式将当前字符串正规化。

repeat

将字符串内容重复指定次数后返回。

trim

去掉字符串开头和结尾的空白字符。

7.1. 字符串常用操作

//获取字符串长度
console.log("sname的长度为: " + sname.length);  // 9
// charAt, charCodeAt, codePointAt
let str = "Hello World!";
console.log(str.charAt(0)); // 返回指定位置的字符 'H'
console.log(str.charCodeAt(1)); // 返回指定位置的字符编码 101
console.log(str.codePointAt(2)); // 返回指定位置的码点 108

// indexOf, lastIndexOf
console.log(str.indexOf("World")); // 返回指定子串的位置 6
console.log(str.lastIndexOf("o")); // 返回指定子串的最后位置 7

// startsWith, endsWith, includes
console.log(str.startsWith("Hello")); // 返回布尔值,判断是否以指定字符串开始 true
console.log(str.endsWith("!")); // 返回布尔值,判断是否以指定字符串结束 true
console.log(str.includes("World")); // 返回布尔值,判断是否包含指定字符串 true

// concat
console.log("Hello, ".concat(str)); // 连接两个字符串并返回新的字符串 "Hello, Hello World!"

// fromCharCode, fromCodePoint
console.log(String.fromCharCode(72, 101, 108, 108, 111)); // 从Unicode值构造字符串 "Hello"
console.log(String.fromCodePoint(72, 101, 108, 108, 111)); // 从码点构造字符串 "Hello"

// split
console.log(str.split(" ")); // 分裂字符串到数组 ["Hello", "World!"]

// slice
console.log(str.slice(0, 5)); // 提取字符串片段并返回新字符串 "Hello"

// substring, substr
console.log(str.substring(0, 5)); // 返回指定子集 "Hello"
console.log(str.substr(0, 5)); // 返回指定子集 "Hello"

// match, replace, search
console.log(str.match(/World/)); // 通过正则表达式匹配子串 ["World"]
console.log(str.replace("World", "JavaScript")); // 替换子串并返回新字符串 "Hello JavaScript!"
console.log(str.search(/World/)); // 通过正则表达式搜索子串的位置 6

// toLowerCase, toUpperCase
console.log(str.toLowerCase()); // 返回字符串的小写表示 "hello world!"
console.log(str.toUpperCase()); // 返回字符串的大写表示 "HELLO WORLD!"

// normalize
console.log(str.normalize("NFD")); // 正规化字符串 "Hello World!"

// repeat
console.log(str.repeat(2)); // 重复字符串内容 "Hello World!Hello World!"

// trim
console.log(str.trim()); // 去掉字符串开头和结尾的空白字符 "Hello World!"

8. 正则相关操作

正则对象的test()方法和字符串对象的search()方法类似,区别在于test()方法返回true、false,而search()方法返回的是下标

let str3 = 'hello world!';
let regex3 = /^hello/;
console.log(regex3.test(str3));// true
        
let str4 = 'hello world!';
let regex4 = /^world/;
console.log(regex4.test(str4));// false
  1. 正则表达式字面量:/pattern/
    1. 在 JavaScript 中,正则表达式通常用斜杠 (/) 包围来创建。
    2. 例如:let regex = /hello/;
    3. 这里的斜杠不是模式的一部分,而是用来定义正则表达式的标记。
  1. 字符串与正则表达式:
    1. 字符串:使用引号 ("" 或 '') 包围。例如:let str = "hello";
    2. 正则表达式:使用斜杠 (//) 包围。例如:let regex = /hello/;
  1. ^ 和 $ 的用途:
    1. ^ 在正则表达式中表示字符串的开始。
    2. $ 表示字符串的结束。
    3. 这些是正则表达式的特殊字符,用于匹配位置。
    4. 例如:/^hello$/ 会精确匹配只包含 "hello" 的字符串。
  1. /g 标志(全局搜索):
    1. 查找所有匹配,而不是在找到第一个匹配后停止。
    2. 影响诸如 match()replace() 等方法的行为。
    3. 允许某些方法(如 exec())在多次调用中记住上次匹配位置。
  1. /i 标志(不区分大小写):
    1. 使匹配过程忽略字母的大小写。
    2. 增加模式匹配的灵活性,无需明确指定所有可能的大小写组合。
let text = "The Cat chased another cat. Both cats like CATnip.";

// 使用 /g 标志(全局搜索)
let globalPattern = /cat/g;
console.log("全局搜索结果:", text.match(globalPattern));
// 输出: 全局搜索结果: ["cat", "cat"]

// 使用 /i 标志(不区分大小写)
let caseInsensitivePattern = /cat/i;
console.log("不区分大小写搜索结果:", text.match(caseInsensitivePattern));
// 输出: 不区分大小写搜索结果: ["Cat"]

// 同时使用 /g 和 /i 标志
let globalCaseInsensitivePattern = /cat/gi;
console.log("全局且不区分大小写搜索结果:", text.match(globalCaseInsensitivePattern));
// 输出: 全局且不区分大小写搜索结果: ["Cat", "cat", "cat", "CAT"]

// 使用 replace() 方法的例子
console.log("替换结果(仅使用 /g):", text.replace(/cat/g, "dog"));
// 输出: 替换结果(仅使用 /g): The Cat chased another dog. Both dogs like CATnip.

console.log("替换结果(使用 /gi):", text.replace(/cat/gi, "dog"));
// 输出: 替换结果(使用 /gi): The dog chased another dog. Both dogs like DOGnip.

// 使用 exec() 方法的例子(仅 /g)
let execPattern = /cat/g;
let execResult;
console.log("使用 exec() 方法的结果:");
while ((execResult = execPattern.exec(text)) !== null) {
    console.log(execResult);
    // 输出:
    // ["cat", index: 19, input: "The Cat chased another cat. Both cats like CATnip.", groups: undefined]
    // ["cat", index: 30, input: "The Cat chased another cat. Both cats like CATnip.", groups: undefined]
}
  1. 示例比较:
// 字符串
let str1 = "hello";
let str2 = "";  // 空字符串

// 正则表达式
let regex1 = /hello/;  // 匹配包含 "hello" 的字符串
let regex2 = /^hello$/;  // 精确匹配 "hello"
let regex3 = //;  // 空的正则表达式,会匹配任何字符串
let regex4 = /^$/;  // 匹配空字符串

console.log(regex1.test("hello world"));  // true
console.log(regex2.test("hello world"));  // false
console.log(regex2.test("hello"));  // true
console.log(regex3.test("anything"));  // true
console.log(regex4.test(""));  // true
console.log(regex4.test("not empty"));  // false
  1. 使用 RegExp 构造函数:
  2. 当使用 RegExp 构造函数时,不需要斜杠,而是使用引号:
let regex5 = new RegExp("hello");
let regex6 = new RegExp("^hello$");
  1. 重点说明:
    1. /pattern/ 是创建正则表达式的语法,不是字符串。
    2. "pattern" 是字符串,不是正则表达式。
    3. ^pattern$ 是正则表达式的一部分,用于精确匹配。
    4. // 是一个空的正则表达式,不同于空字符串 ""。

总结:

  • 正则表达式用 // 包围,这是 JavaScript 的语法。
  • 字符串用 "" 或 '' 包围。
  • ^ 和 $ 在正则表达式中用于指定匹配的开始和结束。
  • 这些概念是分开的,但在使用时可能会结合起来。

正则表达式教程:https://www.runoob.com/regexp/regexp-tutorial.html

二. JavaScript 数组、对象、函数

1. 数组

  • JavaScript中数组的使用和 Java 中的数组基本一致,但是在 JavaScript 中的数组更加灵活,数据类型和长度都没有限制。数组官方文档可参考:文档
  • javascript和java数组的区别
    • js数组可以自动扩容不会出现数组越界的情况,数组中可以存放任意数据类型
    • java数组一旦定义长度,不可以更改,数组中的数据类型必须一致。

1.1. 创建数组

var cars = ["奔驰", "宝马", "保时捷"];
var arr = ["aa", 23, 3.14, false];

1.2. 基本操作

方法名

方法作用、重要内容及返回值

indexOf()

返回指定元素在数组中第一次出现的索引。如果不存在,返回 -1。

lastIndexOf()

返回指定元素在数组中最后一次出现的索引。如果不存在,返回 -1。

toString()

将数组转换为字符串,元素间用逗号分隔。

Array.isArray()

判断一个对象是否为数组。如果是数组则为 true,否则为 false。

push()

在数组末尾添加一个或多个元素。修改原数组。返回值:新数组的长度。

pop()

删除数组的最后一个元素并返回该元素。修改原数组。返回值:被删除的元素。如果数组为空,则返回 undefined。

unshift()

在数组开头添加一个或多个元素。修改原数组。返回值:新数组的长度。

shift()

删除数组的第一个元素并返回该元素。修改原数组。返回值:被删除的元素。如果数组为空,则返回 undefined。

join()

将数组的所有元素连接成一个字符串。可指定分隔符。返回值:连接后的字符串。

slice()

返回数组的一个片段或子数组。不修改原数组。返回值:包含提取元素的新数组。

concat()

合并两个或多个数组。不修改原数组。返回值:合并后的新数组。

splice()

删除、插入或替换数组的元素。修改原数组。返回值:包含被删除元素的数组。如果没有删除元素,则返回空数组。

sort()

对数组元素进行排序。修改原数组。可传入比较函数。返回值:排序后的数组(即修改后的原数组)。

reverse()

颠倒数组中元素的顺序。修改原数组。返回值:颠倒顺序后的数组(即修改后的原数组)。

ES6--新增扩展运算符...
// 原始数组
let arr = [1, 2, 3];

// 1. 展开数组元素
console.log(...arr);
// 输出: 1 2 3

// 2. 复制数组
let arrCopy = [...arr];
console.log(arrCopy);
// 输出: [1, 2, 3]

// 3. 合并数组
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let mergedArr = [...arr1, ...arr2];
console.log(mergedArr);
// 输出: [1, 2, 3, 4, 5, 6]

// 4. 将数组转换为函数参数
function sum(a, b, c) {
    return a + b + c;
}
console.log(sum(...arr));
// 输出: 6 (1 + 2 + 3)

// 5. 在对象字面量中使用
let obj1 = { a: 1, b: 2 };
let obj2 = { ...obj1, c: 3 };
console.log(obj2);
// 输出: { a: 1, b: 2, c: 3 }

// 6. 与解构赋值结合使用
let [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 输出: 1
console.log(rest);  // 输出: [2, 3, 4, 5]

// 7. 将类数组对象转换为真正的数组
function convertToArray() {
    return [...arguments];
}
console.log(convertToArray(1, 2, 3));
// 输出: [1, 2, 3]

// 8. 字符串转数组
let str = "Hello";
let chars = [...str];
console.log(chars);
// 输出: ['H', 'e', 'l', 'l', 'o']
ES6--新增解构赋值
// 原始数组
let arr = [1, 2, 3];

// 使用解构赋值
let [a, b, c] = arr;

console.log(a); // 输出: 1
console.log(b); // 输出: 2
console.log(c); // 输出: 3

// 解构赋值的更多用法:

// 1. 忽略某些值
let [x, , z] = [1, 2, 3];
console.log(x); // 输出: 1
console.log(z); // 输出: 3

// 2. 剩余参数
let [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 输出: 1
console.log(rest);  // 输出: [2, 3, 4, 5]

// 3. 设置默认值
let [m = 1, n = 2, o = 3] = [4, 5];
console.log(m); // 输出: 4
console.log(n); // 输出: 5
console.log(o); // 输出: 3 (使用默认值)

// 4. 交换变量值
let p = 1;
let q = 2;
[p, q] = [q, p];
console.log(p); // 输出: 2
console.log(q); // 输出: 1

// 5. 从函数返回多个值
function returnArray() {
    return [1, 2, 3];
}
let [r, s, t] = returnArray();
console.log(r, s, t); // 输出: 1 2 3

// 6. 嵌套数组解构
let [u, [v, w]] = [1, [2, 3]];
console.log(u, v, w); // 输出: 1 2 3
1.2.1. 通过下标访问数据元素

数组中的元素是通过下标访问的,下标从0开始,一直到数组的长度-1

var firstCar = cars[0];  // 获取第一个元素
var car = cars[2];  // 获取下标为2的元素
var lastCar = cars[cars.length - 1];  // 获取最后一个元素
console.log(firstCar);//奔驰
console.log(car); //保时捷
console.log(lastCar); //保时捷
1.2.2. 更改数组元素
cars[2] = "法拉利";
console.log(cars);  // ['奔驰','宝马','法拉利']
1.2.3. 获取数据长度
var length = cars.length;
console.log('cars数组的长度:' + length);  // 3

需要注意的是和Java中的数组不同,JS中数组的length属性是可写的

//将length赋为一个大的值,剩余元素的值使用 empty x 7 表示
cars.length = 10;
console.log(cars); // ['奔驰', '宝马', '法拉利', empty × 7]
        
//将length赋为一个更小的值会删除元素
cars.length = 2;
console.log(cars); // ['奔驰', '宝马']
cars.length = 3;
console.log(cars); //['奔驰', '宝马', empty]
1.2.4. 遍历数组
for(let i = 0; i < cars.length; i++) {
    let car = cars[i];
    console.log('car: ' + car);
}
// ECMA5.1新增
//参数1:遍历的元素的值   参数2:遍历的元素的角标索引(可选)   参数3:遍历的数组
cars.forEach((item,index,cars) => {
    console.log(item+":"+index);
})
1.2.5. 将数组转成字符串 — toString()
var ss = cars.toString();
console.log(ss);    //奔驰,宝马
1.2.6. 查找第一个匹配元素的下标 — indexOf()

返回数组中第一个与指定值相等的元素的索引,如果找不到这样的元素,则返回 -1

var idx = cars.indexOf("宝马");
console.log(idx);//1
        
idx = cars.indexOf("大众");
console.log(idx);  // 未找到,返回-1
1.2.7. 查找最后一个匹配元素的下标 — lastIndexOf()

返回数组中最后一个(从右边数第一个)与指定值相等的元素的索引,如果找不到这样的元素,则返回 -1。

var lastidx = cars.lastIndexOf("奔驰");
console.log(lastidx); // 0
        
lastidx = cars.lastIndexOf("大众");
console.log(lastidx); // 未找到,返回-1
1.2.8. 判断一个对象是不是数组类型 — isArray()
console.log(Array.isArray(car)); // true

1.3. 进阶操作

1.3.1. 向数组尾部追加元素 — push()

用push方法可以完成向数组中添加一个或多个元素的操作,新添加的元素会放到数组最后的位置

//添加一个元素
cars.push("凯迪拉克");
console.log(cars.toString()); //奔驰,宝马,凯迪拉克
//添加多个元素
cars.push("大众", "福特");
console.log(cars.toString()); //奔驰,宝马,凯迪拉克,大众,福特
1.3.2. 删除数组中最后一个元素 — pop()

删除数组中最后一个元素,并返回该元素

var car = cars.pop();
console.log(car); //福特
console.log(cars.toString())//奔驰,宝马,凯迪拉克,大众
1.3.3. 向数组头部插入元素 — unshift()

unshift方法可以将一个或多个元素添加到数组的开头位置,与push方法对应

cars.unshift("劳斯莱斯");
console.log(cars.toString());//劳斯莱斯,奔驰,宝马,凯迪拉克,大众
        
cars.unshift("雷克萨斯","蒙迪欧");
console.log(cars.toString()); // 雷克萨斯,蒙迪欧,劳斯莱斯,奔驰,宝马,凯迪拉克,大众
1.3.4. 删除数组中第一个元素 — shift()

shift方法可以删除数据中第一个元素,并返回删除的元素,与pop方法对应

var car = cars.shift();
console.log("被删除的元素:" + car);  // 雷克萨斯
console.log(cars.toString()); //蒙迪欧,劳斯莱斯,奔驰,宝马,凯迪拉克,大众
1.3.5. 将数组的所有元素连接成一个字符串 — join()
var strCars = cars.join("*");
console.log(strCars);  // 蒙迪欧*劳斯莱斯*奔驰*宝马*凯迪拉克*大众

该方法也不会修改原数组

1.3.6. 连接多个数组 — concat()

concat方法可以将一个或多个数组中的元素拼接成一个**新的数组**(<span style="color:red;">不会修改原数组</span>)

var myGirls = ["邓紫棋", "孙燕姿"];
var myBoys = ["周杰伦", "刘德华", "陈奕迅"];
var myFruits = ["苹果", "香蕉", "橙子"];
var myChildren1 = myGirls.concat(myBoys);
var myChildren2 = myBoys.concat(myGirls,myFruits);
console.log(myChildren1); // ["邓紫棋", "孙燕姿", "周杰伦", "刘德华", "陈奕迅"]
console.log(myChildren2); // ["周杰伦", "刘德华", "陈奕迅", "邓紫棋", "孙燕姿", "苹果", "香蕉", "橙子"]
//两个数组连接,调用concat函数的一方的数组元素在新数组的前边
//如果concat函数的参数是多个数组,在新数组中,参数1数组的元素在参数2数组的元素的前边
1.3.7. 将元素添加到数组中指定位置,并删除该位置后若干元素 — splice()

splice方法的功能比较强大:

  • 删除数组中的元素
var fruits = ["香蕉", "橙子", "苹果", "芒果"];
let delItem = fruits.splice(2, 1); // 从下标为2的元素开始,往后删除一个元素,返回删除的元素
console.log('被删除的元素:' + delItem);
console.log(fruits);  // ["香蕉", "橙子", "芒果"]
  • 插入元素到指定位置
fruits.splice(2, 0, "柠檬", "石榴"); // 在第三个元素前面添加"柠檬", "石榴"
console.log(fruits);  // ['香蕉', '橙子', '柠檬', '石榴', '芒果']
  • 删除指定位置元素,然后在该位置插入指定元素
fruits.splice(3, 2, "榴莲", "西瓜")  // 从第四个元素开始删除两个元素,之后在添加两个元素
console.log(fruits);  // ['香蕉', '橙子', '柠檬', '榴莲', '西瓜']
1.3.8. 数组排序 — sort()

sort方法可以将数组中的元素按照默认的排序算法做升序排序,我们也可以指定自定义的排序算法

// 使用默认排序算法将数组升序排序(可结合reverse方法实现降序排列)
var languages = ["Java", "PHP", "IOS"];
languages.sort();
console.log(languages.toString()); // IOS,Java,PHP
        
//指定自定义的排序方法
// 使用js中的lamada表达式传一个匿名函数完成按照字符串的本地比较方法作为排序算法
fruits.sort((a,b) => {return a.localeCompare(b)});
console.log(fruits);  //  ['橙子', '榴莲', '柠檬', '西瓜', '香蕉']
1.3.9. 数组反转 — reverse()

将数组中的元素顺序反转

languages.reverse();
console.log(languages.toString()); // PHP,Java,IOS
1.3.10. 抽取数组中部分元素生成新数组 — slice(start, end)

slice方法可以根据传入的start下标和end下标从数组中截取部分元素生成新的数组,包含start不包含end([start,end))。

<span style="color:red;">注意:slice方法不会改变原数组</span>

console.log('原始数组:');
console.log(fruits);  // ['橙子', '榴莲', '柠檬', '西瓜', '香蕉']
// 从下标1开始,截取到下标2
// 注意:slice不会并不会裁剪原数组,只是从原数组中截取部分元素生成一个新的数组对象
var newFruits = fruits.slice(1,3);
console.log('新数组:');  
console.log(newFruits);  //  ['榴莲', '柠檬']
map()

方法是 JavaScript 中数组处理的一种常用方法。它会为数组中的每个元素调用提供的回调函数,然后返回一个新数组,新数组中的每一项对应于原数组通过回调函数处理后的结果。这个方法不会改变原数组,它总是返回一个新的数组。

具体作用

map() 遍历数组并执行一个指定的函数,将原数组的每个元素作为参数传递给该函数,然后将函数的返回值放入一个新数组中。

例如,代码中的 data.map(item => {...}) 表示对 data 数组中的每个 item 执行箭头函数,并返回一个包含新格式对象的数组。

重要内容:

  • 回调函数:map() 方法接收一个回调函数,该函数会被应用到数组的每个元素上。这个回调函数接收三个参数:当前元素值、元素索引、原数组。
  • 返回值:map() 方法总是返回一个新数组,元素是回调函数返回的值。原数组不受影响。

示例

javascript

复制代码

const numbers = [1, 2, 3, 4];
const squared = numbers.map(x => x * x); // 对每个元素进行平方操作
console.log(squared); // [1, 4, 9, 16]

在这个例子中,map() 会对数组 numbers 的每个元素执行平方操作,并返回新数组 [1, 4, 9, 16]

2. ES6新增--Map

ECMAScript 2015(ES6) 引入了一个新的数据结构来将一个值映射到另一个值。一个Map对象就是一个简单的键值对映射集合,可以按照数据插入时的顺序遍历所有的元素。

Map对象常用操作如下:

// 创建map类型
var sayings = new Map();
// 添加元素
sayings.set('dog', 'woof');
sayings.set('cat', 'meow');
sayings.set('elephant', 'toot');
console.log(sayings);
        
// 获取map元素数量
console.log("sayings map的长度" + sayings.size); // 3
    
// 按照Key获取元素值(如果该key不存在,则返回undefined)
console.log(sayings.get('cat')); // meow
        
// 判断map中是否存在指定的key,存在true  不存在false
console.log(sayings.has('bird')); // false
        
// 按照key删除map中的元素
sayings.delete('dog');
console.log(sayings.has('dog')); // false
        
//循环遍历map
for(var [key,value] of sayings){
    console.log(key+":"+value);
}
        
// 清空map
sayings.clear();
console.log("sayings map的长度" + sayings.size); // 0

3. ES6新增--Set

Set对象是一组值的集合,这些值是不重复的,可以按照添加顺序来遍历,这点和大多数编程语言类似。

Set对象常用操作如下:

// 创建Set对象
var mySet = new Set();
// 添加元素
mySet.add(1);
mySet.add("some text");
mySet.add("foo");
console.log(mySet);
        
// 判断是否存在某个元素
console.log(mySet.has(1)); // true
        
// 删除某个元素
mySet.delete("foo");
        
//获取set集合的长度
console.log(mySet.size);
        
//遍历所有的元素
for (let item of mySet) {
    console.log(item)
};

4. 函数

函数是JavaScript中的一个基本概念, 它允许你在一个代码块中存储一段用于处理单任务的代码,然后在任何你需要的时候用一个简短的命令来调用,而不是把相同的代码写很多次。

函数分为内置函数和自定义函数

4.1. 内置函数

在前面的章节我们已经学习了好多内置函数,比如数组中的join()slice(),Math中的random()等。

JavaScript有许多内置的函数,可以让你做很多有用的事情,而无需自己编写所有的代码。事实上, 许多你调用(运行或者执行的专业词语)浏览器内置函数时调用的代码并不是使用JavaScript来编写——大多数调用浏览器后台的函数的代码,是使用像C++这样更低级的系统语言编写的,而不是像JavaScript这样的web编程语言。

还有一些内置函数在浏览器API的内置对象上,如window.alert()window.open(),这些内置浏览器函数不是核心JavaScript语言的一部分,而是被定义为浏览器API的一部分。

4.2. 数学运算函数
  • round 四舍五入
console.log(Math.round(12.2));// 12
  • pow 次方
//次方 参数1:数值   参数3:次方
console.log(Math.pow(2,3));//8
  • sqrt 平方根
//平方根
console.log(Math.sqrt(9));// 3
  • abs 绝对值
console.log(Math.abs(-10)); //10
  • ceil 向上取整
console.log(Math.ceil(10.1));//11
  • floor 向下取整
console.log(Math.floor(10.8))//10
  • random 返回介于0(包括)与1(不包括)之间的随机数
// 随机0 ~ N(不包含)之间的整数
Math.floor(Math.random()*N)
// 随机0 ~ N(包含)之间的整数
Math.floor(Math.random()*(N+1))

// 返回0 ~ 11(不包含)之间的随机整数
Math.floor(Math.random()*11)

// 返回0 ~ 100(包含)之间的随机整数
Math.floor(Math.random()*101)

// 返回10 ~ 100(包含)之间的随机整数
Math.floor(Math.random()*91) + 10


// 返回 min ~ max(包含)之间的随机整数
Math.floor(Math.random() * (max - min + 1) ) + min;
//10-20之间的随机整数
console.log(Math.floor(Math.random() * (20 - 10 + 1)) + 10);
  • sin 正弦
  • cos 余弦
  • max 返回参数列表中最大值
// 获取一组数字中的最大值
var maxNum = Math.max(0, 150, 30, 20, -8, -200);

注意:如果参数列表中有非数字,最后结果会返回NaN

  • min 返回参数列表中最小值
  • Math.PI 返回PI的值
console.log(Math.PI); // 3.141592653589793
  • isNaN()

判断所传的值是否为非数字

console.log(isNaN(34));  // false
console.log(isNaN('34d'));  // true
4.3. 日期操作相关

JavaScript没有日期数据类型。但是你可以在你的程序里使用 Date对象和其方法来处理日期和时间。Date对象有大量的设置、获取和操作日期的方法。 它并不含有任何属性。

下面列举日期对象常用方法:

  • 创建日期对象
var dateObjectName = new Date([parameters]);
    • 无参数 : 创建今天的日期和时间,例如: today = new Date();. 最常用
var date = new Date();
console.log(date); //Wed Mar 01 2023 16:54:34 GMT+0800 (中国标准时间)
    • 一个符合以下格式的表示日期的字符串: "月 日, 年 时:分:秒." 例如: var Xmas95 = new Date("December 25, 1995 13:30:00")。如果你省略时、分、秒,那么他们的值将被设置为0。
console.log(new Date("December 25, 1995 13:30:00"));//Mon Dec 25 1995 13:30:00 GMT+0800 (中国标准时间)
    • 一个年,月,日的整型值的集合,例如: var Xmas95 = new Date(1995, 11, 25)。
console.log(new Date(1995, 11, 25));//Mon Dec 25 1995 00:00:00 GMT+0800 (中国标准时间)
    • 一个年,月,日,时,分,秒的集合,例如: var Xmas95 = new Date(1995, 11, 25, 9, 30, 0);
console.log(new Date(1995, 11, 25, 9, 30, 0)); //Mon Dec 25 1995 09:30:00 GMT+0800 (中国标准时间)
  • 日期对象中的其他方法总体可以分成下面几类:
    • "set" 方法, 用于设置Date对象的日期和时间的值。
    • "get" 方法,用于获取Date对象的日期和时间的值。
    • "to" 方法,用于返回Date对象的字符串格式的值。
    • parse 方法, 将符合日期格式的字符串转成距离1970年1月1日的毫秒数

具体可见:https://www.runoob.com/jsref/jsref-obj-date.html

4.2. 自定义函数

JavaScript 函数是通过 function 关键词定义的。

4.2.1. 使用函数声明的方式定义函数
function myFunction(a, b) {
     return a * b;
}
//函数调用
var number = myFunction(2,3);
4.2.2. 使用函数表达式的方式定义函数(匿名函数)

匿名函数:就是没有函数名的函数。

var x = function (a, b) {
            return a * b
        };
//函数调用
var z = x(4, 3);
4.2.3. 函数参数
  • 参数规则
    • JavaScript 函数定义不会为参数(parameter)规定数据类型。
    • JavaScript 函数不会对所传递的参数(argument)实行类型检查。
    • JavaScript 函数不会检查所接收参数(argument)的数量。
    • JavaScript 函数参数的默认值为undefined。
arguments对象

这样,您就可以简单地使用函数来查找(例如)数字列表中的最高值:

function findMax() {
  var i;
  var max = -Infinity; // -Infinity:负无穷大
  // 通过arguments遍历传进来的所有参数
  for (i = 0; i < arguments.length; i++) {
      if (arguments[i] > max) {
            max = arguments[i];
      }
  }
  return max;
}
console.log(findMax(1, 123, 500, 115, 44, 88));

4.3. 自调用函数

通过在正常定义的函数后面添加一对小括号可以定义一个自调用函数

// 不带参数的自调用函数
(function sayHello() {
            console.log("大家好,我是John老师");
}());
// 带参数的自调用函数
(function sayHello(name) {
    console.log("大家好,我是"+name+"老师");
}("Tony"));
console.log(
            function jian(a,b){
                return a-b;
            }(3,2)
);

ES6新增--逻辑中断

JavaScript 中的 && 操作符的工作方式是:

  1. 如果第一个操作数是假值(如 false, 0, "", null, undefined, NaN),它会立即返回这个假值。
console.log(false && 'anything');  // 返回 false
console.log(0 && 'anything');      // 返回 0
console.log("" && 'anything');     // 返回 ""
console.log(null && 'anything');   // 返回 null
console.log(undefined && 'anything'); // 返回 undefined
console.log(NaN && 'anything');    // 返回 NaN
  1. 如果第一个操作数是真值,它会返回第二个操作数的值,无论这个值是什么。
console.log(true && 'hello');  // 输出: 'hello'
console.log(42 && 0);  // 输出: 0
console.log('非空字符串' && false);  // 输出: false
console.log(1 && {name: 'John'});  // 输出: {name: 'John'}
console.log(true && [1, 2, 3]);  // 输出: [1, 2, 3]
console.log(100 && function() { return 'Hi'; });  // 输出: function() { return 'Hi'; }
console.log('truthy' && null);  // 输出: null
console.log({} && undefined);  // 输出: undefined

|| 操作符的工作方式是:

  1. 如果第一个操作数是真值,它会立即返回这个真值。
console.log("Hello" || "World");  // 输出: "Hello"
console.log(42 || 0);  // 输出: 42
console.log(true || false);  // 输出: true
console.log({name: "John"} || "default");  // 输出: {name: "John"}
console.log([1, 2, 3] || "empty");  // 输出: [1, 2, 3]
  1. 如果第一个操作数是假值,它会返回第二个操作数的值,无论这个值是什么。
console.log("" || "default");  // 输出: "default"
console.log(0 || 42);  // 输出: 42
console.log(false || true);  // 输出: true
console.log(null || {name: "John"});  // 输出: {name: "John"}
console.log(undefined || [1, 2, 3]);  // 输出: [1, 2, 3]
console.log(NaN || "Not a Number");  // 输出: "Not a Number"
console.log(null || undefined);  // 输出: undefined
  1. 空值合并运算符与可选链运算符
// 3. 空值合并运算符 (??)
let user = {
  name: 'Alice',
  age: null
};
let userAge = user.age ?? 18; // 如果user.age为null或undefined,则使用18
console.log(userAge); // 输出: 18

// 4. 可选链运算符 (?.)
let obj = {
  nested: {
    value: 42
  }
};
let value = obj?.nested?.value; // 安全地访问嵌套属性
console.log(value); // 输出: 42

let missingValue = obj?.missing?.value; // 如果属性不存在,不会报错
console.log(missingValue); // 输出: undefined

5. BOM内置对象

JavaScript中的内置对象分为两大类,一类是JavaScript中的标准内置对象,另一类是JavaScript浏览器API中特有的内置对象

5.1. 浏览器API中的内置对象(Browser对象 )

  • window (全局对象,每当 <body> 或 <frameset> 标签出现时,window 对象就会被自动创建)
  • Location (地址栏操作相关)
  • History (浏览历史操作相关,如:前进、后退等)
  • Screen (获取屏幕相关参数)
  • Navigator (Navigator 对象包含有关浏览器的信息)
  • 示例
//windows
var age = 34;
console.log(window.age);  
//window.alert("你好!");
//alert("你好!"); //window可以省略不写
              
//location
//location.href="http://www.jd.com"; //打开页面直接跳转到京东首页
      
//history
//history.back(); //后退
//history.forward();//前进
      
//screen
console.log(screen.availWidth); // 屏幕宽度
console.log(screen.availHeight); //屏幕高度
      
//Navigator  根据 W3C HTML 5 的规范,navigator 对象的 appName 要么返回 Netscape,要么返回浏览器的全名,这是为了兼容性而考虑的!
console.log(navigator.appName);

5.2. 标准内置对象(JavaScript 本地对象和内置对象)

  • Array
  • Number
  • String
  • Date
  • Math

...

5.3创建自定义对象

在JavaScript中我们可以通过以下三种方式创建自定义对象

  • 使用对象初始化器
// 创建一个表示人的对象
let person = {
    name: "张三",
    age: 30,
    sayHello: function() {
        console.log("你好,我是" + this.name);
    }
};

// 使用对象
console.log(person.name); // 输出: 张三
person.sayHello(); // 输出: 你好,我是张三

// 添加新属性
person.job = "程序员";
console.log(person.job); // 输出: 程序员
  • 使用构造函数
    • 构造函数允许我们创建多个相似的对象。
function Student(sname, age, sex) {
    this.sname = sname;
    this.age = age;
    this.sex = sex;
    this.sayHello = function() {
        console.log("你好,我是" + this.name);
    };
}

// 构造函数定义对象支持通过prototype属性扩展对象功能(是在对象原型上扩展功能,类似与Java中的类,所以后续通过该构造函数创建出的对象都带有扩展的功能)
Student.prototype.say = function() {
    console.log("Hi, I'm " + this.sname + "!");
}

let stu2 = new Student("李四", 23, "女");
console.log(stu2.sname); // 李四
stu2.say();      // Hi, I'm 李四!
  • 使用Object.create方法
    • 这种方法允许我们基于现有对象创建新对象。
// 创建一个原型对象
let personProto = {
    sayHello: function() {
        console.log("你好,我是" + this.name);
    }
};

// 基于原型创建新对象
let person = Object.create(personProto);
person.name = "赵六";
person.age = 40;

person.sayHello(); // 输出: 你好,我是赵六
  • 使用ES6的类(class)语法
    • ES6引入了更接近传统面向对象语言的类语法。
// 定义一个类
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    sayHello() {
        console.log("你好,我是" + this.name);
    }
}

// 创建类的实例
let person = new Person("孙七", 28);

console.log(person.age); // 输出: 28
person.sayHello(); // 输出: 你好,我是孙七

三. JavaScript事件DOM定时器

事件

事件是JavaScript浏览器API中非常重要的一个部分。它封装了用户和浏览器的所有交互行为。我们只需给我们感兴趣的事件句柄绑定一个自定义的处理函数,就可以在用户触发指定操作时,执行我们事先绑定好的自定义函数。

绑定事件

示例:

html代码:

<button id="btn">按钮</button>

JavaScript代码:

// 方式一:
// 给按钮绑定点击事件
var btn = document.getElementById("btn");
btn.onclick = function() {
    alert('您点击了按钮');
}
// 给文档对象绑定加载完成事件
document.onload = function() {
    console.log('当前页面已经加载完毕');
}
// 方式二:推荐用法
// 给按钮绑定点击事件
var btn = document.getElementById("btn");
btn.addEventListener('click', function() {
    alert('您点击了按钮');
});
// 方式三: 不推荐
<button id="btn" onclick="xxxx();"></button>

JavaScript浏览器API中给我们提供的事件句柄非常丰富,下面是一个汇总表:

事件句柄类型

属性

此事件发生在何时...

onabort

图像的加载被中断。

onblur

元素失去焦点。

onchange

域的内容被改变。

onclick

当用户点击某个对象时调用的事件句柄。

ondblclick

当用户双击某个对象时调用的事件句柄。

onerror

在加载文档或图像时发生错误。

onfocus

元素获得焦点。

onkeydown

某个键盘按键被按下。

onkeypress

某个键盘按键被按下并松开。

onkeyup

某个键盘按键被松开。

onload

一张页面或一幅图像完成加载。

onmousedown

鼠标按钮被按下。

onmouseup

鼠标按键被松开。

onmousemove

鼠标被移动。

onmouseenter

鼠标移到某元素之上

onmouseleave

鼠标从某元素上移开

onmouseover

鼠标移到某元素之上(或移到其子元素上)。

onmouseout

鼠标从某元素移开(或移到其子元素上)。

oncontextmenu

鼠标右键事件(右键菜单显示前触发)

onreset

重置按钮被点击。

onresize

窗口或框架被重新调整大小。

onselect

文本被选中。

onsubmit

确认按钮被点击。

onunload

用户退出页面。

鼠标、键盘事件属性

属性

描述

button

返回当事件被触发时,哪个鼠标按钮被点击。

clientX

返回当事件被触发时,鼠标指针的水平坐标。(相对于窗口左上角,不计算滚动条)

clientY

返回当事件被触发时,鼠标指针的垂直坐标。(相对于窗口左上角,不计算滚动条)

screenX

返回当某个事件被触发时,鼠标指针的水平坐标。 (相对于屏幕左上角)

screenY

返回当某个事件被触发时,鼠标指针的垂直坐标。(相对于屏幕左上角)

pageX

返回当某个事件被触发时,鼠标指针的水平坐标。(相对于文档左上角,计算滚动条)

pageY

返回当某个事件被触发时,鼠标指针的垂直坐标。(相对于文档左上角,计算滚动条)

metaKey

返回当事件被触发时,"meta" 键是否被按下。

shiftKey

返回当事件被触发时,"SHIFT" 键是否被按下。

ctrlKey

返回当事件被触发时,"CTRL" 键是否被按下。

altKey

返回当事件被触发时,"ALT" 是否被按下。

key

按键名称,如: k (按下键盘上的K)

code

按键代码,如:KeyD (按下键盘上的K)

keyCode (已废弃)

按键对应的数值码,如:68 (按下键盘上的K)

案例一 获取用户按的是哪个键

window.onkeydown = function(e) {
    console.log('code: ' + e.code);  // 获取用户按下键的code值: 如KeyA、keyD
    console.log('key: ' + e.key);  // 获取用户按下键的名称:如a、d、A、D
}

案例二 获取用户鼠标点击位置的坐标

window.onmousemove = function(e) {
    console.log('鼠标当前位置: ' + e.screenX+','+e.screenY);  // 获取用户鼠标当前在屏幕上的绝对坐标
}

标准 Event 属性

属性

描述

bubbles

返回布尔值,指示事件是否是冒泡事件类型。

cancelable

返回布尔值,指示事件是否可拥可取消的默认动作。

currentTarget

返回其事件监听器触发该事件的元素。

eventPhase

返回事件传播的当前阶段。

target

返回触发此事件的元素(事件的目标节点)。

timeStamp

返回事件生成的日期和时间。

type

返回当前 Event 对象表示的事件的名称。

案例 发生事件的DOM元素和发生的事件类型

<button id="tt">测试按钮</button>
document.querySelector("#tt").onclick = function(e){
    console.log(this);
    console.log(e.target);
    console.log('发生了'+e.type+'事件');
}

运行效果:

标准 Event 方法

方法

描述

initEvent()

初始化新创建的 Event 对象的属性。

preventDefault()

通知浏览器不要执行与事件关联的默认动作。

stopPropagation()

不再派发事件。

DOM操作

什么是DOM?

文档对象模型 (DOM) 是HTML和XML文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以从程序中对该结构进行访问,从而改变文档的结构,样式和内容。DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。简言之,它会将web页面和脚本或程序语言连接起来。

常用的DOM操作API

  • document.getElementById(id) 按照标签的id属性值获取dom对象,返回单个
  • document.getElementsByTagName(name) 按照标签名称获取dom对象,返回dom数组
  • document.querySelector(cssSelector) 按照css选择器获取dom对象,返回单个
  • document.querySelectorAll(cssSelector) 按照css选择器获取dom对象,返回dom数组
  • document.createElement(name) 创建DOM元素
  • parentNode.appendChild(node) 将元素添加到父元素中
  • element.innerHTML 设置标签内容
  • element.style.left 设置样式属性值
  • element.setAttribute() 设置属性值
  • element.getAttribute() 获取属性值
  • element.addEventListener() 绑定事件处理函数
  • window.scrollTo() 滚动窗口

案例一 表单验证

需求: 提供一个用户注册表单, 有用户名、密码、重复密码、常用住址几项内容, 当文本框失去焦点后,用户输入的内容进行校验,校验规则如下:

  1. 用户名不能为空, 长度不能少于5位
  2. 密码不能为空
  3. 重复密码必须和密码一致

案例二 点亮熄灭灯泡

需求: 实现如下效果, 点击点亮的时候开灯,点击关闭的时候关灯

分析:可以分别准备开灯和关灯两张图片,当点击点亮时,将img的src指向开灯的图片,关闭时指向关灯的图片。

案例三 小球跟随效果

需求:实现如下效果,将一个小球放置到div框中, 随鼠标位置移动

定时器

JavaScript中的定时器有两个:setInterval()setTimeout()

setInterval()

setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。

setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。

语法:

setInterval(code,millisec)

示例:

用定时器实现时钟效果

<html>
    <body>
        <form>
            <input type="text" id="clock" size="35" />
            <button onclick="stop()">停止</button>
        </form>
    </body>
    <script type="text/javascript">
        function clock(){
            var now=new Date();
            document.getElementById("clock").value=now;
        }
        
        // 开启计时器,50毫秒刷新一次时间
        var timerId = self.setInterval("clock()",50); 
        
        // 停止计时器
        function stop() {
            clearInterval(timerId);
        }
    </script>
</html>

setTimeout()

setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。

语法:

setTimeout(code,millisec);

示例:

function test() {
   alert('5 seconds!'); 
}
var timerId = setTimeout(test,5000);  // 延时5秒弹窗
// 如果想取消定时任务
clearTimeout(timerId);

setTimeout() 只执行 code 一次。如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout()。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值