大理白族自治州网站建设_网站建设公司_JavaScript_seo优化
2026/1/12 22:17:52 网站建设 项目流程

一、错误处理

1、错误类型

// 1. SyntaxError - 语法错误(解析时) const 1num = 5; // 报错:SyntaxError // 2. ReferenceError - 引用错误 console.log(undefinedVariable); // 报错:ReferenceError // 3. TypeError - 类型错误 const obj = null; obj.someMethod(); // 报错:TypeError // 4. RangeError - 范围错误 const arr = new Array(-1); // 报错:RangeError // 5. URIError - URI错误 decodeURIComponent('%'); // 报错:URIError // 6. EvalError - eval错误(已废弃,现在基本不用) // 7. AggregateError - 聚合错误(ES2021) // 当多个错误需要一起报告时使用

2、自定义错误

class ValidationError extends Error { constructor(message, field) { super(message); this.name = 'ValidationError'; this.field = field; this.date = new Date(); } } class DatabaseError extends Error { constructor(message, code) { super(message); this.name = 'DatabaseError'; this.code = code; } } // 使用自定义错误 function validateUser(user) { if (!user.name) { throw new ValidationError('用户名不能为空', 'name'); } if (user.age < 0) { throw new ValidationError('年龄不能为负数', 'age'); } }

3、错误的检查方法

try...catch...finally

try表示定义执行时进行错误测试的代码块

catch允许当try定义的代码块发生错误时所执行的代码块

// 基本用法 try { // 可能出错的代码 const result = riskyOperation(); console.log('成功:', result); } catch (error) { // 错误处理 console.error('错误类型:', error.name); console.error('错误信息:', error.message); console.error('错误堆栈:', error.stack); } finally { // 无论是否出错都会执行 console.log('清理工作...'); } // 嵌套的 try...catch function processData(data) { try { try { const parsed = JSON.parse(data); return parsed; } catch (parseError) { // 如果JSON解析失败,尝试其他格式 if (data.startsWith('<')) { return parseXML(data); } throw parseError; // 重新抛出 } } catch (error) { console.error('数据处理失败:', error); return null; } } // finally 的特殊行为 function testFinally() { try { console.log('try 块开始'); throw new Error('测试错误'); console.log('这行不会执行'); } catch (error) { console.log('catch 块:', error.message); return '从 catch 返回'; // finally 仍然会执行! } finally { console.log('finally 块执行'); } console.log('函数末尾'); // 这行不会执行 }

throw语句

表示允许创建自定义错误(创建或抛出异常)

// 抛出基本错误 function divide(a, b) { if (b === 0) { throw new Error('除数不能为零'); } return a / b; } // 抛出任意值(不推荐) function processInput(input) { if (typeof input !== 'string') { throw { code: 'INVALID_TYPE', message: '输入必须是字符串' }; } } // 条件性抛出 function fetchData(url) { if (!url) { throw new TypeError('URL 不能为空'); } if (!url.startsWith('http')) { throw new URIError('无效的 URL 格式'); } // 模拟网络请求 const success = Math.random() > 0.5; if (!success) { throw new NetworkError('网络请求失败', 500); } return { data: '模拟数据' }; }

二、变量提升

所有声明都会提升只不过表现不同;

var函数声明时,初始化和声明一起提升;

let/const只提升声明形成暂时性死区;

同时函数声明的优先级高于变量声明。

// 示例 1:基本提升 console.log(myVar); // undefined(不会报错) var myVar = 5; console.log(myVar); // 5 // 实际执行顺序相当于: var myVar; // 声明提升到顶部 console.log(myVar); // undefined myVar = 5; // 赋值留在原地 console.log(myVar); // 5 // 示例 2:函数作用域 function example() { console.log(x); // undefined var x = 10; console.log(x); // 10 } example(); // 示例 3:重复声明 var a = 1; var a = 2; // 可以重复声明 console.log(a); // 2 // 示例 4:变量提升的边界情况 function test() { if (false) { var hoisted = '我会被提升'; } console.log(hoisted); // undefined(即使 if 块不执行) } test();

函数声明提升

// 1. 函数声明提升 sayHello(); // "Hello!"(可以调用) function sayHello() { console.log("Hello!"); } // 相当于: function sayHello() { // 整个函数提升到顶部 console.log("Hello!"); } sayHello(); // 调用 // 2. 函数表达式不会提升 // sayHi(); // TypeError: sayHi is not a function var sayHi = function() { console.log("Hi!"); }; sayHi(); // "Hi!"(现在可以调用) // 3. 函数声明 vs 变量声明 console.log(typeof myFunc); // "function"(函数提升优先) var myFunc = '我是字符串'; function myFunc() { return '我是函数'; } console.log(typeof myFunc); // "string" // 相当于: function myFunc() { // 函数声明提升 return '我是函数'; } var myFunc; // var 声明(忽略,因为已经有同名函数) console.log(typeof myFunc); // "function" myFunc = '我是字符串'; // 赋值覆盖 console.log(typeof myFunc); // "string"

