文章目录
- 十二、JavaScript控制语句
- 1.条件语句
- 2.循环语句
- 2.1 for...in 循环
- 2.2 for...of 循环
- 2.2.1 基本语法
- 2.2.2 遍历数组、Set、字符串
- 2.2.3 变量名做属性名时需要 [ ]
- 2.2.4 关于 Symbol 值做对象的键
- 2.2.5 关于 Symbol.iterator
- 2.2.6 实现可迭代对象
- 2.2.7 生成器函数
- 2.2.8 使用生成器函数简化代码
- 3. 跳转语句
- 十三、JavaScript 异常处理
- 1. 异常处理的基本概念
- 1.1 什么是异常
- 1.2 错误类型
- 2. 基础异常处理语法
- 2.1 try-catch 语句
- 2.2 finally 语句
- 2.3 throw 语句
- 3. Error 对象属性
- 4. 自定义异常
- 4.1 创建自定义异常类
- 4.2 使用自定义异常
- 十四、avaScript常用全局函数
- 1. ECMAScript 标准全局函数
- 1.1 类型转换函数
- 1.2 数值处理函数
- 1.3 URI 编码/解码函数
- 1.4 其他 ECMAScript 全局函数
- 2. 浏览器环境提供的全局函数
- 2.1 定时器函数
- 2.2 定时器函数
十二、JavaScript控制语句
JavaScript 中的控制语句可以分为以下几类:
1.条件语句
● if 语句
● if…else 语句
● if…else if…else 语句
● switch 语句
2.循环语句
● for 循环
● for…in 循环 (遍历对象属性)
● for…of 循环 (遍历可迭代对象)
● while 循环
● do…while 循环
2.1 for…in 循环
for…in 语句用于遍历对象的可枚举属性(包括继承的可枚举属性)。
基本语法
for(variableinobject){// 执行的代码}特点
● 遍历对象自身的和继承的可枚举属性(不仅遍历自身属性,还会遍历原型链上的可枚举属性)
默认属性都是可枚举的
letuser={name:"jack",sayHi:function(){console.log("hi");}}user.__proto__.email="jack@123";user.__proto__.sayHello=function(){console.log("hello");}for(letkeyinuser){console.log(user[key]);}结果如下:
● 遍历顺序不固定(依赖于 JavaScript 引擎实现)
● 不适合遍历数组(会遍历数组的所有可枚举属性,包括非数字键)
letarr=[1,2,3];for(letkeyinarr){console.log(key,"----->",arr[key]);}数组的遍历方式推荐:传统的 for 循环,或者 forEach 方法,或者 for…of 循环。
2.2 for…of 循环
for…of 语句用于遍历可迭代对象(如 Array, Map, Set, String, arguments 等)的值。
2.2.1 基本语法
for(variableofiterable){// 执行的代码}特点
● 遍历可迭代对象的值
● 不会遍历对象的属性
● 是 ES6 新增的语法
● 可以配合 break, continue 和 return 使用
2.2.2 遍历数组、Set、字符串
数组、Set、字符串等都是可迭代对象,都可以使用 for…of来遍历这些对象中的值,代码如下:
// 数组letarr=[1,2,3,4];for(constvalueofarr){console.log(value);}// Set集合letmySet=newSet();mySet.add("张三");mySet.add("李四");mySet.add("王五");for(constnameofmySet){console.log(name);}// 字符串letname="king";for(constcofname){console.log(c);}2.2.3 变量名做属性名时需要 [ ]
用变量名做对象属性名时需要使用 [ ],如下代码:
letpropertyName="name";letuser={[propertyName]:"jack",};console.log(user[propertyName]);2.2.4 关于 Symbol 值做对象的键
Symbol可以创建唯一值,用它做对象属性的键,可以保证一定可以创建一个新的属性,代码如下:
letpropertyName=Symbol("随便");letmethodName=Symbol("随便");// Symbol值独一无二console.log(propertyName===methodName);// false// 用Symbol值做属性名,做方法名letuser={[propertyName]:"jackson",[methodName](){console.log("这是一个方法");}};// 访问属性、调用方法console.log(user[propertyName]);user[methodName]();2.2.5 关于 Symbol.iterator
Symbol.iterator 就是一个内置的 Symbol 值。它是一个变量,存着一个 Symbol 值。
它被作为一个约定好的名字,让 JS 知道:你这个对象怎么被 for…of 遍历。
怎么能够知道这个对象是否能够被 for…of遍历?
typeof obj[Symbol.iterator] === ‘function’,如果是 true 则表示该对象是可迭代对象,可以被 for…of遍历。
怎么能够让一个不可迭代的对象,变成可迭代的对象?
在对象内部添加一个 Symbol.iterator {}方法,这是程序员与 for…of之间的约定。
2.2.6 实现可迭代对象
让该对象实现 Symbol.iterator方法【在这个方法中编写自定义的迭代逻辑】。对象就可以被 for…of遍历。 代码如下:
// 要想实现对象可迭代,必须手动编写迭代器,编写迭代规则。// Js的执行引擎和Js程序员之间怎么约定的呢?我们程序员把迭代规则写到什么地方呢?// 通过 Symbol.iterator 来约定.// Symbol.iterator是JS内置的变量,这个变量中保存了“获取迭代器对象” 的 方法名。// 这个方法是干啥的?返回一个迭代器对象。然后我们程序员就可以在这个迭代器对象内部指定具体的迭代规则。// 我要达到的效果:希望user对象是可迭代的。并且迭代user对象的时候,请把user对象中data数组迭代一下。letuser={arr:[1,2,3],[Symbol.iterator](){letindex=0;return{next:()=>{if(index<this.arr.length){return{done:false,value:this.arr[index++]};}else{return{done:true};}}}}}for(constvalofuser){console.log(val);}//实现迭代器,遍历对象属性letvip={name:"jack",age:18,sex:1,password:"123456",[Symbol.iterator](){letindex=0;letkeys=Object.keys(this);return{next:()=>{if(index<keys.length){return{done:false,value:this[keys[index++]]}}else{return{done:true}}}}}}for(constvalofvip){console.log(val);}2.2.7 生成器函数
为了让迭代器写起来更简单,专门为迭代器准备了一个生成器函数,可以大大简化迭代器代码的编写。生成器函数是迭代器的语法糖。按照下面代码格式编写,生成器函数会返回一个迭代器。
function* 是生成器函数的标志
// 生成器函数function*generator(){yield1;yield2;yield3;}// 调用生成器函数,返回迭代器对象constgen=generator();// 通过迭代器对象来取值(根据迭代器协议:所有迭代器对象都有next()方法,并且next()方法的执行结果是一个含有value和done属性的对象,done为true时表示已迭代完毕。)console.log(gen.next().value);console.log(gen.next().value);console.log(gen.next().value);yield 可以理解为 “暂停并返回值”,每次调用迭代器的 .next() 方法时,函数会执行到下一个 yield 处暂停,yield 后面的表达式会被作为返回值
2.2.8 使用生成器函数简化代码
letuser={name:"jack",age:18,weight:50,[Symbol.iterator]:function*(){letkeys=Object.keys(this);// for(let index =0;index<keys.length;index++){// yield this[keys[index]];// }for(letpropertyNameinthis){yieldthis[propertyName];}}}for(letvalofuser){console.log(val);}3. 跳转语句
● break 语句
● continue 语句
● return 语句 (在函数中)
十三、JavaScript 异常处理
异常处理是 JavaScript 编程中的重要概念,它能帮助我们优雅地处理程序运行中可能出现的错误情况。本文将从基础语法角度,详细介绍 JavaScript 中的异常处理机制。
1. 异常处理的基本概念
1.1 什么是异常
异常(Exception)是指程序执行过程中出现的意外情况,它会打断代码的正常执行流程。例如:
constnum=10;console.log(num.toUpperCase());// TypeError: num.toUpperCase is not a function1.2 错误类型
JavaScript 中有几种常见的错误类型:
● Error:通用错误类型,所有其他错误类型的基类
● SyntaxError:语法错误
● ReferenceError:引用未定义的变量
● TypeError:类型错误(如调用不存在的方法)
● RangeError:数值超出有效范围
● URIError:URI 处理函数使用不当
2. 基础异常处理语法
2.1 try-catch 语句
try-catch 是 JavaScript 中最基本的异常处理结构:
try{// 可能出错的代码constresult=riskyOperation();console.log(result);}catch(error){// 出错时执行的代码console.log('发生错误:',error.message);}当catch语句里不需要异常对象时,
可以简写成以下代码:
try{// 可能抛出异常的代码}catch{// 注意:这里没有 error 参数// 仍然可以处理错误,但无法访问错误对象console.log('发生了错误,但不知道具体是什么错误');}2.2 finally 语句
finally 块中的代码无论是否发生异常都会执行:
try{console.log('尝试执行');constdata=JSON.parse('无效的JSON');}catch(error){console.log('捕获到错误:',error.message);}finally{console.log('这部分总会执行');}2.3 throw 语句
使用 throw 可以主动抛出异常:
functioncheckAge(age){if(age<0){thrownewError('年龄不能为负数');}if(age<18){thrownewError('未满18岁');}return'验证通过';}try{checkAge(-5);}catch(error){console.log(error.message);// "年龄不能为负数"}3. Error 对象属性
Error 对象的主要属性:
try{notDefinedFunction();}catch(err){console.log(err.name);// "ReferenceError"console.log(err.message);// "notDefinedFunction is not defined"console.log(err.stack);// 堆栈跟踪信息(调试用)}4. 自定义异常
4.1 创建自定义异常类
JavaScript 通过继承 Error 类来实现自定义异常:
classMyCustomErrorextendsError{constructor(message,extraInfo){super(message);// 调用父类构造函数this.name='MyCustomError';// 设置错误名称this.extraInfo=extraInfo;// 添加自定义属性this.timestamp=newDate();// 添加时间戳}logError(){console.error(`[${this.timestamp}]${this.name}:${this.message}`);}}4.2 使用自定义异常
functionvalidateInput(input){if(!input){thrownewMyCustomError('输入不能为空',{code:'EMPTY_INPUT'});}if(input.length<5){thrownewMyCustomError('输入太短',{code:'TOO_SHORT',minLength:5});}}try{validateInput('abc');}catch(err){if(errinstanceofMyCustomError){err.logError();// 调用自定义方法console.log('额外信息:',err.extraInfo);}else{console.error('其他错误:',err);}}十四、avaScript常用全局函数
以下是 JavaScript 中可以直接调用的全局函数(不依赖任何对象,属于全局作用域),包括 ECMAScript 标准函数 和 浏览器环境提供的函数,并附带简单示例:
1. ECMAScript 标准全局函数
1.1 类型转换函数
1.2 数值处理函数
1.3 URI 编码/解码函数
URL 中如果含有中文、空格等特殊字符时,浏览器向服务器发送请求后,服务器接收到的 URL 可能是乱码。为了避免这种情况的发生,建议在传参前对 URL 进行编码,在服务器中接参后解码。
encodeURI 编码时会保留URL结构字符(不编 😕?#[]@!$&'()*+,;=)
encodeURIComponent 编码时不会保留 URL 结构字符,全部都编,适合单独仅对参数值进行编码。它的使用频率较高。因为大部分情况下是对参数值进行编码,例如 用户提交的数据是 ?x=abc&y=def,如果不对这个参数值进行编码,服务器会把这个参数值中的 ?&=当做结构字符来处理。我想让服务器把它们当成普通数据,而不是解析成结构。
JavaScript中所有URI编码/解码函数都固定采用UTF-8字符集