<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Learning on xiaotian's Blog</title><link>http://blog.xiaosky.top/tags/learning/</link><description>Recent content in Learning on xiaotian's Blog</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sun, 29 Mar 2026 12:00:00 +0800</lastBuildDate><atom:link href="http://blog.xiaosky.top/tags/learning/index.xml" rel="self" type="application/rss+xml"/><item><title>AI SDK</title><link>http://blog.xiaosky.top/posts/ai-sdk/</link><pubDate>Sun, 29 Mar 2026 12:00:00 +0800</pubDate><guid>http://blog.xiaosky.top/posts/ai-sdk/</guid><description>&lt;ol>
&lt;li>
&lt;p>安装AI工具包&lt;/p>
&lt;p>&lt;a href="https://ai-sdk.dev/">https://ai-sdk.dev/&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>安装依赖项&lt;/p>
&lt;p>&lt;code>npm install ai @ai-sdk/react zod&lt;/code>&lt;/p>
&lt;p>&lt;a href="https://ai-sdk.dev/docs/getting-started/tanstack-start">https://ai-sdk.dev/docs/getting-started/tanstack-start&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>配置.env&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>app/api/chat/route.ts&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-ts" data-lang="ts">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">import&lt;/span> { &lt;span style="color:#a6e22e">convertToModelMessages&lt;/span>, &lt;span style="color:#a6e22e">streamText&lt;/span>, &lt;span style="color:#a6e22e">UIMessage&lt;/span> } &lt;span style="color:#66d9ef">from&lt;/span> &lt;span style="color:#e6db74">&amp;#34;ai&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">import&lt;/span> { &lt;span style="color:#a6e22e">createDeepSeek&lt;/span> } &lt;span style="color:#66d9ef">from&lt;/span> &lt;span style="color:#e6db74">&amp;#34;@ai-sdk/deepseek&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Allow streaming responses up to 30 seconds
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">export&lt;/span> &lt;span style="color:#66d9ef">const&lt;/span> &lt;span style="color:#a6e22e">maxDuration&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">30&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">const&lt;/span> &lt;span style="color:#a6e22e">deepseek&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">createDeepSeek&lt;/span>({
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">apiKey&lt;/span>: &lt;span style="color:#66d9ef">process.env.DEEPSEEK_API_KEY&lt;/span> &lt;span style="color:#f92672">??&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">baseURL&lt;/span>: &lt;span style="color:#66d9ef">process.env.DEEPSEEK_BASE_URL&lt;/span> &lt;span style="color:#f92672">??&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>});
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">export&lt;/span> &lt;span style="color:#66d9ef">async&lt;/span> &lt;span style="color:#66d9ef">function&lt;/span> &lt;span style="color:#a6e22e">POST&lt;/span>(&lt;span style="color:#a6e22e">req&lt;/span>: &lt;span style="color:#66d9ef">Request&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">const&lt;/span> { &lt;span style="color:#a6e22e">messages&lt;/span> }&lt;span style="color:#f92672">:&lt;/span> { &lt;span style="color:#a6e22e">messages&lt;/span>: &lt;span style="color:#66d9ef">UIMessage&lt;/span>[] } &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">await&lt;/span> &lt;span style="color:#a6e22e">req&lt;/span>.&lt;span style="color:#a6e22e">json&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">const&lt;/span> &lt;span style="color:#a6e22e">result&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">streamText&lt;/span>({
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">model&lt;/span>: &lt;span style="color:#66d9ef">deepseek&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;deepseek-chat&amp;#34;&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">system&lt;/span>&lt;span style="color:#f92672">:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;You are a helpful assistant.&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">messages&lt;/span>: &lt;span style="color:#66d9ef">await&lt;/span> &lt;span style="color:#a6e22e">convertToModelMessages&lt;/span>(&lt;span style="color:#a6e22e">messages&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> });
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">result&lt;/span>.&lt;span style="color:#a6e22e">toUIMessageStreamResponse&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;a href="https://ai-sdk.dev/docs/ai-sdk-ui/chatbot">https://ai-sdk.dev/docs/ai-sdk-ui/chatbot&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>页面 &lt;code>page.tsx&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-tsx" data-lang="tsx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#34;use client&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">import&lt;/span> { &lt;span style="color:#a6e22e">useChat&lt;/span> } &lt;span style="color:#66d9ef">from&lt;/span> &lt;span style="color:#e6db74">&amp;#34;@ai-sdk/react&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">import&lt;/span> { &lt;span style="color:#a6e22e">useEffect&lt;/span>, &lt;span style="color:#a6e22e">useRef&lt;/span>, &lt;span style="color:#a6e22e">useState&lt;/span> } &lt;span style="color:#66d9ef">from&lt;/span> &lt;span style="color:#e6db74">&amp;#34;react&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">import&lt;/span> &lt;span style="color:#a6e22e">EastIcon&lt;/span> &lt;span style="color:#66d9ef">from&lt;/span> &lt;span style="color:#e6db74">&amp;#34;@mui/icons-material/East&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">export&lt;/span> &lt;span style="color:#66d9ef">default&lt;/span> &lt;span style="color:#66d9ef">function&lt;/span> &lt;span style="color:#a6e22e">Page() {&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">const&lt;/span> [&lt;span style="color:#a6e22e">model&lt;/span>, &lt;span style="color:#a6e22e">setModel&lt;/span>] &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">useState&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;deepseek-v3&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">const&lt;/span> [&lt;span style="color:#a6e22e">input&lt;/span>, &lt;span style="color:#a6e22e">setInput&lt;/span>] &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">useState&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">const&lt;/span> { &lt;span style="color:#a6e22e">messages&lt;/span>, &lt;span style="color:#a6e22e">sendMessage&lt;/span> } &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">useChat&lt;/span>({});
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">const&lt;/span> &lt;span style="color:#a6e22e">handleChangeModel&lt;/span> &lt;span style="color:#f92672">=&lt;/span> () &lt;span style="color:#f92672">=&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">setModel&lt;/span>(&lt;span style="color:#a6e22e">model&lt;/span> &lt;span style="color:#f92672">===&lt;/span> &lt;span style="color:#e6db74">&amp;#34;deepseek-v3&amp;#34;&lt;/span> &lt;span style="color:#f92672">?&lt;/span> &lt;span style="color:#e6db74">&amp;#34;deepseek-r1&amp;#34;&lt;/span> &lt;span style="color:#f92672">:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;deepseek-v3&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> };
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">const&lt;/span> &lt;span style="color:#a6e22e">handleSubmit&lt;/span> &lt;span style="color:#f92672">=&lt;/span> () &lt;span style="color:#f92672">=&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (&lt;span style="color:#a6e22e">input&lt;/span>.&lt;span style="color:#a6e22e">trim&lt;/span>()) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">sendMessage&lt;/span>({ &lt;span style="color:#a6e22e">text&lt;/span>: &lt;span style="color:#66d9ef">input&lt;/span> });
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">setInput&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> };
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">const&lt;/span> &lt;span style="color:#a6e22e">endRef&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">useRef&lt;/span>&amp;lt;&lt;span style="color:#f92672">HTMLDivElement&lt;/span>&amp;gt;(&lt;span style="color:#66d9ef">null&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">useEffect&lt;/span>(() &lt;span style="color:#f92672">=&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (&lt;span style="color:#a6e22e">endRef&lt;/span>.&lt;span style="color:#a6e22e">current&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">endRef&lt;/span>&lt;span style="color:#f92672">?&lt;/span>.&lt;span style="color:#a6e22e">current&lt;/span>&lt;span style="color:#f92672">?&lt;/span>.&lt;span style="color:#a6e22e">scrollIntoView&lt;/span>({ &lt;span style="color:#a6e22e">behavior&lt;/span>&lt;span style="color:#f92672">:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;smooth&amp;#34;&lt;/span> });
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }, [&lt;span style="color:#a6e22e">messages&lt;/span>]);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">div&lt;/span> &lt;span style="color:#a6e22e">className&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;flex flex-col h-screen justify-between items-center&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">div&lt;/span> &lt;span style="color:#a6e22e">className&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;flex flex-col w-2/3 gap-8 overflow-y-auto justify-between flex-1&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">div&lt;/span> &lt;span style="color:#a6e22e">className&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;h-4&amp;#34;&lt;/span>&amp;gt;&amp;lt;/&lt;span style="color:#f92672">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">div&lt;/span> &lt;span style="color:#a6e22e">className&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;flex flex-col gap-8 flex-1&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {&lt;span style="color:#a6e22e">messages&lt;/span>&lt;span style="color:#f92672">?&lt;/span>.&lt;span style="color:#a6e22e">map&lt;/span>((&lt;span style="color:#a6e22e">message&lt;/span>) &lt;span style="color:#f92672">=&amp;gt;&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">div&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">key&lt;/span>&lt;span style="color:#f92672">=&lt;/span>{&lt;span style="color:#a6e22e">message&lt;/span>.&lt;span style="color:#a6e22e">id&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">className&lt;/span>&lt;span style="color:#f92672">=&lt;/span>{&lt;span style="color:#e6db74">`rounded-lg flex flex-row &lt;/span>&lt;span style="color:#e6db74">${&lt;/span>&lt;span style="color:#a6e22e">message&lt;/span>&lt;span style="color:#f92672">?&lt;/span>.&lt;span style="color:#a6e22e">role&lt;/span> &lt;span style="color:#f92672">===&lt;/span> &lt;span style="color:#e6db74">&amp;#34;assistant&amp;#34;&lt;/span> &lt;span style="color:#f92672">?&lt;/span> &lt;span style="color:#e6db74">&amp;#34;justify-start mr-18&amp;#34;&lt;/span> &lt;span style="color:#f92672">:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;justify-end ml-10&amp;#34;&lt;/span>&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">`&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">p&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">className&lt;/span>&lt;span style="color:#f92672">=&lt;/span>{&lt;span style="color:#e6db74">`inline-block p-2 rounded-lg &lt;/span>&lt;span style="color:#e6db74">${&lt;/span>&lt;span style="color:#a6e22e">message&lt;/span>&lt;span style="color:#f92672">?&lt;/span>.&lt;span style="color:#a6e22e">role&lt;/span> &lt;span style="color:#f92672">===&lt;/span> &lt;span style="color:#e6db74">&amp;#34;assistant&amp;#34;&lt;/span> &lt;span style="color:#f92672">?&lt;/span> &lt;span style="color:#e6db74">&amp;#34;bg-blue-300&amp;#34;&lt;/span> &lt;span style="color:#f92672">:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;bg-slate-100&amp;#34;&lt;/span>&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">`&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {&lt;span style="color:#a6e22e">message&lt;/span>.&lt;span style="color:#a6e22e">parts&lt;/span>.&lt;span style="color:#a6e22e">map&lt;/span>((&lt;span style="color:#a6e22e">part&lt;/span>, &lt;span style="color:#a6e22e">index&lt;/span>) &lt;span style="color:#f92672">=&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">part&lt;/span>.&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#f92672">===&lt;/span> &lt;span style="color:#e6db74">&amp;#34;text&amp;#34;&lt;/span> &lt;span style="color:#f92672">?&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">span&lt;/span> &lt;span style="color:#a6e22e">key&lt;/span>&lt;span style="color:#f92672">=&lt;/span>{&lt;span style="color:#a6e22e">index&lt;/span>}&amp;gt;{&lt;span style="color:#a6e22e">part&lt;/span>.&lt;span style="color:#a6e22e">text&lt;/span>}&amp;lt;/&lt;span style="color:#f92672">span&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ) &lt;span style="color:#f92672">:&lt;/span> &lt;span style="color:#66d9ef">null&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> )}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;/&lt;span style="color:#f92672">p&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;/&lt;span style="color:#f92672">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ))}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;/&lt;span style="color:#f92672">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">div&lt;/span> &lt;span style="color:#a6e22e">className&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;h-4&amp;#34;&lt;/span> &lt;span style="color:#a6e22e">ref&lt;/span>&lt;span style="color:#f92672">=&lt;/span>{&lt;span style="color:#a6e22e">endRef&lt;/span>}&amp;gt;&amp;lt;/&lt;span style="color:#f92672">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;/&lt;span style="color:#f92672">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {&lt;span style="color:#75715e">/* 输入框 */&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">div&lt;/span> &lt;span style="color:#a6e22e">className&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;flex flex-col items-center justify-center mt-4 shadow-lg border-[1px] border-gray-300 h-32 rounded-lg w-2/3&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">textarea&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">className&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;w-full rounded-lg p-3 h-30 focus:outline-none&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">value&lt;/span>&lt;span style="color:#f92672">=&lt;/span>{&lt;span style="color:#a6e22e">input&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">onChange&lt;/span>&lt;span style="color:#f92672">=&lt;/span>{(&lt;span style="color:#a6e22e">e&lt;/span>) &lt;span style="color:#f92672">=&amp;gt;&lt;/span> &lt;span style="color:#a6e22e">setInput&lt;/span>(&lt;span style="color:#a6e22e">e&lt;/span>.&lt;span style="color:#a6e22e">target&lt;/span>.&lt;span style="color:#a6e22e">value&lt;/span>)}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;gt;&amp;lt;/&lt;span style="color:#f92672">textarea&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">div&lt;/span> &lt;span style="color:#a6e22e">className&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;flex flex-row items-center justify-between w-full h-12 mb-2&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">div&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">className&lt;/span>&lt;span style="color:#f92672">=&lt;/span>{&lt;span style="color:#e6db74">`flex flex-row items-center justify-center rounded-lg border-[1px] px-2 py-1 ml-2 cursor-pointer &lt;/span>&lt;span style="color:#e6db74">${&lt;/span>&lt;span style="color:#a6e22e">model&lt;/span> &lt;span style="color:#f92672">===&lt;/span> &lt;span style="color:#e6db74">&amp;#34;deepseek-r1&amp;#34;&lt;/span> &lt;span style="color:#f92672">?&lt;/span> &lt;span style="color:#e6db74">&amp;#34;border-blue-300 bg-blue-200&amp;#34;&lt;/span> &lt;span style="color:#f92672">:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;border-gray-300&amp;#34;&lt;/span>&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">`&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">onClick&lt;/span>&lt;span style="color:#f92672">=&lt;/span>{&lt;span style="color:#a6e22e">handleChangeModel&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">p&lt;/span> &lt;span style="color:#a6e22e">className&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;text-sm&amp;#34;&lt;/span>&amp;gt;&lt;span style="color:#960050;background-color:#1e0010">深度思考&lt;/span>(&lt;span style="color:#a6e22e">R1&lt;/span>)&amp;lt;/&lt;span style="color:#f92672">p&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;/&lt;span style="color:#f92672">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;/&lt;span style="color:#f92672">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">div&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">className&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;flex items-center justify-center border-2 mr-4 border-black p-1 rounded-full&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">onClick&lt;/span>&lt;span style="color:#f92672">=&lt;/span>{&lt;span style="color:#a6e22e">handleSubmit&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#f92672">EastIcon&lt;/span>&amp;gt;&amp;lt;/&lt;span style="color:#f92672">EastIcon&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;/&lt;span style="color:#f92672">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;/&lt;span style="color:#f92672">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;/&lt;span style="color:#f92672">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;/&lt;span style="color:#f92672">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> );
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ol></description></item><item><title>eventLoop</title><link>http://blog.xiaosky.top/posts/eventloop/</link><pubDate>Sun, 29 Mar 2026 12:00:00 +0800</pubDate><guid>http://blog.xiaosky.top/posts/eventloop/</guid><description/></item><item><title>NeetCode Roadmap</title><link>http://blog.xiaosky.top/posts/neetcode-roadmap/</link><pubDate>Sun, 29 Mar 2026 12:00:00 +0800</pubDate><guid>http://blog.xiaosky.top/posts/neetcode-roadmap/</guid><description>&lt;ul>
&lt;li>
&lt;p>&lt;strong>第一阶段：核心基础&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Arrays &amp;amp; Hashing (数组与哈希表)
&lt;ul>
&lt;li>Two Pointers (双指针)&lt;/li>
&lt;li>Stack (栈)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>第二阶段：线性结构进阶&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Binary Search (二分查找)&lt;/li>
&lt;li>Sliding Window (滑动窗口)&lt;/li>
&lt;li>Linked List (链表)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>第三阶段：树与堆 (核心枢纽)&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Trees (树)&lt;/strong>
&lt;ul>
&lt;li>Tries (前缀树)&lt;/li>
&lt;li>Heap / Priority Queue (堆/优先队列)&lt;/li>
&lt;li>Backtracking (回溯)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>第四阶段：高级算法与图论&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>从堆延伸：&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Intervals (区间)&lt;/li>
&lt;li>Greedy (贪心)&lt;/li>
&lt;li>Advanced Graphs (高级图论)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>从回溯延伸：&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Graphs (图)&lt;/li>
&lt;li>1-D DP (一维动态规划)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>第五阶段：深度优化与综合&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>2-D DP (二维动态规划)&lt;/li>
&lt;li>Bit Manipulation (位运算)&lt;/li>
&lt;li>Math &amp;amp; Geometry (数学与几何)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="合并两个有序链表">合并两个有序链表&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">function&lt;/span> &lt;span style="color:#a6e22e">mergeTwoLists&lt;/span>(&lt;span style="color:#a6e22e">list1&lt;/span>, &lt;span style="color:#a6e22e">list2&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 递归终止：其中一个链表为空，直接返回另一个
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">if&lt;/span> (&lt;span style="color:#f92672">!&lt;/span>&lt;span style="color:#a6e22e">list1&lt;/span>) &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">list2&lt;/span>; &lt;span style="color:#75715e">// list1 空了，list2 剩下的全接上
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">if&lt;/span> (&lt;span style="color:#f92672">!&lt;/span>&lt;span style="color:#a6e22e">list2&lt;/span>) &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">list1&lt;/span>; &lt;span style="color:#75715e">// list2 空了，list1 剩下的全接上
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 比较头节点，小的作为当前节点
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">if&lt;/span> (&lt;span style="color:#a6e22e">list1&lt;/span>.&lt;span style="color:#a6e22e">val&lt;/span> &lt;span style="color:#f92672">&amp;lt;=&lt;/span> &lt;span style="color:#a6e22e">list2&lt;/span>.&lt;span style="color:#a6e22e">val&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// list1 小，list1 当头
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#a6e22e">list1&lt;/span>.&lt;span style="color:#a6e22e">next&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">mergeTwoLists&lt;/span>(&lt;span style="color:#a6e22e">list1&lt;/span>.&lt;span style="color:#a6e22e">next&lt;/span>, &lt;span style="color:#a6e22e">list2&lt;/span>); &lt;span style="color:#75715e">// list1.next 指向合并后的结果
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">list1&lt;/span>; &lt;span style="color:#75715e">// 返回当前头节点
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> } &lt;span style="color:#66d9ef">else&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// list2 小，list2 当头
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#a6e22e">list2&lt;/span>.&lt;span style="color:#a6e22e">next&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">mergeTwoLists&lt;/span>(&lt;span style="color:#a6e22e">list1&lt;/span>, &lt;span style="color:#a6e22e">list2&lt;/span>.&lt;span style="color:#a6e22e">next&lt;/span>); &lt;span style="color:#75715e">// list2.next 指向合并后的结果
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">list2&lt;/span>; &lt;span style="color:#75715e">// 返回当前头节点
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>执行流程：&lt;/p></description></item><item><title>Taildwind CSS</title><link>http://blog.xiaosky.top/posts/tailwind-css-%E7%B1%BB%E5%90%8D%E7%9A%84%E8%AF%A6%E7%BB%86%E6%B3%A8%E9%87%8A/</link><pubDate>Sun, 29 Mar 2026 12:00:00 +0800</pubDate><guid>http://blog.xiaosky.top/posts/tailwind-css-%E7%B1%BB%E5%90%8D%E7%9A%84%E8%AF%A6%E7%BB%86%E6%B3%A8%E9%87%8A/</guid><description>&lt;h3 id="1-尺寸与定位-sizing--layout">1. 尺寸与定位 (Sizing &amp;amp; Layout)&lt;/h3>
&lt;ul>
&lt;li>&lt;code>h-screen&lt;/code>: 高度等于 &lt;strong>100vh&lt;/strong>（视口高度）。&lt;/li>
&lt;li>&lt;code>h-min-screen&lt;/code>: 最小高度等于 &lt;strong>100vh&lt;/strong>（保证至少撑满屏幕，内容多时可扩展）。&lt;/li>
&lt;li>&lt;code>w-screen&lt;/code>: 宽度等于 &lt;strong>100vw&lt;/strong>（视口宽度）。&lt;/li>
&lt;li>&lt;code>w-3/4&lt;/code>: 宽度设置为 &lt;strong>75%&lt;/strong>。&lt;/li>
&lt;li>&lt;code>h-full&lt;/code>: 高度设置为 &lt;strong>100%&lt;/strong>（相对于父元素高度）。&lt;/li>
&lt;li>&lt;code>w-full&lt;/code>: 宽度设置为 &lt;strong>100%&lt;/strong>。&lt;/li>
&lt;li>&lt;code>gap-4&lt;/code>: 网格或弹性布局的间隙大小（通常为 &lt;strong>1rem / 16px&lt;/strong>）。&lt;/li>
&lt;/ul>
&lt;h3 id="2-背景与边框-background--borders">2. 背景与边框 (Background &amp;amp; Borders)&lt;/h3>
&lt;ul>
&lt;li>&lt;code>bg-slate-50&lt;/code>: 背景颜色设为极浅的石板色。&lt;/li>
&lt;li>&lt;code>bg-white&lt;/code>: 背景颜色设为白色。&lt;/li>
&lt;li>&lt;code>hover:bg-slate-200&lt;/code>: 鼠标悬停时背景变为浅灰色（石板色 200）。&lt;/li>
&lt;li>&lt;code>rounded-full&lt;/code>: 彻底圆角（通常用于制作圆形按钮或药丸形状）。&lt;/li>
&lt;li>&lt;code>rounded-md&lt;/code>: 中等圆角（标准卡片或按钮常用）。&lt;/li>
&lt;/ul>
&lt;h3 id="3-间距-spacing">3. 间距 (Spacing)&lt;/h3>
&lt;ul>
&lt;li>&lt;code>p-1&lt;/code>: 四周内边距（Padding）为 &lt;strong>0.25rem / 4px&lt;/strong>。&lt;/li>
&lt;li>&lt;code>p-4&lt;/code>: 四周内边距为 &lt;strong>1rem / 16px&lt;/strong>。&lt;/li>
&lt;li>&lt;code>px-4&lt;/code>: 左右（水平方向）内边距为 &lt;strong>1rem / 16px&lt;/strong>。&lt;/li>
&lt;/ul>
&lt;h3 id="4-文本样式-typography">4. 文本样式 (Typography)&lt;/h3>
&lt;ul>
&lt;li>&lt;code>text-2xl&lt;/code>: 字体大小设置为 &lt;strong>1.5rem / 24px&lt;/strong>，行高 &lt;strong>2rem&lt;/strong>。&lt;/li>
&lt;li>&lt;code>font-bold&lt;/code>: 字体加粗。&lt;/li>
&lt;li>&lt;code>text-xs&lt;/code>: 最小字体大小（通常为 &lt;strong>12px&lt;/strong>）。&lt;/li>
&lt;li>&lt;code>tracking-widest&lt;/code>: 字符间距最大化（增加字母之间的空隙）。&lt;/li>
&lt;li>&lt;code>text-gray-500&lt;/code>: 文字颜色设为中灰色。&lt;/li>
&lt;/ul>
&lt;h3 id="5-响应式与复杂布局-responsive--advanced">5. 响应式与复杂布局 (Responsive &amp;amp; Advanced)&lt;/h3>
&lt;ul>
&lt;li>&lt;code>sm:w-1/2&lt;/code>: 在 &lt;strong>sm&lt;/strong> 屏幕（≥640px）及以上时，宽度为 &lt;strong>50%&lt;/strong>。&lt;/li>
&lt;li>&lt;code>lg:w-1/5&lt;/code>: 在 &lt;strong>lg&lt;/strong> 屏幕（≥1024px）及以上时，宽度为 &lt;strong>20%&lt;/strong>。&lt;/li>
&lt;li>&lt;code>flex-row&lt;/code>: 弹性布局方向为水平行。&lt;/li>
&lt;li>&lt;code>scroll-auto&lt;/code>: 溢出时根据内容自动显示滚动条。&lt;/li>
&lt;li>&lt;code>cursor-pointer&lt;/code>: 鼠标悬停时显示小手图标（点击反馈）。&lt;/li>
&lt;li>&lt;code>line-clamp-1&lt;/code>: 文本超出 1 行时显示省略号。&lt;/li>
&lt;li>&lt;code>line-clamp-2&lt;/code>: 文本超出 2 行时显示省略号。&lt;/li>
&lt;/ul></description></item><item><title>V8 引擎的底层逻辑</title><link>http://blog.xiaosky.top/posts/js%E5%BC%95%E6%93%8E%E8%A7%A3%E6%9E%90%E4%BB%A3%E7%A0%81%E7%9A%84%E5%BA%95%E5%B1%82%E9%80%BB%E8%BE%91/</link><pubDate>Sun, 29 Mar 2026 12:00:00 +0800</pubDate><guid>http://blog.xiaosky.top/posts/js%E5%BC%95%E6%93%8E%E8%A7%A3%E6%9E%90%E4%BB%A3%E7%A0%81%E7%9A%84%E5%BA%95%E5%B1%82%E9%80%BB%E8%BE%91/</guid><description/></item><item><title>var_let_const 的区别</title><link>http://blog.xiaosky.top/posts/var_let_const%E7%9A%84%E5%8C%BA%E5%88%AB/</link><pubDate>Sun, 29 Mar 2026 12:00:00 +0800</pubDate><guid>http://blog.xiaosky.top/posts/var_let_const%E7%9A%84%E5%8C%BA%E5%88%AB/</guid><description/></item><item><title>作用域</title><link>http://blog.xiaosky.top/posts/%E4%BD%9C%E7%94%A8%E5%9F%9F/</link><pubDate>Sun, 29 Mar 2026 12:00:00 +0800</pubDate><guid>http://blog.xiaosky.top/posts/%E4%BD%9C%E7%94%A8%E5%9F%9F/</guid><description/></item><item><title>函数柯里化</title><link>http://blog.xiaosky.top/posts/%E6%9F%AF%E9%87%8C%E5%8C%96/</link><pubDate>Sun, 29 Mar 2026 12:00:00 +0800</pubDate><guid>http://blog.xiaosky.top/posts/%E6%9F%AF%E9%87%8C%E5%8C%96/</guid><description>&lt;h2 id="函数柯里化">函数柯里化&lt;/h2>
&lt;blockquote>
&lt;p>将一个接收&lt;strong>多个参数&lt;/strong>的函数转换成一系列只接收&lt;strong>单个参数&lt;/strong>的嵌套函数。&lt;/p>&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">function&lt;/span> &lt;span style="color:#a6e22e">sum&lt;/span>(&lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#a6e22e">y&lt;/span>, &lt;span style="color:#a6e22e">z&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">x&lt;/span> &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#a6e22e">y&lt;/span> &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#a6e22e">z&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">function&lt;/span> &lt;span style="color:#a6e22e">sum2&lt;/span>(&lt;span style="color:#a6e22e">x&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#66d9ef">function&lt;/span> (&lt;span style="color:#a6e22e">y&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">x&lt;/span> &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#a6e22e">y&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> };
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">function&lt;/span> &lt;span style="color:#a6e22e">curry&lt;/span>(&lt;span style="color:#a6e22e">fn&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#66d9ef">function&lt;/span> (&lt;span style="color:#a6e22e">x&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#66d9ef">function&lt;/span> (&lt;span style="color:#a6e22e">y&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#66d9ef">function&lt;/span> (&lt;span style="color:#a6e22e">z&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">fn&lt;/span>(&lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#a6e22e">y&lt;/span>, &lt;span style="color:#a6e22e">z&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> };
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> };
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> };
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">curriedSum&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">curry&lt;/span>((&lt;span style="color:#a6e22e">x&lt;/span>, &lt;span style="color:#a6e22e">y&lt;/span>, &lt;span style="color:#a6e22e">z&lt;/span>) =&amp;gt; {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">x&lt;/span> &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#a6e22e">y&lt;/span> &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#a6e22e">z&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>});
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">console&lt;/span>.&lt;span style="color:#a6e22e">log&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;sum:&amp;#34;&lt;/span> &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#a6e22e">sum&lt;/span>(&lt;span style="color:#ae81ff">1&lt;/span>, &lt;span style="color:#ae81ff">2&lt;/span>, &lt;span style="color:#ae81ff">3&lt;/span>));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">console&lt;/span>.&lt;span style="color:#a6e22e">log&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;sum2:&amp;#34;&lt;/span> &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#a6e22e">sum2&lt;/span>(&lt;span style="color:#ae81ff">1&lt;/span>)(&lt;span style="color:#ae81ff">2&lt;/span>));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">console&lt;/span>.&lt;span style="color:#a6e22e">log&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;curriedSum:&amp;#34;&lt;/span> &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#a6e22e">curriedSum&lt;/span>(&lt;span style="color:#ae81ff">1&lt;/span>)(&lt;span style="color:#ae81ff">2&lt;/span>)(&lt;span style="color:#ae81ff">3&lt;/span>));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// curry(func) 的结果就是一个包装器 function(x)。
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// 当它被像 curriedSum(1) 这样调用时，它的参数会被保存在词法环境中，然后返回一个新的包装器 function(y)。
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// 然后这个包装器被以 2 为参数调用，最终它将该调用传递给原始的 func 函数。
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="偏函数">偏函数&lt;/h2>
&lt;p>&lt;strong>偏函数（Partial Function）&lt;/strong> 是指固定一个函数的&lt;strong>部分参数&lt;/strong>，从而得到一个&lt;strong>接收剩余参数的新函数&lt;/strong>。&lt;/p>
&lt;h2 id="应用">应用：&lt;/h2>
&lt;p>实现一个柯里化（currying）版本的 &lt;code>log&lt;/code> 函数&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// 1. 原始 log 函数
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">function&lt;/span> &lt;span style="color:#a6e22e">log&lt;/span>(&lt;span style="color:#a6e22e">date&lt;/span>, &lt;span style="color:#a6e22e">importance&lt;/span>, &lt;span style="color:#a6e22e">message&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">alert&lt;/span>(&lt;span style="color:#e6db74">`[&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>&lt;span style="color:#a6e22e">date&lt;/span>.&lt;span style="color:#a6e22e">getHours&lt;/span>()&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">:&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>&lt;span style="color:#a6e22e">date&lt;/span>.&lt;span style="color:#a6e22e">getMinutes&lt;/span>()&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">] [&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>&lt;span style="color:#a6e22e">importance&lt;/span>&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">] &lt;/span>&lt;span style="color:#e6db74">${&lt;/span>&lt;span style="color:#a6e22e">message&lt;/span>&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">`&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// 2. 通用 curry 函数
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">function&lt;/span> &lt;span style="color:#a6e22e">curry&lt;/span>(&lt;span style="color:#a6e22e">fn&lt;/span>){
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#66d9ef">function&lt;/span> &lt;span style="color:#a6e22e">curried&lt;/span>(...&lt;span style="color:#a6e22e">args&lt;/span>){
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 检查当前传入的参数数量是否足够调用原函数
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">if&lt;/span> (&lt;span style="color:#a6e22e">args&lt;/span>.&lt;span style="color:#a6e22e">length&lt;/span> &lt;span style="color:#f92672">&amp;gt;=&lt;/span> &lt;span style="color:#a6e22e">fn&lt;/span>.&lt;span style="color:#a6e22e">length&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">fn&lt;/span>.&lt;span style="color:#a6e22e">apply&lt;/span>(&lt;span style="color:#66d9ef">this&lt;/span>, &lt;span style="color:#a6e22e">args&lt;/span>)&lt;span style="color:#75715e">// 调用原函数
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> }&lt;span style="color:#66d9ef">else&lt;/span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// 返回一个新函数以继续收集参数
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#66d9ef">function&lt;/span>(...&lt;span style="color:#a6e22e">nextArgs&lt;/span>){
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">curried&lt;/span>.&lt;span style="color:#a6e22e">apply&lt;/span>(&lt;span style="color:#66d9ef">this&lt;/span>, &lt;span style="color:#a6e22e">args&lt;/span>.&lt;span style="color:#a6e22e">concat&lt;/span>(&lt;span style="color:#a6e22e">nextArgs&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// 3. 柯里化 log
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">const&lt;/span> &lt;span style="color:#a6e22e">curriedLog&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">curry&lt;/span>(&lt;span style="color:#a6e22e">log&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// 4. 测试：正常调用
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#a6e22e">curriedLog&lt;/span>(&lt;span style="color:#66d9ef">new&lt;/span> Date(), &lt;span style="color:#e6db74">&amp;#34;DEBUG&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;normal call&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// 5. 测试：柯里化调用
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#a6e22e">curriedLog&lt;/span>(&lt;span style="color:#66d9ef">new&lt;/span> Date())(&lt;span style="color:#e6db74">&amp;#34;INFO&amp;#34;&lt;/span>)(&lt;span style="color:#e6db74">&amp;#34;curried call&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// 6. 偏函数
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">const&lt;/span> &lt;span style="color:#a6e22e">now&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> Date()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">const&lt;/span> &lt;span style="color:#a6e22e">logNow&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">log&lt;/span>(&lt;span style="color:#66d9ef">new&lt;/span> Date())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">logNow&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;WARN&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;partial applied&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// 7. 进一步偏函数
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">const&lt;/span> &lt;span style="color:#a6e22e">debugNow&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">logNow&lt;/span>(&lt;span style="color:#e6db74">&amp;#39;DEBUG&amp;#39;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">debugNow&lt;/span>(&lt;span style="color:#e6db74">&amp;#39;deep partial&amp;#39;&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>闭包</title><link>http://blog.xiaosky.top/posts/%E9%97%AD%E5%8C%85/</link><pubDate>Sun, 29 Mar 2026 12:00:00 +0800</pubDate><guid>http://blog.xiaosky.top/posts/%E9%97%AD%E5%8C%85/</guid><description/></item></channel></rss>