汤大官人 發表於 2025-5-15 09:00:00

(转载)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>&nbsp; return a + b;</code><code>}</code><code><br></code><code>// 2. 函数表达式</code><code>const multiply = function(a, b) {</code><code>&nbsp; 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) =&gt; base ** exponent;</code><code><br></code><code>// 5. 简写方法语法</code><code>const calculator = {</code><code>&nbsp; sqrt(x) {</code><code>&nbsp; &nbsp; return Math.sqrt(x);</code><code>&nbsp; }</code><code>};</code><code><br></code><code>// 6. 生成器函数</code><code>function* idGenerator() {</code><code>&nbsp; let id = 1;</code><code>&nbsp; while(true) yield id++;</code><code>}</code><code><br></code><code>// 7. Async函数</code><code>async function fetchData(url) {</code><code>&nbsp; const res = await fetch(url);</code><code>&nbsp; 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>&nbsp; const outerVar = '外层';</code><code><br></code><code>&nbsp; function inner() {</code><code>&nbsp; &nbsp; const innerVar = '内层';</code><code>&nbsp; &nbsp; console.log(outerVar); // 访问外层作用域</code><code>&nbsp; }</code><code><br></code><code>&nbsp; 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>&nbsp; let count = 0;</code><code><br></code><code>&nbsp; return {</code><code>&nbsp; &nbsp; increment() { count++ },</code><code>&nbsp; &nbsp; get() { return count },</code><code>&nbsp; &nbsp; reset() { count = 0 }</code><code>&nbsp; };</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>&nbsp; const cache = new Map();</code><code><br></code><code>&nbsp; return function(...args) {</code><code>&nbsp; &nbsp; const key = JSON.stringify(args);</code><code>&nbsp; &nbsp; if (cache.has(key)) return cache.get(key);</code><code><br></code><code>&nbsp; &nbsp; const result = fn(...args);</code><code>&nbsp; &nbsp; cache.set(key, result);</code><code>&nbsp; &nbsp; return result;</code><code>&nbsp; };</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>&nbsp; const element = document.getElementById('bigData');</code><code>&nbsp; element.addEventListener('click', () =&gt; {</code><code>&nbsp; &nbsp; console.log(element.id); // 闭包保留element引用</code><code>&nbsp; });</code><code>}</code><code><br></code><code>// 正确做法:弱引用</code><code>function safeInit() {</code><code>&nbsp; const element = document.getElementById('bigData');</code><code>&nbsp; const weakRef = new WeakRef(element);</code><code><br></code><code>&nbsp; element.addEventListener('click', () =&gt; {</code><code>&nbsp; &nbsp; const el = weakRef.deref();</code><code>&nbsp; &nbsp; if (el) console.log(el.id);</code><code>&nbsp; });</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>&nbsp; console.log(this); // window/global</code><code>}</code><code><br></code><code>// 2. 隐式绑定</code><code>const obj = {</code><code>&nbsp; value: 42,</code><code>&nbsp; getValue() {</code><code>&nbsp; &nbsp; return this.value;</code><code>&nbsp; }</code><code>};</code><code><br></code><code>// 3. 显式绑定</code><code>function logThis() {</code><code>&nbsp; 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>&nbsp; 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 = () =&gt; {</code><code>&nbsp; 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>&nbsp; constructor() {</code><code>&nbsp; &nbsp; this.seconds = 0;</code><code>&nbsp; &nbsp; // 使用箭头函数保留this</code><code>&nbsp; &nbsp; setInterval(() =&gt; {</code><code>&nbsp; &nbsp; &nbsp; this.seconds++;</code><code>&nbsp; &nbsp; }, 1000);</code><code>&nbsp; }</code><code>}</code><code><br></code><code>// 多层嵌套this访问</code><code>const deepObj = {</code><code>&nbsp; level1: {</code><code>&nbsp; &nbsp; level2: {</code><code>&nbsp; &nbsp; &nbsp; method() {</code><code>&nbsp; &nbsp; &nbsp; &nbsp; // 使用箭头函数维持this指向</code><code>&nbsp; &nbsp; &nbsp; &nbsp; const helper = () =&gt; {</code><code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(this); // 指向level2对象</code><code>&nbsp; &nbsp; &nbsp; &nbsp; };</code><code>&nbsp; &nbsp; &nbsp; &nbsp; helper();</code><code>&nbsp; &nbsp; &nbsp; }</code><code>&nbsp; &nbsp; }</code><code>&nbsp; }</code><code>};</code></pre>
<hr>
<h2>高阶函数与函数式编程</h2>
<h3>1. 高阶函数应用</h3>
<pre class="code-snippet__js" data-lang=""><code>// 函数组合</code><code>const compose = (...fns) =&gt;&nbsp;</code><code>&nbsp; (value) =&gt; fns.reduceRight((acc, fn) =&gt; fn(acc), value);</code><code><br></code><code>const add5 = x =&gt; x + 5;</code><code>const double = x =&gt; 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>&nbsp; return function curried(...args) {</code><code>&nbsp; &nbsp; if (args.length &gt;= fn.length) {</code><code>&nbsp; &nbsp; &nbsp; return fn.apply(this, args);</code><code>&nbsp; &nbsp; } else {</code><code>&nbsp; &nbsp; &nbsp; return (...args2) =&gt; curried(...args, ...args2);</code><code>&nbsp; &nbsp; }</code><code>&nbsp; };</code><code>}</code><code><br></code><code>const curriedSum = curry((a, b, c) =&gt; 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>&nbsp; { id: 1, name: 'Alice', age: 28 },</code><code>&nbsp; { id: 2, name: 'Bob', age: 35 }</code><code>];</code><code><br></code><code>// 纯函数处理</code><code>const getAdults = users =&gt;</code><code>&nbsp; users</code><code>&nbsp; &nbsp; .filter(user =&gt; user.age &gt;= 18)</code><code>&nbsp; &nbsp; .map(({ id, name }) =&gt; ({ id, name }));</code><code><br></code><code>// 管道操作(ES2023)</code><code>const result = users</code><code>&nbsp; |&gt; filter(_, u =&gt; u.age &gt; 30)</code><code>&nbsp; |&gt; map(_, u =&gt; ({ ...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>&nbsp; return { name, age, role };</code><code>}</code><code><br></code><code>// 剩余参数</code><code>function sumAll(...numbers) {</code><code>&nbsp; return numbers.reduce((acc, n) =&gt; acc + n, 0);</code><code>}</code><code><br></code><code>// 参数解构</code><code>function draw({ x = 0, y = 0, color = 'black' }) {</code><code>&nbsp; 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>&nbsp; console.log(demo.name); &nbsp; &nbsp; &nbsp;// "demo"</code><code>&nbsp; console.log(demo.length); &nbsp; &nbsp;// 2</code><code>}</code><code><br></code><code>// Reflect API</code><code>const handler = {</code><code>&nbsp; apply(target, thisArg, args) {</code><code>&nbsp; &nbsp; console.log(`调用函数并传入参数: ${args}`);</code><code>&nbsp; &nbsp; return Reflect.apply(...arguments);</code><code>&nbsp; }</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 =&gt; {</code><code>&nbsp; element.addEventListener('click', () =&gt; {</code><code>&nbsp; &nbsp; // 每次循环都创建新函数</code><code>&nbsp; });</code><code>});</code><code><br></code><code>// 优化方案</code><code>const handler = function(event) {</code><code>&nbsp; // 统一处理逻辑</code><code>};</code><code>elements.forEach(element =&gt; {</code><code>&nbsp; element.addEventListener('click', handler);</code><code>});</code><code><br></code><code>// 尾调用优化(TCO)</code><code>function factorial(n, acc = 1) {</code><code>&nbsp; if (n &lt;= 1) return acc;</code><code>&nbsp; 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>&nbsp; debugger; // 自动暂停执行</code><code>&nbsp; // ...</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>&nbsp; let count = 0;</code><code>&nbsp; return function(...args) {</code><code>&nbsp; &nbsp; count++;</code><code>&nbsp; &nbsp; console.log(`函数第${count}次调用`);</code><code>&nbsp; &nbsp; return fn(...args);</code><code>&nbsp; };</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">&nbsp;&nbsp;&nbsp; Austin Liu&nbsp; 刘恒辉</span>
            <br><span style="font-size: 10pt; color: #223355">&nbsp;&nbsp;&nbsp; Project Manager and Software Designer</span><br><br>
            <span style="font-size: 10pt; color: #223355">&nbsp;&nbsp;&nbsp; E-Mail:lzhdim@163.com</span><br>
            <span style="font-size: 10pt; color: #223355">&nbsp;&nbsp;&nbsp; Blog:https://lzhdim.cnblogs.com<br></span><br>
            <span style="font-size: 10pt; color: #223355">&nbsp;&nbsp;&nbsp;
                  欢迎收藏和转载此博客中的博文,但是请注明出处,给笔者一个与大家交流的空间。谢谢大家。<br></span>
      </td>
    </tr>
    </tbody>
</table><br><br>
来源:https://www.cnblogs.com/lzhdim/p/18796873
頁: [1]
查看完整版本: (转载)20个JavaScript重点知识点(2)函数