<?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>Methods on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/methods/</link><description>Recent content in Methods on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sun, 15 Dec 2024 00:00:00 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/methods/index.xml" rel="self" type="application/rss+xml"/><item><title>methods</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/vue/methods/</link><pubDate>Fri, 04 Oct 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/vue/methods/</guid><description>&lt;h2 id="methods-的初始化"&gt;Methods 的初始化&lt;/h2&gt;
&lt;p&gt;在 Vue.js 中，每个组件实例（&lt;code&gt;vm&lt;/code&gt;）都会有一个 &lt;code&gt;methods&lt;/code&gt; 属性，这个属性包含了组件中定义的所有方法。这些方法需要被初始化到实例上，以便可以在模板和生命周期钩子中被调用。初始化过程如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;initMethods&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;vm&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;methods&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;key&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;methods&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;vm&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;methods&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;] &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;noop&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bind&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;methods&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;], &lt;span style="color:#a6e22e"&gt;vm&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这段代码遍历 &lt;code&gt;methods&lt;/code&gt; 对象中的每个属性，并将其复制到 Vue 实例（&lt;code&gt;vm&lt;/code&gt;）上。如果方法不存在（&lt;code&gt;methods[key] == null&lt;/code&gt;），则赋值为一个空函数（&lt;code&gt;noop&lt;/code&gt;），以避免对 &lt;code&gt;undefined&lt;/code&gt; 的调用。否则，使用 &lt;code&gt;bind&lt;/code&gt; 方法将每个方法的 &lt;code&gt;this&lt;/code&gt; 绑定到 Vue 实例上。&lt;/p&gt;
&lt;h2 id="methods-作用域的固定"&gt;Methods 作用域的固定&lt;/h2&gt;
&lt;p&gt;在 JavaScript 中，函数的 &lt;code&gt;this&lt;/code&gt; 值是在函数被调用时确定的，而不是在定义时。这可能导致在 Vue 实例的方法中 &lt;code&gt;this&lt;/code&gt; 并不指向实例本身，尤其是在方法被传递给其他函数或作为回调函数时。Vue 使用 &lt;code&gt;bind&lt;/code&gt; 来解决这个问题，确保 &lt;code&gt;this&lt;/code&gt; 总是指向 Vue 实例。&lt;/p&gt;
&lt;h3 id="原生和兼容性-bind-实现"&gt;原生和兼容性 bind 实现&lt;/h3&gt;
&lt;p&gt;Vue.js 提供了两种 &lt;code&gt;bind&lt;/code&gt; 的实现：原生的和兼容性的。兼容性实现是为了兼容那些不支持 &lt;code&gt;Function.prototype.bind&lt;/code&gt; 的旧浏览器。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;polyfillBind&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;fn&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;boundFn&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;l&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;arguments&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;l&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#a6e22e"&gt;l&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fn&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;apply&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;arguments&lt;/span&gt;) &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fn&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;call&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;)) &lt;span style="color:#f92672"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fn&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;call&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;boundFn&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;_length&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fn&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;boundFn&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;nativeBind&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;fn&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fn&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;bind&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bind&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Function.&lt;span style="color:#a6e22e"&gt;prototype&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;bind&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;nativeBind&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;polyfillBind&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;polyfillBind&lt;/code&gt; 函数创建了一个新的函数 &lt;code&gt;boundFn&lt;/code&gt;，它在调用时使用 &lt;code&gt;call&lt;/code&gt; 或 &lt;code&gt;apply&lt;/code&gt; 将 &lt;code&gt;fn&lt;/code&gt; 的 &lt;code&gt;this&lt;/code&gt; 绑定到 &lt;code&gt;ctx&lt;/code&gt; 上。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nativeBind&lt;/code&gt; 函数直接使用原生的 &lt;code&gt;bind&lt;/code&gt; 方法。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bind&lt;/code&gt; 变量根据浏览器是否支持原生 &lt;code&gt;bind&lt;/code&gt; 来选择使用哪种实现。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="使用-bind-的好处"&gt;使用 bind 的好处&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;bind&lt;/code&gt; 后，我们可以在组件的方法中直接使用 &lt;code&gt;this&lt;/code&gt; 来访问实例的属性和方法，而不用担心 &lt;code&gt;this&lt;/code&gt; 的指向问题。这使得代码更加简洁和安全。&lt;/p&gt;</description></item></channel></rss>