三、严格模式

由于历史原因JavaScript在设计初期为了快速推广,做了宽容设计,所以使用严格模式可以更容易发现一些错误。

1、消除静默错误

'use strict'; // 1. 赋值给未声明的变量 → 抛出错误 function testUndeclared() { undeclaredVar = 10; // ReferenceError: undeclaredVar is not defined } // 2. 给只读属性赋值 → 抛出错误 NaN = 5; // TypeError: Cannot assign to read only property 'NaN' undefined = 10; // TypeError: Cannot assign to read only property 'undefined' // 3. 删除不可删除的属性 → 抛出错误 delete Object.prototype; // TypeError: Cannot delete property 'prototype' // 4. 给不可扩展的对象添加属性 → 抛出错误 const sealedObj = Object.preventExtensions({}); sealedObj.newProp = 'value'; // TypeError: Cannot add property newProp

2、防止意外创建全局变量

'use strict'; // 示例 1:拼写错误立即暴露 function calculate(price, quantity) { // 假设这里拼写错误 totla = price * quantity; // ReferenceError: totla is not defined return totla; } // 示例 2:忘记声明变量 function processData(data) { result = data.map(x => x * 2); // ReferenceError: result is not defined // 正确的应该是:let result = data.map(x => x * 2); return result; } // 对比:非严格模式的危险 function dangerousFunction() { counter = 0; // 意外全局变量! return function() { counter++; // 修改全局变量 return counter; }; } const fn1 = dangerousFunction(); const fn2 = dangerousFunction(); console.log(fn1()); // 1 console.log(fn2()); // 2 - 两个函数共享同一个计数器!

3、消除this的模糊性

'use strict'; // 1. 普通函数调用时 this 为 undefined function logContext() { console.log(this); // undefined(非严格模式:window/global) } logContext(); // 2. apply/call 不自动包装基本类型 function showNumber() { console.log(typeof this); // 'number'(非严格模式:'object') } showNumber.call(42); // 3. 构造函数忘记 new 时报错 function Person(name) { this.name = name; } // 正确使用 const john = new Person('John'); // OK // 错误使用 - 立即发现错误 // const mary = Person('Mary'); // TypeError: Cannot set property 'name' of undefined // 对比:非严格模式的危险 function UnsafePerson(name) { // 非严格模式 this.name = name; } // 忘记 new 的后果 const oops = UnsafePerson('Oops'); console.log(oops); // undefined - 函数返回 undefined console.log(name); // 'Oops' - 创建了全局变量!

4、禁止使用with语句

'use strict'; // with 语句已被禁止 const config = { apiUrl: 'https://api.example.com' }; // 非严格模式允许(但不推荐) // with (config) { // console.log(apiUrl); // 可以访问 // someVar = 'test'; // 这可能创建全局变量! // } // 严格模式:直接报错 // with (config) { // SyntaxError: Strict mode code may not include a with statement // console.log(apiUrl); // } // 替代方案:解构赋值 const { apiUrl } = config; console.log(apiUrl); // 更清晰,更安全

5、更安全的eval

'use strict'; // 1. eval 中的变量不会泄漏到外部作用域 eval('var evalVar = "内部变量";'); console.log(evalVar); // ReferenceError: evalVar is not defined // 2. 不能将 eval 赋值给其他变量 // var evil = eval; // 可以赋值,但行为改变 // 3. 不能使用 eval 作为标识符 // var eval = 10; // SyntaxError: Unexpected eval or arguments in strict mode // 对比:非严格模式的危险 function dangerousEval() { // 非严格模式 var secret = '不应暴露'; eval('console.log(secret);'); // 可以访问闭包变量 } // 实际应用:安全的沙箱 function safeEval(code, context) { 'use strict'; // 使用 Function 构造函数创建隔离作用域 try { const fn = new Function('context', ` with (context) { return ${code}; } `); return fn(context); } catch (error) { console.error('安全执行失败:', error); return null; } } const safeContext = { a: 1, b: 2 }; const result = safeEval('a + b', safeContext); console.log(result); // 3

闭包变量:内部函数中访问外部函数作用域的变量,即使外部函数已经执行完毕,但这些变量依然可以被内部函数访问。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询