(转载)20个JavaScript重点知识点(2)函数
JavaScript<strong>函数</strong>是一段可重复使用的代码块,用于执行特定任务。函数通过<code>function</code>关键字定义,可以接收参数、执行操作并返回结果。函数可以被定义一次,然后在程序中多次调用,从而实现代码的复用和模块化编程。本文将带来JavaScript基础到高阶实战分享!<br><h2>函数定义</h2>
<h3>1. 传统定义方式</h3>
<pre class="code-snippet__js" data-lang=""><code>// 1. 函数声明(存在提升)</code><code>function sum(a, b) {</code><code> return a + b;</code><code>}</code><code><br></code><code>// 2. 函数表达式</code><code>const multiply = function(a, b) {</code><code> return a * b;</code><code>};</code><code><br></code><code>// 3. 构造函数(不推荐)</code><code>const div = new Function('a', 'b', 'return a / b');</code></pre>
<h3>2. 现代ES6+语法</h3>
<pre class="code-snippet__js" data-lang=""><code>// 4. 箭头函数(无this/arguments)</code><code>const pow = (base, exponent) => base ** exponent;</code><code><br></code><code>// 5. 简写方法语法</code><code>const calculator = {</code><code> sqrt(x) {</code><code> return Math.sqrt(x);</code><code> }</code><code>};</code><code><br></code><code>// 6. 生成器函数</code><code>function* idGenerator() {</code><code> let id = 1;</code><code> while(true) yield id++;</code><code>}</code><code><br></code><code>// 7. Async函数</code><code>async function fetchData(url) {</code><code> const res = await fetch(url);</code><code> return res.json();</code><code>}</code></pre>
<h3>3. 关键差异对比</h3>
<table>
<thead>
<tr><th>特性</th><th>函数声明</th><th>函数表达式</th><th>箭头函数</th></tr>
</thead>
<tbody>
<tr>
<td>提升</td>
<td>✅</td>
<td>❌</td>
<td>❌</td>
</tr>
<tr>
<td>自有this</td>
<td>✅</td>
<td>✅</td>
<td>❌</td>
</tr>
<tr>
<td>arguments对象</td>
<td>✅</td>
<td>✅</td>
<td>❌</td>
</tr>
<tr>
<td>构造函数</td>
<td>✅</td>
<td>✅</td>
<td>❌</td>
</tr>
<tr>
<td>原型属性</td>
<td>✅</td>
<td>✅</td>
<td>❌</td>
</tr>
</tbody>
</table>
<br><hr>
<h2>作用域与闭包</h2>
<h3>1. 作用域链解析</h3>
<pre class="code-snippet__js" data-lang=""><code>function outer() {</code><code> const outerVar = '外层';</code><code><br></code><code> function inner() {</code><code> const innerVar = '内层';</code><code> console.log(outerVar); // 访问外层作用域</code><code> }</code><code><br></code><code> return inner;</code><code>}</code><code><br></code><code>const closure = outer();</code><code>closure(); // "外层" (闭包保持outerVar引用)</code></pre>
<h3>2. 闭包</h3>
<h4>实现私有变量</h4>
<pre class="code-snippet__js" data-lang=""><code>function createCounter() {</code><code> let count = 0;</code><code><br></code><code> return {</code><code> increment() { count++ },</code><code> get() { return count },</code><code> reset() { count = 0 }</code><code> };</code><code>}</code><code><br></code><code>const counter = createCounter();</code><code>counter.increment();</code><code>console.log(counter.get()); // 1</code></pre>
<h4>记忆化缓存</h4>
<pre class="code-snippet__js" data-lang=""><code>function memoize(fn) {</code><code> const cache = new Map();</code><code><br></code><code> return function(...args) {</code><code> const key = JSON.stringify(args);</code><code> if (cache.has(key)) return cache.get(key);</code><code><br></code><code> const result = fn(...args);</code><code> cache.set(key, result);</code><code> return result;</code><code> };</code><code>}</code><code><br></code><code>const memoizedFib = memoize(fibonacci);</code></pre>
<h3>3. 内存泄漏防范</h3>
<pre class="code-snippet__js" data-lang=""><code>// 错误示例:DOM元素引用未释放</code><code>function init() {</code><code> const element = document.getElementById('bigData');</code><code> element.addEventListener('click', () => {</code><code> console.log(element.id); // 闭包保留element引用</code><code> });</code><code>}</code><code><br></code><code>// 正确做法:弱引用</code><code>function safeInit() {</code><code> const element = document.getElementById('bigData');</code><code> const weakRef = new WeakRef(element);</code><code><br></code><code> element.addEventListener('click', () => {</code><code> const el = weakRef.deref();</code><code> if (el) console.log(el.id);</code><code> });</code><code>}</code></pre>
<hr>
<h2>this的5种绑定规则</h2>
<h3>1. 绑定规则详解</h3>
<pre class="code-snippet__js" data-lang=""><code>// 1. 默认绑定(非严格模式)</code><code>function showThis() {</code><code> console.log(this); // window/global</code><code>}</code><code><br></code><code>// 2. 隐式绑定</code><code>const obj = {</code><code> value: 42,</code><code> getValue() {</code><code> return this.value;</code><code> }</code><code>};</code><code><br></code><code>// 3. 显式绑定</code><code>function logThis() {</code><code> console.log(this);</code><code>}</code><code>const boundFunc = logThis.bind({ name: '绑定的this' });</code><code><br></code><code>// 4. new绑定</code><code>function Person(name) {</code><code> this.name = name;</code><code>}</code><code>const person = new Person('Alice');</code><code><br></code><code>// 5. 箭头函数(继承外层this)</code><code>const outerThis = this;</code><code>const arrowFunc = () => {</code><code> console.log(this === outerThis); // true</code><code>};</code></pre>
<h3>2. 常见问题解决方案</h3>
<pre class="code-snippet__js" data-lang=""><code>// 回调函数丢失this问题</code><code>class Timer {</code><code> constructor() {</code><code> this.seconds = 0;</code><code> // 使用箭头函数保留this</code><code> setInterval(() => {</code><code> this.seconds++;</code><code> }, 1000);</code><code> }</code><code>}</code><code><br></code><code>// 多层嵌套this访问</code><code>const deepObj = {</code><code> level1: {</code><code> level2: {</code><code> method() {</code><code> // 使用箭头函数维持this指向</code><code> const helper = () => {</code><code> console.log(this); // 指向level2对象</code><code> };</code><code> helper();</code><code> }</code><code> }</code><code> }</code><code>};</code></pre>
<hr>
<h2>高阶函数与函数式编程</h2>
<h3>1. 高阶函数应用</h3>
<pre class="code-snippet__js" data-lang=""><code>// 函数组合</code><code>const compose = (...fns) => </code><code> (value) => fns.reduceRight((acc, fn) => fn(acc), value);</code><code><br></code><code>const add5 = x => x + 5;</code><code>const double = x => x * 2;</code><code>const process = compose(double, add5);</code><code>console.log(process(10)); // (10+5)*2=30</code><code><br></code><code>// 柯里化实现</code><code>function curry(fn) {</code><code> return function curried(...args) {</code><code> if (args.length >= fn.length) {</code><code> return fn.apply(this, args);</code><code> } else {</code><code> return (...args2) => curried(...args, ...args2);</code><code> }</code><code> };</code><code>}</code><code><br></code><code>const curriedSum = curry((a, b, c) => a + b + c);</code><code>console.log(curriedSum(1)(2)(3)); // 6</code></pre>
<h3>2. 函数式编程实践</h3>
<pre class="code-snippet__js" data-lang=""><code>// 不可变数据转换</code><code>const users = [</code><code> { id: 1, name: 'Alice', age: 28 },</code><code> { id: 2, name: 'Bob', age: 35 }</code><code>];</code><code><br></code><code>// 纯函数处理</code><code>const getAdults = users =></code><code> users</code><code> .filter(user => user.age >= 18)</code><code> .map(({ id, name }) => ({ id, name }));</code><code><br></code><code>// 管道操作(ES2023)</code><code>const result = users</code><code> |> filter(_, u => u.age > 30)</code><code> |> map(_, u => ({ ...u, status: 'vip' }));</code></pre>
<hr>
<h2>ES6+ 函数增强特性</h2>
<h3>1. 参数处理新语法</h3>
<pre class="code-snippet__js" data-lang=""><code>// 默认参数</code><code>function createUser(name, { age = 18, role = 'user' } = {}) {</code><code> return { name, age, role };</code><code>}</code><code><br></code><code>// 剩余参数</code><code>function sumAll(...numbers) {</code><code> return numbers.reduce((acc, n) => acc + n, 0);</code><code>}</code><code><br></code><code>// 参数解构</code><code>function draw({ x = 0, y = 0, color = 'black' }) {</code><code> console.log(`在(${x},${y})绘制${color}`);</code><code>}</code></pre>
<h3>2. 元编程能力</h3>
<pre class="code-snippet__js" data-lang=""><code>// 函数元属性</code><code>function demo(a, b) {</code><code> console.log(demo.name); // "demo"</code><code> console.log(demo.length); // 2</code><code>}</code><code><br></code><code>// Reflect API</code><code>const handler = {</code><code> apply(target, thisArg, args) {</code><code> console.log(`调用函数并传入参数: ${args}`);</code><code> return Reflect.apply(...arguments);</code><code> }</code><code>};</code><code><br></code><code>const proxiedFunc = new Proxy(sum, handler);</code><code>proxiedFunc(2, 3); // 输出日志并返回5</code></pre>
<hr>
<h2>性能优化与调试技巧</h2>
<h3>1. 函数性能优化</h3>
<pre class="code-snippet__js" data-lang=""><code>// 避免重复创建函数</code><code>// 错误示例</code><code>elements.forEach(element => {</code><code> element.addEventListener('click', () => {</code><code> // 每次循环都创建新函数</code><code> });</code><code>});</code><code><br></code><code>// 优化方案</code><code>const handler = function(event) {</code><code> // 统一处理逻辑</code><code>};</code><code>elements.forEach(element => {</code><code> element.addEventListener('click', handler);</code><code>});</code><code><br></code><code>// 尾调用优化(TCO)</code><code>function factorial(n, acc = 1) {</code><code> if (n <= 1) return acc;</code><code> return factorial(n - 1, n * acc); // 尾递归形式</code><code>}</code></pre>
<h3>2. 调试技巧</h3>
<pre class="code-snippet__js" data-lang=""><code>// 函数断点调试</code><code>function complexCalculation() {</code><code> debugger; // 自动暂停执行</code><code> // ...</code><code>}</code><code><br></code><code>// 性能分析</code><code>console.time('heavyTask');</code><code>heavyTask();</code><code>console.timeEnd('heavyTask');</code><code><br></code><code>// 函数调用追踪</code><code>function trackCalls(fn) {</code><code> let count = 0;</code><code> return function(...args) {</code><code> count++;</code><code> console.log(`函数第${count}次调用`);</code><code> return fn(...args);</code><code> };</code><code>}</code></pre>
总结<ol class="list-paddingleft-1">
<li>
<p><strong>1.优先使用箭头函数</strong>:处理异步回调和需要保持this的场景</p>
</li>
<li>
<p><strong>2.合理使用闭包</strong>:注意内存管理,必要时使用<span>WeakMap</span></p>
</li>
<li>
<p><strong>3.避免过度嵌套</strong>:使用函数组合替代深层嵌套</p>
</li>
<li>
<p><strong>4.函数单一职责</strong>:每个函数只完成一个明确任务</p>
</li>
<li>
<p><strong>5.性能敏感区优化</strong>:避免在循环内创建函数</p>
</li>
<li>
<p><strong>6.严格模式启用</strong>:'use strict' 避免隐式错误</p>
</li>
<li>
<p><strong>7.全面类型检查</strong>:使用TypeScript增强函数可靠性</p>
</li>
</ol>
</div>
<div id="MySignature" role="contentinfo">
<!--
博客签名HTML
Austin Liu 刘恒辉
Project Manager and Software Designer
E-Mail: lzhdim@163.com
Blog: http://lzhdim.cnblogs.com
Date: 2022-03-23 18:00:00
使用方法:
//在博客里添加该代码
-->
<br><br>
<table cellpadding="0" cellspacing="0" class="field" style="background-color: #EEE; width: 100%">
<tbody>
<tr>
<td align="center" width="110px"><img
height="100px" src="https://images.cnblogs.com/cnblogs_com/lzhdim/636184/o_230607054137_lzhdim.png"
width="100px"></td>
<td align="left">
<span style="font-size: 10pt; color: #223355"> Austin Liu 刘恒辉</span>
<br><span style="font-size: 10pt; color: #223355"> Project Manager and Software Designer</span><br><br>
<span style="font-size: 10pt; color: #223355"> E-Mail:lzhdim@163.com</span><br>
<span style="font-size: 10pt; color: #223355"> Blog:https://lzhdim.cnblogs.com<br></span><br>
<span style="font-size: 10pt; color: #223355">
欢迎收藏和转载此博客中的博文,但是请注明出处,给笔者一个与大家交流的空间。谢谢大家。<br></span>
</td>
</tr>
</tbody>
</table><br><br>
来源:https://www.cnblogs.com/lzhdim/p/18796873
頁:
[1]