<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>一半设计一半前端</title><link>http://mrszhao.com/</link><description>鹤望岚</description><item><title>前端开发的模块化发展和ES6模块化标准</title><link>http://mrszhao.com/post/344.html</link><description>&lt;p&gt;在框架里面都讲模块化、组件化，其实发展到今天，模块化是走了很长的一条路的，现在ES6终于标准化了，不过也可以看看以前的历史。&lt;/p&gt;&lt;h2&gt;1、模块化发展历史&lt;/h2&gt;&lt;h3&gt;1.1 模块化的目的&lt;/h3&gt;&lt;p cid=&quot;n36&quot; mdtype=&quot;paragraph&quot;&gt;2009年以前，前端还属于手动操作html/css/js之间的关系，js代码还不够庞大到需要工程化的处理。&lt;/p&gt;&lt;p cid=&quot;n38&quot; mdtype=&quot;paragraph&quot;&gt;随着js的不断发展，在项目中越来越重要，承担的功能越来越多，js代码的体量和复杂度上升，就需要进行规范的管理。&lt;/p&gt;&lt;p cid=&quot;n40&quot; mdtype=&quot;paragraph&quot;&gt;因为有了运行大量 Javascript 脚本的复杂程序 ，所以&amp;nbsp;将 JavaScript 程序拆分为可按需导入的单独模块的机制就非常重要，一个js文件代码多了之后，就需要拆分成多个模块的文件，这样就形成了模块化的概念。&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;http://mrszhao.com/zb_users/upload/2023/09/202309061693972612121776.jpg&quot; alt=&quot;1.jpg&quot;/&gt;&lt;/p&gt;&lt;p cid=&quot;n44&quot; mdtype=&quot;paragraph&quot;&gt;在今天看来， 模块化应该具有以下价值：&lt;/p&gt;&lt;ul class=&quot;ul-list list-paddingleft-2&quot; cid=&quot;n46&quot; mdtype=&quot;list&quot; data-mark=&quot;-&quot; style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p cid=&quot;n48&quot; mdtype=&quot;paragraph&quot;&gt;可维护性&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p cid=&quot;n51&quot; mdtype=&quot;paragraph&quot;&gt;减少全局污染&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p cid=&quot;n54&quot; mdtype=&quot;paragraph&quot;&gt;可复用性&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p cid=&quot;n57&quot; mdtype=&quot;paragraph&quot;&gt;版本管理&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p cid=&quot;n60&quot; mdtype=&quot;paragraph&quot;&gt;方便管理依赖关系&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p cid=&quot;n63&quot; mdtype=&quot;paragraph&quot;&gt;分治思想的实践&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p cid=&quot;n65&quot; mdtype=&quot;paragraph&quot;&gt;但是，随着js的复杂攀升，ECMAScript却没有提出一套规范化的模块化语法，所以，js的模块化走了一条十来年不断演化的道路。&lt;/p&gt;&lt;h2&gt;1.2 前端模块化的雏形&lt;/h2&gt;&lt;h3&gt;1.2.1 第一阶段 文件划分&lt;/h3&gt;&lt;p cid=&quot;n69&quot; mdtype=&quot;paragraph&quot;&gt;具体做法就是将每个功能及其相关状态数据各自单独放到不同的文件中， &amp;nbsp;约定每个文件就是一个独立的模块， 使用某个模块就是将这个模块引入到页面中，然后直接调用模块中的成员（变量&amp;nbsp;/&amp;nbsp;函数）&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//module-1.js&amp;nbsp;&amp;nbsp;
var&amp;nbsp;module_name&amp;nbsp;=&amp;nbsp;&amp;#39;module1&amp;#39;;
function&amp;nbsp;fn1()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;console.log(module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn1&amp;#39;);
}
function&amp;nbsp;fn2()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;console.log(module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn2&amp;#39;);
}
$(&amp;#39;html&amp;#39;).on(&amp;#39;click&amp;#39;,&amp;nbsp;function()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;console.log(module_name+&amp;#39;被执行了&amp;#39;)
})&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//module-2.js&amp;nbsp;&amp;nbsp;
var&amp;nbsp;module_name&amp;nbsp;=&amp;nbsp;&amp;#39;module2&amp;#39;;
function&amp;nbsp;fn1()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;console.log(module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn1&amp;#39;);
}
function&amp;nbsp;fn2()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;console.log(module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn2&amp;#39;);
}&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;&amp;lt;!--index.html&amp;nbsp;--&amp;gt;
&amp;lt;script&amp;nbsp;src=&amp;quot;http://libs.baidu.com/jquery/2.0.0/jquery.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;nbsp;src=&amp;quot;js/module-1.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;nbsp;src=&amp;quot;js/module-2.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;调用函数的时候,两个模块有相同的函数名，导致后面的模块覆盖了前面的
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;命名冲突
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn1();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;模块内部的成员可以在外面被修改
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;module_name&amp;nbsp;=&amp;nbsp;&amp;#39;我的模块名&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(module_name)
&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;p cid=&quot;n74&quot; mdtype=&quot;paragraph&quot;&gt;这种缺点非常明显：&lt;/p&gt;&lt;ul class=&quot;ul-list list-paddingleft-2&quot; cid=&quot;n76&quot; mdtype=&quot;list&quot; data-mark=&quot;-&quot; style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p cid=&quot;n78&quot; mdtype=&quot;paragraph&quot;&gt;模块变量相当于在全局声明，没有私有空间，所有成员都可以在模块外部被访问或者修改&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p cid=&quot;n81&quot; mdtype=&quot;paragraph&quot;&gt;模块多了之后，会有命名冲突的问题。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p cid=&quot;n84&quot; mdtype=&quot;paragraph&quot;&gt;变量都在全局定义，导致难以调试，我们很难知道某个变量到底属于哪些模块。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p cid=&quot;n87&quot; mdtype=&quot;paragraph&quot;&gt;无法清晰地管理模块之间的依赖关系和加载顺序。假如 a.js 依赖 b.js，那么 HTML 中的 script 执行顺序需要手动调整，不然可能会产生运行时错误。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;1.2.2 第二阶段 命名空间&lt;/h3&gt;&lt;p cid=&quot;n90&quot; mdtype=&quot;paragraph&quot;&gt;在第一阶段的基础上，通过将每个模块「包裹」为一个全局对象的形式实现，有点类似于为模块内的成员添加了「命名空间」的感觉。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;module-1.js
var&amp;nbsp;module1&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;module_name:&amp;nbsp;&amp;#39;module1&amp;#39;,
&amp;nbsp;&amp;nbsp;fn1:&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn1&amp;#39;);
&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;fn2:&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn2&amp;#39;);
&amp;nbsp;&amp;nbsp;}
}

$(&amp;#39;html&amp;#39;).on(&amp;#39;click&amp;#39;,&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;console.log(module2.module_name&amp;nbsp;+&amp;nbsp;&amp;#39;被执行了&amp;#39;)
})&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;module-2.js
var&amp;nbsp;module2&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;module_name:&amp;nbsp;&amp;#39;module2&amp;#39;,
&amp;nbsp;&amp;nbsp;fn1:&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn1&amp;#39;);
&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;fn2:&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn2&amp;#39;);
&amp;nbsp;&amp;nbsp;}
}
//&amp;nbsp;无法管理模块之间的依赖关系。
module1.fn2()；&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;&amp;lt;script&amp;nbsp;src=&amp;quot;http://libs.baidu.com/jquery/2.0.0/jquery.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;nbsp;src=&amp;quot;js/module-1.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;nbsp;src=&amp;quot;js/module-2.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;通过「命名空间」减小了命名冲突的可能
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;module1.fn1();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;module2.fn1();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;但是同样没有私有空间，所有模块成员也可以在模块外部被访问或者修改，
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;module1.module_name&amp;nbsp;=&amp;nbsp;&amp;#39;改了之后的模块名&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(module1.module_name);
&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;p&gt;虽然每个变量都有自己专属的命名空间，我们可以清楚地知道某个变量到底属于哪个&lt;code&gt;模块&lt;/code&gt;，同时也避免全局变量命名的问题。 但是依然没有私有空间，外部可以修改模块内部变量，也无法管理模块之间的依赖关系。&lt;/p&gt;&lt;h3&gt;1.2.3 IIFE立即执行的函数表达式&lt;/h3&gt;&lt;p cid=&quot;n98&quot; mdtype=&quot;paragraph&quot;&gt;使用立即执行函数表达式（IIFE：Immediately-Invoked&amp;nbsp;Function&amp;nbsp;Expression）为模块提供私有空间 。&lt;/p&gt;&lt;p cid=&quot;n100&quot; mdtype=&quot;paragraph&quot;&gt;具体做法就是将每个模块成员都放在一个函数提供的私有作用域中，对于需要暴露给外部的成员，通过挂在到全局对象上的方式实现。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//module-1.js
;&amp;nbsp;(function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;var&amp;nbsp;module_name&amp;nbsp;=&amp;nbsp;&amp;#39;module1&amp;#39;;
&amp;nbsp;&amp;nbsp;function&amp;nbsp;fn1()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn1&amp;#39;);
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;function&amp;nbsp;fn2()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn2&amp;#39;);
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;不能直接访问模块内部的私有成员
&amp;nbsp;&amp;nbsp;$(&amp;#39;html&amp;#39;).on(&amp;#39;click&amp;#39;,&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(module1.module_name&amp;nbsp;+&amp;nbsp;&amp;#39;被执行了&amp;#39;)
&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;window.module1&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn1:&amp;nbsp;fn1,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn2:&amp;nbsp;fn2
&amp;nbsp;&amp;nbsp;}
})();&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//module-2.js
;&amp;nbsp;(function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;var&amp;nbsp;module_name&amp;nbsp;=&amp;nbsp;&amp;#39;module2&amp;#39;;
&amp;nbsp;&amp;nbsp;function&amp;nbsp;fn1()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn1&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;module1.fn1();
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;function&amp;nbsp;fn2()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn2&amp;#39;);
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;window.module2&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn1:&amp;nbsp;fn1,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn2:&amp;nbsp;fn2
&amp;nbsp;&amp;nbsp;}
})();&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;&amp;lt;script&amp;nbsp;src=&amp;quot;http://libs.baidu.com/jquery/2.0.0/jquery.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;nbsp;src=&amp;quot;js/module-1.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;nbsp;src=&amp;quot;js/module-2.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;module1.fn1();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;module2.fn1();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;外部不能直接访问模块内部的私有成员
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(module1.module_name);&amp;nbsp;//&amp;nbsp;undefined
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;为模块添加了一个新的属性，虽然名字和模块内部的变量名同名，但是它们在不同的作用域，互相不受影响。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;module1.module_name&amp;nbsp;=&amp;nbsp;&amp;#39;改了模块名字&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(module1.module_name);&amp;nbsp;//改了模块名字
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;module1.fn1();&amp;nbsp;//&amp;nbsp;module1fn1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(module1);//{module_name:&amp;nbsp;&amp;#39;改了模块名字&amp;#39;,&amp;nbsp;fn1:&amp;nbsp;ƒ,&amp;nbsp;fn2:&amp;nbsp;ƒ}

&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;p cid=&quot;n105&quot; mdtype=&quot;paragraph&quot;&gt;每个&lt;code&gt;IIFE&lt;/code&gt;即&lt;code&gt;立即执行函数&lt;/code&gt;都会创建一个私有的作用域，在私有作用域中的变量外界是无法访问的，只有模块内部的方法才能访问。相比于命名空间的模块化手段，&lt;code&gt;IIFE&lt;/code&gt;实现的模块化安全性要更高，对于模块作用域的区分更加彻底。&lt;/p&gt;&lt;p cid=&quot;n107&quot; mdtype=&quot;paragraph&quot;&gt;对于模块内部的module_name变量，我们只能在模块内部的fn函数中通过闭包访问，而在其它模块中无法直接访问。这就是模块私有化功能，避免模块私有成员被其他模块非法篡改，相比于命名空间的实现方式更加安全。&lt;/p&gt;&lt;h3&gt;1.2.4 利用传参解决依赖问题&lt;/h3&gt;&lt;p cid=&quot;n110&quot; mdtype=&quot;paragraph&quot;&gt;只用IIFE虽然解决了私有化的问题，但是没有解决模块之间的依赖关系。&lt;/p&gt;&lt;p cid=&quot;n112&quot; mdtype=&quot;paragraph&quot;&gt;后来通过利用立即执行函数的参数传递模块依赖项。 这使得每一个模块之间的关系变得更加明显。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//module-1.js
;&amp;nbsp;(function&amp;nbsp;($)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;var&amp;nbsp;module_name&amp;nbsp;=&amp;nbsp;&amp;#39;module1&amp;#39;;
&amp;nbsp;&amp;nbsp;function&amp;nbsp;fn1()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn1&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;body&amp;#39;).css(&amp;#39;backgroundColor&amp;#39;,&amp;nbsp;&amp;#39;#ddd&amp;#39;);
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;function&amp;nbsp;fn2()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn2&amp;#39;);
&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;window.module1&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn1:&amp;nbsp;fn1,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn2:&amp;nbsp;fn2
&amp;nbsp;&amp;nbsp;}
})(jQuery);&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//module-2.js
;&amp;nbsp;(function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;var&amp;nbsp;module_name&amp;nbsp;=&amp;nbsp;&amp;#39;module2&amp;#39;;
&amp;nbsp;&amp;nbsp;function&amp;nbsp;fn1()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn1&amp;#39;);
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;function&amp;nbsp;fn2()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(module_name&amp;nbsp;+&amp;nbsp;&amp;#39;fn2&amp;#39;);

&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;module1.fn2();
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;window.module2&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn1:&amp;nbsp;fn1,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn2:&amp;nbsp;fn2
&amp;nbsp;&amp;nbsp;}
})();&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;&amp;lt;script&amp;nbsp;src=&amp;quot;http://unpkg.com/jquery&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;nbsp;src=&amp;quot;js/module-1.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;nbsp;src=&amp;quot;js/module-2.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;module1.fn1();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;module2.fn1();
&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;h2&gt;2、模块化的规范&lt;/h2&gt;&lt;p cid=&quot;n120&quot; mdtype=&quot;paragraph&quot;&gt;十年之前，模块化还主要使用闭包简单的实现一个命名空间。使用这种解决方式可以简单粗暴的处理全局变量和依赖关系等问题。&lt;/p&gt;&lt;p cid=&quot;n122&quot; mdtype=&quot;paragraph&quot;&gt;转眼间模块化已经发展了有十余年了，不同的工具和轮子层出不穷，下面是最各大工具或框架的诞生时间：&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr class=&quot;firstRow&quot;&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;生态&lt;/td&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;诞生时间&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;&lt;strong&gt;CommonJS&lt;/strong&gt;&lt;/td&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;2009年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;Node.js&lt;/td&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;2009年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;&lt;strong&gt;NPM&lt;/strong&gt;&lt;/td&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;2010年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;requireJS(AMD)&lt;/td&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;2010年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;seaJS(CMD)&lt;/td&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;2011年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;broswerify&lt;/td&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;2011年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;&lt;strong&gt;webpack&lt;/strong&gt;&lt;/td&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;2012年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;grunt &amp;nbsp;&lt;/td&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;2012年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;&lt;strong&gt;gulp&lt;/strong&gt;&lt;/td&gt;&lt;td width=&quot;698&quot; valign=&quot;top&quot; style=&quot;word-break: break-all;&quot;&gt;2013年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; style=&quot;word-break: break-all;&quot;&gt;react&lt;/td&gt;&lt;td valign=&quot;top&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; style=&quot;word-break: break-all;&quot;&gt;2013年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; style=&quot;word-break: break-all;&quot;&gt;&lt;strong&gt;vue&lt;/strong&gt;&lt;/td&gt;&lt;td valign=&quot;top&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; style=&quot;word-break: break-all;&quot;&gt;2014年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; style=&quot;word-break: break-all;&quot;&gt;&lt;strong&gt;ES6(Module)&lt;/strong&gt;&lt;/td&gt;&lt;td valign=&quot;top&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; style=&quot;word-break: break-all;&quot;&gt;2015年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; style=&quot;word-break: break-all;&quot;&gt;angular&lt;/td&gt;&lt;td valign=&quot;top&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; style=&quot;word-break: break-all;&quot;&gt;2016年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; style=&quot;word-break: break-all;&quot;&gt;redux&lt;/td&gt;&lt;td valign=&quot;top&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; style=&quot;word-break: break-all;&quot;&gt;2015年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; style=&quot;word-break: break-all;&quot;&gt;&lt;strong&gt;vite&lt;/strong&gt;&lt;/td&gt;&lt;td valign=&quot;top&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; style=&quot;word-break: break-all;&quot;&gt;2020年&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; style=&quot;word-break: break-all;&quot;&gt;snowpack&lt;/td&gt;&lt;td valign=&quot;top&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; style=&quot;word-break: break-all;&quot;&gt;2020年&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p cid=&quot;n142&quot; mdtype=&quot;paragraph&quot;&gt;随着前端工程的日益庞大，前端的模块化规范统一也经历了漫长的发展阶段，现在业界主流的三大模块规范是：&lt;code&gt;CommonJS&lt;/code&gt;、&lt;code&gt;AMD&lt;/code&gt;和&lt;code&gt;ES Modules&lt;/code&gt;。对于模块规范而言，一般会包含两方面内容：&lt;/p&gt;&lt;ul class=&quot;ul-list list-paddingleft-2&quot; cid=&quot;n144&quot; mdtype=&quot;list&quot; data-mark=&quot;-&quot; style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p cid=&quot;n146&quot; mdtype=&quot;paragraph&quot;&gt;统一的模块化代码规范&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p cid=&quot;n149&quot; mdtype=&quot;paragraph&quot;&gt;实现自动加载模块的加载器(也称&lt;code&gt;loader&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;2.1 CommonJS规范&lt;/h3&gt;&lt;p cid=&quot;n152&quot; mdtype=&quot;paragraph&quot;&gt;CommonJS 是业界最早正式提出的 JavaScript 模块规范，主要用于服务端 Node.js 。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//module-a.js
var&amp;nbsp;data&amp;nbsp;=&amp;nbsp;&amp;quot;hello&amp;nbsp;world&amp;quot;;
function&amp;nbsp;getData()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;return&amp;nbsp;data;
}
module.exports&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;getData,
};&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//index.js
const&amp;nbsp;{&amp;nbsp;getData&amp;nbsp;}&amp;nbsp;=&amp;nbsp;require(&amp;quot;./module-a.js&amp;quot;);
console.log(getData());&lt;/pre&gt;&lt;p cid=&quot;n156&quot; mdtype=&quot;paragraph&quot;&gt;CommonJS 中使用&lt;code&gt;require&lt;/code&gt;来导入一个模块，用&lt;code&gt;module.exports&lt;/code&gt;来导出一个模块。CommonJS 定义了一套完整的模块化代码规范，不过仍然存在一些问题：&lt;/p&gt;&lt;ul class=&quot;ul-list list-paddingleft-2&quot; cid=&quot;n158&quot; mdtype=&quot;list&quot; data-mark=&quot;-&quot; style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p cid=&quot;n160&quot; mdtype=&quot;paragraph&quot;&gt;它的模块加载器由 Node.js 提供，依赖了 Node.js 本身的功能实现。如果 CommonJS 模块直接放到浏览器中无法执行。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p cid=&quot;n163&quot; mdtype=&quot;paragraph&quot;&gt;CommonJS 约定以同步的方式进行模块加载，这种加载机制放到浏览器端，会带来明显的性能问题。它会产生大量同步的模块请求，浏览器要等待响应返回后才能继续解析模块。即，模块请求会造成浏览器 JS 解析过程的阻塞，导致页面加载速度缓慢。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p cid=&quot;n165&quot; mdtype=&quot;paragraph&quot;&gt;CommonJS 的这种加载机制放在服务端是没问题的，一来模块都在本地，不需要进行网络 IO，二来只有服务启动时才会加载模块，而服务通常启动后会一直运行，所以对服务的性能并没有太大的影响。&lt;/p&gt;&lt;p cid=&quot;n167&quot; mdtype=&quot;paragraph&quot;&gt;但是在浏览器端却会造成阻塞，白屏时间过长，用户体验不够友好。&lt;/p&gt;&lt;p cid=&quot;n169&quot; mdtype=&quot;paragraph&quot;&gt;总之，CommonJS 是一个不太适合在浏览器中运行的模块规范。因此，业界也设计出了全新的规范来作为浏览器端的模块标准，最知名的要数&lt;code&gt;AMD&lt;/code&gt;和&lt;code&gt;CMD&lt;/code&gt;了。&lt;/p&gt;&lt;h3&gt;2.2 AMD规范和CMD规范&lt;/h3&gt;&lt;h4&gt;2.2.1 RequireJS和SeaJS&lt;/h4&gt;&lt;p cid=&quot;n173&quot; mdtype=&quot;paragraph&quot;&gt;&lt;code&gt;AMD&lt;/code&gt;全称为&lt;code&gt;Asynchronous Module Definition&lt;/code&gt;，即异步模块定义规范。模块根据这个规范，在浏览器环境中会被异步加载，而不会像 CommonJS 规范进行同步加载，也就不会产生同步请求导致的浏览器解析过程阻塞的问题了。&lt;/p&gt;&lt;p cid=&quot;n175&quot; mdtype=&quot;paragraph&quot;&gt;RequireJS 遵循的是 AMD（异步模块定义）规范。&lt;/p&gt;&lt;p cid=&quot;n177&quot; mdtype=&quot;paragraph&quot;&gt;SeaJS 遵循的是 CMD （通用模块定义）规范（阿里的玉伯主导的）&lt;/p&gt;&lt;p cid=&quot;n179&quot; mdtype=&quot;paragraph&quot;&gt;随着 2015 年 6 月，ECMAScript 对 ES6 Modules 的正式发布，浏览器厂商和 Node.js 随之纷纷跟进实现，市面上的模块化加载库随之暗淡失色，间接给 CommonJS 社区判了死刑。在浏览器端取而代之流行的做法的是大家都使用 ES6 Modules 写法，然后使用 Babel 等的 transpiler 来应对不同浏览器版本的支持程度和在浏览器端异步特性产生的一些待解决的问题。Node.js 的模块还是大量的采用 CommonJS 模式，随着对 ES6 Modules 的支持力度的提高和可以兼容之前 CommonJS 模块，CommonJS 写法过渡到 ES6 Modules 只是时间的问题。&lt;/p&gt;&lt;h3&gt;3、 ES6 Module&lt;/h3&gt;&lt;p cid=&quot;n182&quot; mdtype=&quot;paragraph&quot;&gt;&lt;code&gt;ES Module&lt;/code&gt;(或&lt;code&gt;ESM&lt;/code&gt;)， 是由 ECMAScript 官方提出的模块化规范，它已经得到了现代浏览器的内置支持。&lt;/p&gt;&lt;p cid=&quot;n184&quot; mdtype=&quot;paragraph&quot;&gt;不仅在浏览器端，一直以 CommonJS 作为模块标准的 Node.js 也从&lt;code&gt;12.20&lt;/code&gt;版本开始正式支持原生 ES Module。&lt;/p&gt;&lt;h3&gt;3.1 ESM特性&lt;/h3&gt;&lt;h4&gt;3.1.1 在HTML中声明脚本模块&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;&amp;lt;!--&amp;nbsp;引入外部模块&amp;nbsp;--&amp;gt;
&amp;lt;script&amp;nbsp;type=&amp;quot;module&amp;quot;&amp;nbsp;src=&amp;quot;main.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;

&amp;lt;!--&amp;nbsp;把模块导入内部脚本--&amp;gt;
&amp;lt;script&amp;nbsp;type=&amp;quot;module&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;this&amp;nbsp;is&amp;nbsp;es&amp;nbsp;module&amp;#39;);
&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;h4&gt;3.1.2 默认是严格模式&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;&amp;lt;!--&amp;nbsp;ESM&amp;nbsp;默认采用严格模式&amp;nbsp;use&amp;nbsp;strict&amp;nbsp;--&amp;gt;
&amp;lt;script&amp;nbsp;type=&amp;quot;module&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this);&amp;nbsp;//undefined
&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;h4&gt;3.1.3 每个模块都是运行在单独的私有作用域中&lt;/h4&gt;&lt;h4&gt;3.1.4 通过CORS访问外部资源&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;&amp;lt;!--&amp;nbsp;通过CORS&amp;nbsp;跨域资源共享方式访问外部的模块，&amp;nbsp;有的外部地址不支持CORS，会报错&amp;nbsp;--&amp;gt;
&amp;lt;script&amp;nbsp;type=&amp;quot;module&amp;quot;&amp;nbsp;src=&amp;quot;http://libs.baidu.com/jquery/2.0.0/jquery.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;!--&amp;nbsp;支持CORS跨域访问资源&amp;nbsp;--&amp;gt;
&amp;lt;script&amp;nbsp;type=&amp;quot;module&amp;quot;&amp;nbsp;src=&amp;quot;unpkg.com/jquery&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;blockquote&gt;&lt;p&gt;CORS 全称为 Cross-Origin Resource Sharing，被译为跨域资源共享，简称跨域访问，是 W3C 制定的标准协议。它由一系列传输的 HTTP 标头（首部字段）组成，浏览器会根据这些 HTTP 标头决定着是否阻止前端 JS 代码获取跨域请求的资源。CORS 主要作用是消除各种 API 的同源限制，以便在不同源（服务器）之间共享资源，且确保跨域数据传输的安全性。&lt;/p&gt;&lt;/blockquote&gt;&lt;h4&gt;3.1.5 模块会自动延迟加载&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;&amp;lt;!--&amp;nbsp;ESM&amp;nbsp;的script标签会延迟执行脚本,不影响页面的渲染&amp;nbsp;--&amp;gt;
&amp;lt;script&amp;nbsp;type=&amp;quot;module&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert(&amp;#39;Hello&amp;#39;);
&amp;lt;/script&amp;gt;
&amp;lt;p&amp;gt;页面内容&amp;lt;/p&amp;gt;&lt;/pre&gt;&lt;h3&gt;3.2 导入和导出&lt;/h3&gt;&lt;p cid=&quot;n201&quot; mdtype=&quot;paragraph&quot;&gt;模块都在单独的私有作用域中，所以外部不能直接访问，必须通过导出到外部才能访问。&lt;/p&gt;&lt;p cid=&quot;n203&quot; mdtype=&quot;paragraph&quot;&gt;为了获得模块的功能要做的第一件事是把它们导出来。使用&amp;nbsp;&lt;code&gt;export&lt;/code&gt;&amp;nbsp;语句来完成。&lt;/p&gt;&lt;p cid=&quot;n205&quot; mdtype=&quot;paragraph&quot;&gt;导出有三种方式。&lt;/p&gt;&lt;h4&gt;3.2.1 变量函数声明导出&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//module.js

//&amp;nbsp;导出变量username
export&amp;nbsp;var&amp;nbsp;username&amp;nbsp;=&amp;nbsp;&amp;#39;诸葛&amp;#39;
//&amp;nbsp;导出函数sayName
export&amp;nbsp;function&amp;nbsp;sayName()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;console.log(username);
}
//&amp;nbsp;导出类Person
export&amp;nbsp;class&amp;nbsp;Person&amp;nbsp;{
&amp;nbsp;&amp;nbsp;constructor(username)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.username&amp;nbsp;=&amp;nbsp;username;
&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//app.js

//导入，这里的.js不能省略。import&amp;nbsp;{}&amp;nbsp;是一种语法，不是解构赋值
import&amp;nbsp;{&amp;nbsp;username,&amp;nbsp;sayName,&amp;nbsp;Person&amp;nbsp;}&amp;nbsp;from&amp;nbsp;&amp;quot;../modules/module.js&amp;quot;;
console.log(username);
sayName()
console.log(new&amp;nbsp;Person(&amp;#39;孔明&amp;#39;))&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;&amp;lt;!--index.html--&amp;gt;

&amp;lt;script&amp;nbsp;type=&amp;quot;module&amp;quot;&amp;nbsp;src=&amp;quot;js/app.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;h4&gt;3.2.2 命名导出&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//module.js

//&amp;nbsp;命名导出方式

var&amp;nbsp;username&amp;nbsp;=&amp;nbsp;&amp;#39;诸葛&amp;#39;;

function&amp;nbsp;sayName()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;console.log(username);
}

class&amp;nbsp;Person&amp;nbsp;{
&amp;nbsp;&amp;nbsp;constructor(username)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.username&amp;nbsp;=&amp;nbsp;username;
&amp;nbsp;&amp;nbsp;}
}

//&amp;nbsp;集中命名导出
export&amp;nbsp;{username,&amp;nbsp;sayName,&amp;nbsp;Person};
//&amp;nbsp;通过as重命名，导入的时候，用重命名的名字导入
export&amp;nbsp;{username,&amp;nbsp;sayName&amp;nbsp;as&amp;nbsp;sayUserName,&amp;nbsp;Person};&lt;/pre&gt;&lt;h4&gt;3.2.3 默认导出&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//module.js
//默认导出&amp;nbsp;export&amp;nbsp;default&amp;nbsp;，后面没有{}大括号
export&amp;nbsp;default&amp;nbsp;sayName;
//&amp;nbsp;或者默认导出一个匿名函数
export&amp;nbsp;default&amp;nbsp;function(){
&amp;nbsp;&amp;nbsp;console.log(username);
}&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//app.js
//导入默认的导出时，直接写上导出的名字，不需要大括号。因为每个模块只允许有一个默认导出
import&amp;nbsp;sayName&amp;nbsp;from&amp;nbsp;&amp;quot;../modules/module.js&amp;quot;;
//是这种的缩写形式
//import&amp;nbsp;{default&amp;nbsp;as&amp;nbsp;sayName}&amp;nbsp;from&amp;nbsp;&amp;#39;../modules/module.js&amp;#39;&lt;/pre&gt;&lt;p&gt;导入有四种方式。&lt;/p&gt;&lt;h4&gt;3.2.4 按需导入&lt;/h4&gt;&lt;p cid=&quot;n219&quot; mdtype=&quot;paragraph&quot;&gt;导入的变量名字必须和导出的变量名一致。后面的路径是相对根目录的相对路径，必须以 . 或者 / 或者http路径开头，不能直接用字母开头。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;import&amp;nbsp;{&amp;nbsp;sayName&amp;nbsp;}&amp;nbsp;from&amp;nbsp;&amp;quot;../modules/module.js&amp;quot;;&lt;/pre&gt;&lt;h4&gt;3.2.5 命名空间导入&lt;/h4&gt;&lt;p&gt;如果需要导入的模块很多，有可能需要重命名导出的变量， 导致有点冗余。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;import&amp;nbsp;{&amp;nbsp;sayName&amp;nbsp;as&amp;nbsp;sayName1&amp;nbsp;}&amp;nbsp;from&amp;nbsp;&amp;quot;../modules/module.js&amp;quot;;
import&amp;nbsp;{&amp;nbsp;sayName&amp;nbsp;as&amp;nbsp;sayName2}&amp;nbsp;from&amp;nbsp;&amp;quot;../modules/module1.js&amp;quot;;&lt;/pre&gt;&lt;p&gt;一个更好的解决方是，导入每一个模块功能到一个模块功能对象上。可以使用以下语法形式：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;import&amp;nbsp;*&amp;nbsp;as&amp;nbsp;Module&amp;nbsp;from&amp;nbsp;&amp;#39;/modules/module.js&amp;#39;;&lt;/pre&gt;&lt;p&gt;这将获取&amp;nbsp;&lt;code&gt;module.js&lt;/code&gt;&amp;nbsp;中所有可用的导出，并使它们可以作为对象模块的成员使用，从而有效地为其提供自己的命名空间。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;import&amp;nbsp;*&amp;nbsp;as&amp;nbsp;Module1&amp;nbsp;from&amp;nbsp;&amp;#39;../modules/module.js&amp;#39;;
import&amp;nbsp;*&amp;nbsp;as&amp;nbsp;Module2&amp;nbsp;from&amp;nbsp;&amp;#39;../modules/module1.js&amp;#39;;
console.log(Module1.username);
Module1.sayName();
console.log(new&amp;nbsp;Module1.Person(&amp;#39;孔明&amp;#39;))

console.log(Module2.username)
Module2.sayName();&lt;/pre&gt;&lt;h4&gt;3.2.6 默认导入&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;import&amp;nbsp;_&amp;nbsp;from&amp;nbsp;&amp;#39;module.js&amp;#39;&lt;/pre&gt;&lt;p&gt;导入export default后面的值，可以取任意名字，因为一个模块只有一个export default，可以省略大括号。&lt;/p&gt;&lt;h4&gt;3.2.7 默认和按需同时导入&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//module.js
export&amp;nbsp;{&amp;nbsp;username,&amp;nbsp;count&amp;nbsp;}

export&amp;nbsp;default&amp;nbsp;sayName&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//app.js
//两种方式导入
//&amp;nbsp;import&amp;nbsp;{username,&amp;nbsp;count,&amp;nbsp;default&amp;nbsp;as&amp;nbsp;sayName}&amp;nbsp;from&amp;nbsp;&amp;#39;../module/module.js&amp;#39;
import&amp;nbsp;sayName,&amp;nbsp;{username,&amp;nbsp;count}&amp;nbsp;from&amp;nbsp;&amp;#39;../module/module.js&amp;#39;&lt;/pre&gt;&lt;h4&gt;3.2.8 只运行不导入&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;import&amp;nbsp;&amp;#39;module.js&amp;#39;&lt;/pre&gt;&lt;p&gt;只运行模块而不引入模块中的任何方法或变量。&lt;/p&gt;&lt;h4&gt;3.2.9 动态导入&lt;/h4&gt;&lt;p cid=&quot;n244&quot; mdtype=&quot;paragraph&quot;&gt;import &amp;nbsp;只能放在最外层作用域中，不能嵌套在if这种块作用域中。&lt;/p&gt;&lt;p cid=&quot;n246&quot; mdtype=&quot;paragraph&quot;&gt;from 后面的路径也不能是变量。&lt;/p&gt;&lt;p cid=&quot;n248&quot; mdtype=&quot;paragraph&quot;&gt;所以，当不知道模块加载的路径，或者在刚开始还不需要加载模块的时候，可以使用动态加载。&lt;/p&gt;&lt;p cid=&quot;n250&quot; mdtype=&quot;paragraph&quot;&gt;这时用import()函数来实现动态加载。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;import(&amp;#39;../module/module.js&amp;#39;).then(function(module)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;console.log(module)
})&lt;/pre&gt;&lt;p&gt;这是异步加载，当加载完模块后，才执行后面的回调函数，module形参获得模块返回的导出对象。&lt;/p&gt;&lt;h4&gt;3.2.10 注意事项&lt;/h4&gt;&lt;p cid=&quot;n256&quot; mdtype=&quot;paragraph&quot;&gt;export {} 和 import {}都是一种语法，不是对象字面量，也不是解构赋值&lt;/p&gt;&lt;p cid=&quot;n258&quot; mdtype=&quot;paragraph&quot;&gt;只有export default 后面可以跟一个值，可以是变量，函数，对象，字符串等值。export default {}这才是默认导出一个对象。&lt;/p&gt;&lt;p cid=&quot;n260&quot; mdtype=&quot;paragraph&quot;&gt;导入和导出之间的成员的值是一种引用关系，不是赋值关系。导出的成员是只读的。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//module.js
var&amp;nbsp;count&amp;nbsp;=&amp;nbsp;0;
var&amp;nbsp;username&amp;nbsp;=&amp;nbsp;&amp;#39;Tom&amp;#39;;

setTimeout(function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;username&amp;nbsp;=&amp;nbsp;&amp;#39;Jenn&amp;#39;;
},&amp;nbsp;1000)

setInterval(function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;count++;
},&amp;nbsp;1000)

export&amp;nbsp;{&amp;nbsp;username,&amp;nbsp;count&amp;nbsp;}&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//app.js
import&amp;nbsp;{username,&amp;nbsp;count}&amp;nbsp;from&amp;nbsp;&amp;#39;../module/module.js&amp;#39;
console.log(count,&amp;nbsp;username);
setInterval(function()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;console.log(count,&amp;nbsp;username);
},&amp;nbsp;1500)&lt;/pre&gt;&lt;p&gt;关于原生js的教案差不多就整理完了，算是一个总结吧，自动化构建和框架的教案就不放出来了。如果我以后转行不干了，再说！&lt;br/&gt;&lt;/p&gt;&lt;p&gt; © Copyright Birdol.Com 2006-2014.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/344.html&quot; target=&quot;_blank&quot;&gt;继续阅读《前端开发的模块化发展和ES6模块化标准》的全文内容...&lt;/a&gt;&lt;/p&gt;&lt;p&gt;分类: JavaScript教程 | Tags: &lt;a href=&quot;http://mrszhao.com/tags-327.html&quot;&gt;ES6 Module&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-328.html&quot;&gt;模块化&lt;/a&gt;， | &lt;a href=&quot;http://mrszhao.com/post/344.html#comment&quot; target=&quot;_blank&quot;&gt;添加评论&lt;/a&gt;(2)&lt;/p&gt;&lt;hr /&gt; &lt;h3&gt;最新评论:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/344.html#comment-235&quot;&gt;2023-09-07 21:44:52 PM&lt;/a&gt;，赵老师 ： 把以前的畅言留言系统关闭了，免得有广告，看看这个留言能用吗？&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/344.html#comment-236&quot;&gt;2023-09-07 21:51:31 PM&lt;/a&gt;，赵老师 ： 可以留言了，罢工了很久的留言系统还是启动起来吧。&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;相关文章:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/231.html&quot;&gt;JavaScript基础3:运算符和表达式&lt;/a&gt; (2019-07-08)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/311.html&quot;&gt;HTML5新增的拖拽上传API&lt;/a&gt; (2023-07-08)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/258.html&quot;&gt;DOM基础5：Event事件对象&lt;/a&gt; (2019-08-23)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/238.html&quot;&gt;JavaScript基础7:数组Arrays常用的迭代方法&lt;/a&gt; (2019-07-25)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/257.html&quot;&gt;DOM基础4：对CSS样式的操作&lt;/a&gt; (2019-08-21)  &lt;/li&gt;&lt;/ul&gt;&lt;a target=&quot;_blank&quot; title=&quot;阿里云优惠&quot; href=&quot;http://www.birdol.com/redirect/?s=6&quot;&gt;&lt;img alt=&quot;Z-Blog&quot; src=&quot;http://www.birdol.com/aliyun/qingdao950x90.jpg&quot;&gt;&lt;/a&gt;</description><pubDate>Sun, 30 Jul 2023 11:47:57 +0800</pubDate></item><item><title>Vue版本的todos本地任务清单！</title><link>http://mrszhao.com/post/345.html</link><description>&lt;p&gt;前面用ES6写了一个 todos，这里放一个Vue版本写的，可以通过代码对比，看看Vue和原生js的区别。&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/343.html&quot; target=&quot;_blank&quot; title=&quot;ES6版本的todos本地任务清单！&quot;&gt;用ES6写了一个todos，本地任务清单！&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/zb_users/upload/2023/07/todosVue/index.html&quot; target=&quot;_blank&quot; title=&quot;Vue版本的todos&quot;&gt;&lt;img src=&quot;http://mrszhao.com/zb_users/upload/2023/09/202309061693975768504890.jpg&quot; title=&quot;5.jpg&quot; alt=&quot;5.jpg&quot;/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;点击图片看效果。&lt;/p&gt;&lt;p&gt;核心代码：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;filters&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;all(todos)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;todos;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;active(todos)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;todos.filter(item&amp;nbsp;=&amp;gt;&amp;nbsp;!item.completed);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;completed(todos)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;todos.filter(item&amp;nbsp;=&amp;gt;&amp;nbsp;item.completed);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;const&amp;nbsp;TODO_KEY&amp;nbsp;=&amp;nbsp;&amp;#39;todo-keys&amp;#39;
&amp;nbsp;&amp;nbsp;const&amp;nbsp;storage&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;JSON.parse(localStorage.getItem(TODO_KEY))&amp;nbsp;||&amp;nbsp;[];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set(todos)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;localStorage.setItem(TODO_KEY,&amp;nbsp;JSON.stringify(todos));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;const&amp;nbsp;vm&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Vue({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;el:&amp;nbsp;&amp;#39;#app&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;todos:[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;nbsp;{id:1,&amp;nbsp;title:&amp;nbsp;&amp;#39;上课&amp;#39;,&amp;nbsp;completed:&amp;nbsp;true},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;nbsp;{id:2,&amp;nbsp;title:&amp;nbsp;&amp;#39;吃饭&amp;#39;,&amp;nbsp;completed:&amp;nbsp;false},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;nbsp;{id:3,&amp;nbsp;title:&amp;nbsp;&amp;#39;睡觉&amp;#39;,&amp;nbsp;completed:&amp;nbsp;false},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;nbsp;{id:4,&amp;nbsp;title:&amp;nbsp;&amp;#39;梦游&amp;#39;,&amp;nbsp;completed:&amp;nbsp;false},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todos:&amp;nbsp;storage.get(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newTodo:&amp;nbsp;&amp;#39;&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;editingTodo:&amp;nbsp;null,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todoBeforeTitle:&amp;nbsp;&amp;#39;&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todoType:&amp;nbsp;&amp;#39;all&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;methods:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pluralize(unit)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;unit&amp;nbsp;+&amp;nbsp;(this.remaining&amp;nbsp;===&amp;nbsp;1&amp;nbsp;?&amp;nbsp;&amp;#39;&amp;#39;&amp;nbsp;:&amp;nbsp;&amp;#39;s&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;addTodo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;val&amp;nbsp;=&amp;nbsp;this.newTodo.trim();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(!val)&amp;nbsp;return;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;this.todos.push({id:this.todos.length&amp;nbsp;&amp;gt;&amp;nbsp;0&amp;nbsp;?&amp;nbsp;this.todos[this.todos.length&amp;nbsp;-1].id&amp;nbsp;+&amp;nbsp;1&amp;nbsp;:&amp;nbsp;0&amp;nbsp;,&amp;nbsp;title:&amp;nbsp;val,&amp;nbsp;completed:&amp;nbsp;false});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.todos.push({id:&amp;nbsp;Date.now(),&amp;nbsp;title:&amp;nbsp;val,&amp;nbsp;completed:&amp;nbsp;false});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.newTodo&amp;nbsp;=&amp;nbsp;&amp;#39;&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;removeTodo(todo)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;index&amp;nbsp;=&amp;nbsp;this.todos.indexOf(todo);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.todos.splice(index,1);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;editTodo(todo)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.editingTodo&amp;nbsp;=&amp;nbsp;todo;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.todoBeforeTitle&amp;nbsp;=&amp;nbsp;todo.title;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;editDone(todo)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(todo&amp;nbsp;!==&amp;nbsp;this.editingTodo)&amp;nbsp;return;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;val&amp;nbsp;=&amp;nbsp;todo.title.trim();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(!val)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.removeTodo(todo);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}else{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todo.title&amp;nbsp;=&amp;nbsp;val;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.editingTodo&amp;nbsp;=&amp;nbsp;null;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.todoBeforeTitle&amp;nbsp;=&amp;nbsp;&amp;#39;&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cancelEdit(todo)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todo.title&amp;nbsp;=&amp;nbsp;this.todoBeforeTitle;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.editingTodo&amp;nbsp;=&amp;nbsp;null;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.todoBeforeTitle&amp;nbsp;=&amp;nbsp;&amp;#39;&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;removeAllCompleted()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;this.todos&amp;nbsp;=&amp;nbsp;this.todos.filter(item&amp;nbsp;=&amp;gt;&amp;nbsp;!item.completed)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.todos&amp;nbsp;=&amp;nbsp;filters.active(this.todos);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;computed:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;remaining()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;return&amp;nbsp;this.todos.filter(item&amp;nbsp;=&amp;gt;&amp;nbsp;!item.completed).length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;filters.active(this.todos).length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;allDone:{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this.remaining&amp;nbsp;===&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set(value)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.todos.forEach(item&amp;nbsp;=&amp;gt;&amp;nbsp;item.completed&amp;nbsp;=&amp;nbsp;value);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;filtersTodo()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;filters[this.todoType](this.todos);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;directives:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;todo-focus&amp;#39;(el)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;el.focus();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;watch:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todos:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;deep:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;handler:&amp;nbsp;storage.set
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;})&lt;/pre&gt;&lt;p&gt;差不多了，原生js的案例也整理完了，框架的案例就不上了，如果有一天我转行了，可以把所有完整的项目都分享出来，再给自己三个月的时间吧。&lt;br/&gt;&lt;/p&gt;&lt;p&gt; © Copyright Birdol.Com 2006-2014.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/345.html&quot; target=&quot;_blank&quot;&gt;继续阅读《Vue版本的todos本地任务清单！》的全文内容...&lt;/a&gt;&lt;/p&gt;&lt;p&gt;分类: JavaScript案例集 | Tags: &lt;a href=&quot;http://mrszhao.com/tags-329.html&quot;&gt;Vue&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-325.html&quot;&gt;todos&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-326.html&quot;&gt;本地任务清单&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-256.html&quot;&gt;js案例&lt;/a&gt;， | &lt;a href=&quot;http://mrszhao.com/post/345.html#comment&quot; target=&quot;_blank&quot;&gt;添加评论&lt;/a&gt;(0)&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/345.html#comment&quot; target=&quot;_blank&quot;&gt;还没有评论，您来说两句？&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;相关文章:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/209.html&quot;&gt;JavaScript案例10：仿百度风云排行榜&lt;/a&gt; (2019-08-15)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/333.html&quot;&gt;利用ajax+mock.js+echarts.js模拟汽车销量饼状图&lt;/a&gt; (2021-12-20)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/316.html&quot;&gt;商城购物车ES6原生js实现零漏洞&lt;/a&gt; (2023-07-02)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/182.html&quot;&gt;利用transform打造走动的2D时钟&lt;/a&gt; (2018-05-15)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/207.html&quot;&gt;JavaScript案例8：两组幻灯分别切换和统一切换&lt;/a&gt; (2018-09-14)  &lt;/li&gt;&lt;/ul&gt;&lt;a target=&quot;_blank&quot; title=&quot;阿里云优惠&quot; href=&quot;http://www.birdol.com/redirect/?s=6&quot;&gt;&lt;img alt=&quot;Z-Blog&quot; src=&quot;http://www.birdol.com/aliyun/qingdao950x90.jpg&quot;&gt;&lt;/a&gt;</description><pubDate>Fri, 28 Jul 2023 12:43:59 +0800</pubDate></item><item><title>用ES6写了一个todos，本地任务清单！</title><link>http://mrszhao.com/post/343.html</link><description>&lt;p&gt;学完了ES6，就可以拿一个小项目练练手，todoMVC是一个比较出名的用来练习各种编程语言的项目，可以直接去它官网看。&lt;/p&gt;&lt;p&gt;这里写一个ES6版本的。&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/zb_users/upload/2023/07/todosES6/index.html&quot; target=&quot;_blank&quot; title=&quot;todosES6版本&quot;&gt;&lt;img src=&quot;http://mrszhao.com/zb_users/upload/2023/09/202309061693971516756203.jpg&quot; title=&quot;4.jpg&quot; alt=&quot;4.jpg&quot;/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;点击图片看效果，如果想看Vue2版本的，也可以&lt;a href=&quot;http://mrszhao.com/post/345.html&quot; target=&quot;_blank&quot; title=&quot;Vue版本的todos本地任务清单&quot;&gt;点这里&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;增删改查功能都有，自己看代码。&lt;/p&gt;&lt;p&gt;核心代码：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;找对象
&amp;nbsp;&amp;nbsp;const&amp;nbsp;newTodoInput&amp;nbsp;=&amp;nbsp;$(&amp;#39;.new-todo&amp;#39;);
&amp;nbsp;&amp;nbsp;const&amp;nbsp;oTodoList&amp;nbsp;=&amp;nbsp;$(&amp;#39;.todo-list&amp;#39;);
&amp;nbsp;&amp;nbsp;const&amp;nbsp;oMain&amp;nbsp;=&amp;nbsp;$(&amp;#39;.main&amp;#39;);
&amp;nbsp;&amp;nbsp;const&amp;nbsp;oFooter&amp;nbsp;=&amp;nbsp;$(&amp;#39;.footer&amp;#39;);
&amp;nbsp;&amp;nbsp;const&amp;nbsp;oTodoCount&amp;nbsp;=&amp;nbsp;$(&amp;#39;.todo-count&amp;#39;);
&amp;nbsp;&amp;nbsp;const&amp;nbsp;oClearCompleted&amp;nbsp;=&amp;nbsp;$(&amp;#39;.clear-completed&amp;#39;);
&amp;nbsp;&amp;nbsp;const&amp;nbsp;oToggleAll&amp;nbsp;=&amp;nbsp;$(&amp;#39;.toggle-all&amp;#39;);
&amp;nbsp;&amp;nbsp;const&amp;nbsp;oTodoType&amp;nbsp;=&amp;nbsp;$$(&amp;#39;.filters&amp;nbsp;a&amp;#39;);

&amp;nbsp;&amp;nbsp;//&amp;nbsp;数据的本地存储
&amp;nbsp;&amp;nbsp;const&amp;nbsp;TODOS_KEY&amp;nbsp;=&amp;nbsp;&amp;#39;dotos_ES6&amp;#39;;
&amp;nbsp;&amp;nbsp;let&amp;nbsp;todosStorage&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;JSON.parse(localStorage.getItem(TODOS_KEY))&amp;nbsp;||&amp;nbsp;[];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set(todos)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;localStorage.setItem(TODOS_KEY,JSON.stringify(todos));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;//&amp;nbsp;全局变量
&amp;nbsp;&amp;nbsp;//&amp;nbsp;存储数据的todos
&amp;nbsp;&amp;nbsp;//&amp;nbsp;let&amp;nbsp;todos&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;nbsp;{&amp;nbsp;id:&amp;nbsp;1,&amp;nbsp;title:&amp;nbsp;&amp;#39;学习&amp;#39;,&amp;nbsp;completed:&amp;nbsp;false&amp;nbsp;},
&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;nbsp;{&amp;nbsp;id:&amp;nbsp;2,&amp;nbsp;title:&amp;nbsp;&amp;#39;做饭&amp;#39;,&amp;nbsp;completed:&amp;nbsp;true&amp;nbsp;},
&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;nbsp;{&amp;nbsp;id:&amp;nbsp;3,&amp;nbsp;title:&amp;nbsp;&amp;#39;接娃放学&amp;#39;,&amp;nbsp;completed:&amp;nbsp;true&amp;nbsp;},
&amp;nbsp;&amp;nbsp;//&amp;nbsp;]
&amp;nbsp;&amp;nbsp;let&amp;nbsp;todos&amp;nbsp;=&amp;nbsp;todosStorage.get();

&amp;nbsp;&amp;nbsp;//&amp;nbsp;用于区分单击和双击事件
&amp;nbsp;&amp;nbsp;let&amp;nbsp;timer&amp;nbsp;=&amp;nbsp;null;

&amp;nbsp;&amp;nbsp;//&amp;nbsp;初始化渲染
&amp;nbsp;&amp;nbsp;render(todos);

&amp;nbsp;&amp;nbsp;//&amp;nbsp;当enter的时候添加事项
&amp;nbsp;&amp;nbsp;newTodoInput.addEventListener(&amp;#39;keyup&amp;#39;,&amp;nbsp;(e)&amp;nbsp;=&amp;gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(e.key&amp;nbsp;===&amp;nbsp;&amp;#39;Enter&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;添加事项
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;addTodo();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todosStorage.set(todos);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;重新渲染
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;render(todos);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;})

&amp;nbsp;&amp;nbsp;//&amp;nbsp;因为有很多事项，有很多删除按钮，所以用事件委托性能更高
&amp;nbsp;&amp;nbsp;//&amp;nbsp;ul同时委托了单击事件和双击事件，通过300ms的延迟来判断是单击还是双击
&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果300ms以后没有单击，则是单击事件，执行对应的代码。
&amp;nbsp;&amp;nbsp;oTodoList.addEventListener(&amp;#39;click&amp;#39;,&amp;nbsp;function&amp;nbsp;(e)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;clearTimeout(timer);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;timer&amp;nbsp;=&amp;nbsp;setTimeout(function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;target&amp;nbsp;=&amp;nbsp;e.target;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(target);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;tempLi&amp;nbsp;=&amp;nbsp;target.closest(&amp;#39;li&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;根据li的id属性找到todos里面该id的数据,数字和字符串的相等用==
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;todo&amp;nbsp;=&amp;nbsp;todos.find(item&amp;nbsp;=&amp;gt;&amp;nbsp;item.id&amp;nbsp;==&amp;nbsp;tempLi.id);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果点击的是删除按钮，则删除该事项
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(target.className&amp;nbsp;===&amp;nbsp;&amp;#39;destroy&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delTodo(todo);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果点击的是复选框按钮，则切换完成和未完成的状态
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(target.className&amp;nbsp;===&amp;nbsp;&amp;#39;toggle&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todo.completed&amp;nbsp;=&amp;nbsp;target.checked;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;修复双击下出现输入框编辑的时候，单击输入框的文本，输入框又消失的问题
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(target.className&amp;nbsp;===&amp;nbsp;&amp;#39;edit&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;oEditing&amp;nbsp;=&amp;nbsp;tempLi.querySelector(&amp;#39;.edit&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tempLi.classList.add(&amp;#39;editing&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oEditing.focus();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todosStorage.set(todos);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;render(todos);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&amp;nbsp;300);
&amp;nbsp;&amp;nbsp;})

&amp;nbsp;&amp;nbsp;//&amp;nbsp;编辑事项
&amp;nbsp;&amp;nbsp;oTodoList.addEventListener(&amp;#39;dblclick&amp;#39;,&amp;nbsp;function&amp;nbsp;(e)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果300ms以内又有点击事件，则是双击事件，清掉前面定时器要执行的代码，执行双击对应的代码。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;clearTimeout(timer);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;target&amp;nbsp;=&amp;nbsp;e.target;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(target);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;tempLi&amp;nbsp;=&amp;nbsp;target.closest(&amp;#39;li&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;todo&amp;nbsp;=&amp;nbsp;todos.find(item&amp;nbsp;=&amp;gt;&amp;nbsp;item.id&amp;nbsp;==&amp;nbsp;tempLi.id);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(target.tagName&amp;nbsp;===&amp;nbsp;&amp;#39;LABEL&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;oEditing&amp;nbsp;=&amp;nbsp;tempLi.querySelector(&amp;#39;.edit&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tempLi.classList.add(&amp;#39;editing&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oEditing.focus();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;把输入框的光标放在最后面。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;element.setSelectionRange(selectionStart,&amp;nbsp;selectionEnd&amp;nbsp;[,&amp;nbsp;selectionDirection]);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果希望全选输入元素中的文本，你可以使用&amp;nbsp;HTMLInputElement.select()&amp;nbsp;方法。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oEditing.setSelectionRange(-1,&amp;nbsp;-1);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;存储输入框以前的数据
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;titleBeforeEdit&amp;nbsp;=&amp;nbsp;oEditing.value;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oEditing.addEventListener(&amp;#39;keyup&amp;#39;,&amp;nbsp;function&amp;nbsp;(e)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(e.key)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;val&amp;nbsp;=&amp;nbsp;this.value.trim();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;编辑完成
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(e.key&amp;nbsp;===&amp;nbsp;&amp;#39;Enter&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(val&amp;nbsp;===&amp;nbsp;&amp;#39;&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delTodo(todo);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todo.title&amp;nbsp;=&amp;nbsp;val;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todosStorage.set(todos);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;render(todos);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;取消编辑
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(e.key&amp;nbsp;===&amp;nbsp;&amp;#39;Escape&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.value&amp;nbsp;=&amp;nbsp;titleBeforeEdit;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;render(todos);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;失去焦点的时候，编辑完成
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oEditing.addEventListener(&amp;#39;blur&amp;#39;,&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;val&amp;nbsp;=&amp;nbsp;this.value.trim();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(val&amp;nbsp;===&amp;nbsp;&amp;#39;&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delTodo(todo);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todo.title&amp;nbsp;=&amp;nbsp;val;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todosStorage.set(todos);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;render(todos);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;})

&amp;nbsp;&amp;nbsp;//&amp;nbsp;删除完成的事项
&amp;nbsp;&amp;nbsp;oClearCompleted.addEventListener(&amp;#39;click&amp;#39;,&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todos&amp;nbsp;=&amp;nbsp;todos.filter(todo&amp;nbsp;=&amp;gt;&amp;nbsp;!todo.completed);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todosStorage.set(todos);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;render(todos);
&amp;nbsp;&amp;nbsp;})

&amp;nbsp;&amp;nbsp;//&amp;nbsp;点击全选复选框，对所有事项的状态切换
&amp;nbsp;&amp;nbsp;oToggleAll.addEventListener(&amp;#39;change&amp;#39;,&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;val&amp;nbsp;=&amp;nbsp;this.checked;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(const&amp;nbsp;todo&amp;nbsp;of&amp;nbsp;todos)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todo.completed&amp;nbsp;=&amp;nbsp;val;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todosStorage.set(todos);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;render(todos);
&amp;nbsp;&amp;nbsp;})

&amp;nbsp;&amp;nbsp;//&amp;nbsp;根据hash切换a的状态
&amp;nbsp;&amp;nbsp;//&amp;nbsp;不能点击a的时候获取hash，否则获取的是上一个hash值。
&amp;nbsp;&amp;nbsp;window.onhashchange&amp;nbsp;=&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;console.log(location.hash);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;a被选中的状态
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;selectedType();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;render(todos);
&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;//&amp;nbsp;找对象的函数
&amp;nbsp;&amp;nbsp;function&amp;nbsp;$(selector)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;document.querySelector(selector);
&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;function&amp;nbsp;$$(selector)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;document.querySelectorAll(selector);
&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;//&amp;nbsp;渲染事项
&amp;nbsp;&amp;nbsp;function&amp;nbsp;render(todos)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;对面板的切换
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(todos.length)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oMain.style.display&amp;nbsp;=&amp;nbsp;&amp;#39;block&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oFooter.style.display&amp;nbsp;=&amp;nbsp;&amp;#39;block&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oMain.style.display&amp;nbsp;=&amp;nbsp;&amp;#39;none&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oFooter.style.display&amp;nbsp;=&amp;nbsp;&amp;#39;none&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(!todos.length)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;renderTodos&amp;nbsp;=&amp;nbsp;[];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;筛选数据
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;console.log(location.hash);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;switch&amp;nbsp;(location.hash)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;&amp;#39;#/active&amp;#39;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;renderTodos&amp;nbsp;=&amp;nbsp;todos.filter(todo&amp;nbsp;=&amp;gt;&amp;nbsp;!todo.completed);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;&amp;#39;#/completed&amp;#39;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;renderTodos&amp;nbsp;=&amp;nbsp;todos.filter(todo&amp;nbsp;=&amp;gt;&amp;nbsp;todo.completed);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;renderTodos&amp;nbsp;=&amp;nbsp;todos;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;a的被选中状态
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;selectedType();

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;str&amp;nbsp;=&amp;nbsp;&amp;#39;&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(const&amp;nbsp;obj&amp;nbsp;of&amp;nbsp;renderTodos)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;str&amp;nbsp;+=&amp;nbsp;`&amp;lt;li&amp;nbsp;id=&amp;#39;${obj.id}&amp;#39;&amp;nbsp;class=${obj.completed&amp;nbsp;?&amp;nbsp;&amp;#39;completed&amp;#39;&amp;nbsp;:&amp;nbsp;&amp;#39;&amp;#39;}&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;class=&amp;quot;view&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;input&amp;nbsp;class=&amp;quot;toggle&amp;quot;&amp;nbsp;type=&amp;quot;checkbox&amp;quot;&amp;nbsp;${obj.completed&amp;nbsp;?&amp;nbsp;&amp;#39;checked&amp;#39;&amp;nbsp;:&amp;nbsp;&amp;#39;&amp;#39;}&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;label&amp;gt;${obj.title}&amp;lt;/label&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;button&amp;nbsp;class=&amp;quot;destroy&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;input&amp;nbsp;class=&amp;quot;edit&amp;quot;&amp;nbsp;value=&amp;quot;${obj.title}&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/li&amp;gt;`
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oTodoList.innerHTML&amp;nbsp;=&amp;nbsp;str;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;得到未完成的事项的个数。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;remainingCount&amp;nbsp;=&amp;nbsp;getRemainingCount(todos);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;状态栏&amp;nbsp;未完成数量的显示
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oTodoCount.innerHTML&amp;nbsp;=&amp;nbsp;`&amp;lt;strong&amp;gt;${remainingCount}&amp;lt;/strong&amp;gt;&amp;nbsp;${remainingCount&amp;nbsp;===&amp;nbsp;1&amp;nbsp;?&amp;nbsp;&amp;#39;item&amp;#39;&amp;nbsp;:&amp;nbsp;&amp;#39;items&amp;#39;}&amp;nbsp;left`

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;删除完成事项的按钮
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果事项的总个数大于未完成事项的个数，则按钮显示
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oClearCompleted.style.display&amp;nbsp;=&amp;nbsp;todos.length&amp;nbsp;&amp;gt;&amp;nbsp;remainingCount&amp;nbsp;?&amp;nbsp;&amp;#39;block&amp;#39;&amp;nbsp;:&amp;nbsp;&amp;#39;none&amp;#39;;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//对全选复选框的状态设置
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(remainingCount&amp;nbsp;===&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;todos.length&amp;nbsp;!==&amp;nbsp;0)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oToggleAll.checked&amp;nbsp;=&amp;nbsp;true;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oToggleAll.checked&amp;nbsp;=&amp;nbsp;false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;//&amp;nbsp;未完成的事项的个数
&amp;nbsp;&amp;nbsp;function&amp;nbsp;getRemainingCount(todos)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;todos.filter(item&amp;nbsp;=&amp;gt;&amp;nbsp;!item.completed).length;
&amp;nbsp;&amp;nbsp;}


&amp;nbsp;&amp;nbsp;//&amp;nbsp;添加事项
&amp;nbsp;&amp;nbsp;function&amp;nbsp;addTodo()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;value&amp;nbsp;=&amp;nbsp;newTodoInput.value.trim();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(!value)&amp;nbsp;return;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todos.push({&amp;nbsp;id:&amp;nbsp;Date.now(),&amp;nbsp;title:&amp;nbsp;value,&amp;nbsp;completed:&amp;nbsp;false&amp;nbsp;});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newTodoInput.value&amp;nbsp;=&amp;nbsp;&amp;#39;&amp;#39;;
&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;//&amp;nbsp;删除单个事项
&amp;nbsp;&amp;nbsp;function&amp;nbsp;delTodo(todo)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;index&amp;nbsp;=&amp;nbsp;todos.indexOf(todo);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(index&amp;nbsp;!==&amp;nbsp;-1)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;todos.splice(index,&amp;nbsp;1);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;//&amp;nbsp;事项类别状态设置
&amp;nbsp;&amp;nbsp;function&amp;nbsp;selectedType()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oTodoType.forEach((item,&amp;nbsp;index)&amp;nbsp;=&amp;gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(item.hash&amp;nbsp;===&amp;nbsp;location.hash)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oTodoType.forEach(item&amp;nbsp;=&amp;gt;&amp;nbsp;item.classList.remove(&amp;#39;selected&amp;#39;));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item.classList.add(&amp;#39;selected&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;console.log(item.hash);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt; © Copyright Birdol.Com 2006-2014.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/343.html&quot; target=&quot;_blank&quot;&gt;继续阅读《用ES6写了一个todos，本地任务清单！》的全文内容...&lt;/a&gt;&lt;/p&gt;&lt;p&gt;分类: JavaScript案例集 | Tags: &lt;a href=&quot;http://mrszhao.com/tags-324.html&quot;&gt;todoMVC&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-325.html&quot;&gt;todos&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-326.html&quot;&gt;本地任务清单&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-319.html&quot;&gt;ES6&lt;/a&gt;， | &lt;a href=&quot;http://mrszhao.com/post/343.html#comment&quot; target=&quot;_blank&quot;&gt;添加评论&lt;/a&gt;(0)&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/343.html#comment&quot; target=&quot;_blank&quot;&gt;还没有评论，您来说两句？&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;相关文章:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/341.html&quot;&gt;JavaScript(ES6)的常用特性！(下)&lt;/a&gt; (2023-07-20)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/342.html&quot;&gt; JavaScript(ES6)的常用特性！(上)&lt;/a&gt; (2023-07-18)  &lt;/li&gt;&lt;/ul&gt;&lt;a target=&quot;_blank&quot; title=&quot;阿里云优惠&quot; href=&quot;http://www.birdol.com/redirect/?s=6&quot;&gt;&lt;img alt=&quot;Z-Blog&quot; src=&quot;http://www.birdol.com/aliyun/qingdao950x90.jpg&quot;&gt;&lt;/a&gt;</description><pubDate>Sat, 22 Jul 2023 11:29:48 +0800</pubDate></item><item><title>JavaScript(ES6)的常用特性！(下)</title><link>http://mrszhao.com/post/341.html</link><description>&lt;p&gt;现在几乎都是使用ES6了，浏览器要兼容的时代随着移动端的统一归于平静，想起以前轰轰烈烈的浏览器大战，为了兼容性痛苦不堪的年代，这一切都过去了。况且随着脚手架等自动化构建工具的使用，直接写最新最酷的代码，再babel一下，放心大胆的用。&lt;br/&gt;&lt;/p&gt;&lt;p&gt;所以，我也建议直接用最新版本的语法，不管是语法糖，还是效率，用起来都更舒心。&lt;/p&gt;&lt;h2&gt;1、Symbol&lt;/h2&gt;&lt;p cid=&quot;n41&quot; mdtype=&quot;paragraph&quot;&gt;ES6为JavaScript引入了一个新的原生类型：Symbol，但是，和其他原生数据类型不一样，symbol没有字面量形式。作为构造函数来说它并不完整，因为它不支持语法：&amp;quot;&lt;code&gt;new Symbol()&lt;/code&gt;&amp;quot;。&lt;/p&gt;&lt;p cid=&quot;n43&quot; mdtype=&quot;paragraph&quot;&gt;下面是创建Symbol的过程：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;sym&amp;nbsp;=&amp;nbsp;Symbol(&amp;#39;something&amp;#39;)；
console.log(typeof&amp;nbsp;sym);&amp;nbsp;//symbol
console.dir(Symbol)&lt;/pre&gt;&lt;p cid=&quot;n46&quot; mdtype=&quot;paragraph&quot;&gt;注意事项：&lt;/p&gt;&lt;ul class=&quot;ul-list list-paddingleft-2&quot; cid=&quot;n48&quot; mdtype=&quot;list&quot; data-mark=&quot;-&quot; style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p cid=&quot;n50&quot; mdtype=&quot;paragraph&quot;&gt;不能也不应该对Symbol()使用new。它不是一个构造器，也不会创建一个对象。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p cid=&quot;n53&quot; mdtype=&quot;paragraph&quot;&gt;传给Symbol(...)的参数是可选的，如果传入了的话，应该是一个为这个symbol的用途给出用户友好描述的字符串。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p cid=&quot;n56&quot; mdtype=&quot;paragraph&quot;&gt;typeof的输出是一个新的值&amp;quot;symbol&amp;quot;，这是识别symbol的首选方法。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p cid=&quot;n58&quot; mdtype=&quot;paragraph&quot;&gt;两个Symbol永远不会相等&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;console.log(Symbol(&amp;#39;name&amp;#39;)&amp;nbsp;===&amp;nbsp;Symbol(&amp;#39;name&amp;#39;));&amp;nbsp;//&amp;nbsp;false&lt;/pre&gt;&lt;h3&gt;1.1 为对象添加私有成员&lt;/h3&gt;&lt;p cid=&quot;n62&quot; mdtype=&quot;paragraph&quot;&gt;利用Symbol不重复的特性，可以为对象添加不重复的键名。&lt;/p&gt;&lt;p cid=&quot;n64&quot; mdtype=&quot;paragraph&quot;&gt;每个从&amp;nbsp;&lt;code&gt;Symbol()&lt;/code&gt;&amp;nbsp;返回的 symbol 值都是唯一的。一个 symbol 值能作为对象属性的标识符；这是该数据类型的目的。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//使用&amp;nbsp;Symbol&amp;nbsp;为对象添加不重复的键

const&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{}
obj[Symbol()]&amp;nbsp;=&amp;nbsp;&amp;#39;123&amp;#39;
obj[Symbol()]&amp;nbsp;=&amp;nbsp;&amp;#39;456&amp;#39;
console.log(obj)

//也可以在计算属性名中使用

const&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;[Symbol()]:&amp;nbsp;123
}
console.log(obj)&lt;/pre&gt;&lt;p&gt;利用两个Symbol不相等的特性，可以为对象创建私有成员，外部不能访问。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;axisName&amp;nbsp;=&amp;nbsp;Symbol(&amp;#39;obj的别名&amp;#39;);
const&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;利用这种方式可以创建私有成员，外部不能访问
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[Symbol(&amp;#39;obj的id&amp;#39;)]:&amp;nbsp;1,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[Symbol(&amp;#39;obj的name&amp;#39;)]:&amp;nbsp;&amp;#39;obj&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[axisName]:&amp;nbsp;&amp;#39;myObj&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;url:&amp;nbsp;&amp;#39;http://www.xxx.com&amp;#39;

}
//&amp;nbsp;外部不能访问，因为没有两个Symbol是一样的。
console.log(obj[Symbol(&amp;#39;obj的id&amp;#39;)]);
console.log(obj[axisName]);
console.log(obj.url);&lt;/pre&gt;&lt;p&gt;常规的方式不能获取Symbol属性名&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;for...in遍历不出Symbol，仅包含了以字符串为键的属性
for(const&amp;nbsp;key&amp;nbsp;in&amp;nbsp;obj){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(key)
}
//&amp;nbsp;也不能返回Symbol，仅包含了对象自身的、可枚举的、以字符串为键的属性
console.log(Object.keys(obj))
//&amp;nbsp;当使用&amp;nbsp;JSON.stringify()&amp;nbsp;时，以&amp;nbsp;symbol&amp;nbsp;值作为键的属性会被完全忽略：
console.log(JSON.stringify(obj))&lt;/pre&gt;&lt;p&gt;ES6的Object专门提供了一个方法用于获取对象的Symbol属性。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//其包含的是以&amp;nbsp;Symbol&amp;nbsp;为键的属性
console.log(Object.getOwnPropertySymbols(obj));&amp;nbsp;//[Symbol(obj的id),&amp;nbsp;Symbol(obj的name),&amp;nbsp;Symbol(obj的别名)]&lt;/pre&gt;&lt;h3&gt;1.2 内置的Symbol属性&lt;/h3&gt;&lt;p cid=&quot;n77&quot; mdtype=&quot;paragraph&quot;&gt;除了自己创建的 symbol，JavaScript 还内建了一些在 ECMAScript 5 之前没有暴露给开发者的 symbol，它们代表了内部语言行为。它们可以使用以下属性访问：&lt;/p&gt;&lt;p cid=&quot;n79&quot; mdtype=&quot;paragraph&quot;&gt;1、迭代 symbols&amp;nbsp;&lt;code&gt;Symbol.iterator&lt;/code&gt; &lt;/p&gt;&lt;p cid=&quot;n81&quot; mdtype=&quot;paragraph&quot;&gt;一个返回一个对象默认迭代器的方法。被&amp;nbsp;&lt;code&gt;for...of&lt;/code&gt;&amp;nbsp;使用。&lt;/p&gt;&lt;p cid=&quot;n83&quot; mdtype=&quot;paragraph&quot;&gt;object默认没有这个迭代属性，所以不能使用for...of，但是可以自己定义&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//通过数组可以观察这个迭代器
const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;[1,&amp;nbsp;2,&amp;nbsp;3];
console.log(arr[Symbol.iterator]);&amp;nbsp;//&amp;nbsp;f()
const&amp;nbsp;it&amp;nbsp;=&amp;nbsp;arr[Symbol.iterator]();&amp;nbsp;//{next:&amp;nbsp;f(){}}
console.log(it.next());&amp;nbsp;//{value:&amp;nbsp;1,&amp;nbsp;done:&amp;nbsp;false}
console.log(it.next())
console.log(it.next())
console.log(it.next());&amp;nbsp;//{value:&amp;nbsp;undefined,&amp;nbsp;done:&amp;nbsp;true}&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;&amp;#39;诸葛&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;age:&amp;nbsp;18,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;address:&amp;nbsp;&amp;#39;卧龙岗&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[Symbol.iterator]:&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;_this&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;num&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;keys&amp;nbsp;=&amp;nbsp;Object.keys(_this);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;next:&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:&amp;nbsp;_this[keys[num++]],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;done:&amp;nbsp;num&amp;nbsp;&amp;gt;&amp;nbsp;keys.length
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
//现在可以使用for...of迭代obj了
for(const&amp;nbsp;value&amp;nbsp;of&amp;nbsp;myObj){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(value);
}&lt;/pre&gt;&lt;p cid=&quot;n87&quot; mdtype=&quot;paragraph&quot;&gt;2、&lt;code&gt;Symbol.replace&lt;/code&gt; &lt;/p&gt;&lt;p cid=&quot;n89&quot; mdtype=&quot;paragraph&quot;&gt;一个替换匹配字符串的子串的方法。被&amp;nbsp;&lt;code&gt;String.prototype.replace()&lt;/code&gt;&amp;nbsp;使用。&lt;/p&gt;&lt;p cid=&quot;n91&quot; mdtype=&quot;paragraph&quot;&gt;3、&lt;code&gt;Symbol.split&lt;/code&gt; &lt;/p&gt;&lt;p cid=&quot;n93&quot; mdtype=&quot;paragraph&quot;&gt;一个在匹配正则表达式的索引处拆分一个字符串的方法.。被&amp;nbsp;&lt;code&gt;String.prototype.split()&lt;/code&gt;&amp;nbsp;使用。&lt;/p&gt;&lt;p cid=&quot;n95&quot; mdtype=&quot;paragraph&quot;&gt;更多了解：&lt;/p&gt;&lt;p cid=&quot;n97&quot; mdtype=&quot;paragraph&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol&quot;&gt;https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;2、Set数据结构&lt;/h2&gt;&lt;p cid=&quot;n100&quot; mdtype=&quot;paragraph&quot;&gt;Set&amp;nbsp;对象允许你存储任何类型的唯一值，无论是原始值或者是对象引用。&lt;/p&gt;&lt;p cid=&quot;n102&quot; mdtype=&quot;paragraph&quot;&gt;&lt;code&gt;Set&lt;/code&gt;对象是值的集合，Set 中的元素只会出现一次，即 Set 中的元素是唯一的。&lt;/p&gt;&lt;p cid=&quot;n104&quot; mdtype=&quot;paragraph&quot;&gt;&lt;code&gt;NaN&lt;/code&gt;&amp;nbsp;和&amp;nbsp;&lt;code&gt;undefined&lt;/code&gt;&amp;nbsp;都可以被存储在 Set 中，&lt;code&gt;NaN&lt;/code&gt;&amp;nbsp;被视为相同的值（NaN 被认为是相同的，尽管 NaN !== NaN）。&lt;/p&gt;&lt;h3&gt;2.1 创建一个set数据结构的实例&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//Set&amp;nbsp;构造函数能创建&amp;nbsp;Set&amp;nbsp;对象实例
const&amp;nbsp;mySet&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Set();&amp;nbsp;//&amp;nbsp;Set(0)&amp;nbsp;{size:&amp;nbsp;0}&lt;/pre&gt;&lt;p&gt;参数iterable 可选，如果传递一个可迭代对象，它的所有元素将不重复地被添加到新的&amp;nbsp;&lt;code&gt;Set&lt;/code&gt;&amp;nbsp;中。如果不指定此参数或其值为&amp;nbsp;&lt;code&gt;null&lt;/code&gt;，则新的&amp;nbsp;&lt;code&gt;Set&lt;/code&gt;&amp;nbsp;为空，返回一个新的&amp;nbsp;&lt;code&gt;Set&lt;/code&gt;&amp;nbsp;对象。 &amp;nbsp;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;mySet1&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Set([1,2,2,3,3,4,5]);
console.log(mySet1);//Set(5)&amp;nbsp;{1,&amp;nbsp;2,&amp;nbsp;3,&amp;nbsp;4,&amp;nbsp;5}&lt;/pre&gt;&lt;h3&gt;2.2 实例的方法&lt;/h3&gt;&lt;h4&gt;2.2.1 添加add(value)&lt;/h4&gt;&lt;p&gt;如果&amp;nbsp;&lt;code&gt;Set&lt;/code&gt;&amp;nbsp;对象中没有具有相同值的元素，则&amp;nbsp;add()&amp;nbsp;方法将插入一个具有指定值的新元素到&amp;nbsp;&lt;code&gt;Set&lt;/code&gt;&amp;nbsp;对象中。 并返回&lt;code&gt;Set&lt;/code&gt;&amp;nbsp;对象本身，因此可以链式调用。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;mySet&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Set();
mySet.add(1).add(true).add(&amp;#39;Tom&amp;#39;).add(18)
console.log(mySet);&amp;nbsp;//Set(4)&amp;nbsp;{1,&amp;nbsp;true,&amp;nbsp;&amp;#39;Tom&amp;#39;,&amp;nbsp;18}&lt;/pre&gt;&lt;h4&gt;2.2.2 移除某个值delete(value)&lt;/h4&gt;&lt;p cid=&quot;n117&quot; mdtype=&quot;paragraph&quot;&gt;delete()&amp;nbsp;方法从&amp;nbsp;&lt;code&gt;Set&lt;/code&gt;&amp;nbsp;对象中删除指定的值（如果该值在&amp;nbsp;&lt;code&gt;Set&lt;/code&gt;&amp;nbsp;中）。&lt;/p&gt;&lt;p cid=&quot;n119&quot; mdtype=&quot;paragraph&quot;&gt;成功删除返回&amp;nbsp;&lt;code&gt;true&lt;/code&gt;，否则返回&amp;nbsp;&lt;code&gt;false&lt;/code&gt;。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;console.log(mySet.delete(&amp;#39;Tom&amp;#39;));&amp;nbsp;//&amp;nbsp;true
console.log(mySet.delete(&amp;#39;daisy&amp;#39;));//false&lt;/pre&gt;&lt;p cid=&quot;n122&quot; mdtype=&quot;paragraph&quot;&gt;从Set中删除对象。&lt;/p&gt;&lt;p cid=&quot;n124&quot; mdtype=&quot;paragraph&quot;&gt;因为对象是通过引用比较的，所以如果没有对原始对象的引用，就必须通过检查单个属性来删除它们。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;setObj&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Set();
setObj.add({&amp;nbsp;x:&amp;nbsp;5,&amp;nbsp;y:&amp;nbsp;20&amp;nbsp;}).add({&amp;nbsp;x:&amp;nbsp;20,&amp;nbsp;y:&amp;nbsp;30&amp;nbsp;});
//&amp;nbsp;删除任何x&amp;nbsp;&amp;gt;&amp;nbsp;10&amp;nbsp;的对象&amp;nbsp;
setObj.forEach(point&amp;nbsp;=&amp;gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(point.x&amp;nbsp;&amp;gt;&amp;nbsp;10)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setObj.delete(point);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
})
console.log(setObj)&lt;/pre&gt;&lt;h4&gt;2.2.3 移除所有元素 clear()&lt;/h4&gt;&lt;p cid=&quot;n128&quot; mdtype=&quot;paragraph&quot;&gt;clear()&amp;nbsp;方法移除&amp;nbsp;&lt;code&gt;Set&lt;/code&gt;&amp;nbsp;对象中所有元素。 返回值为undefined.&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;mySet.clear()&lt;/pre&gt;&lt;h4&gt;2.2.4 has(value)&lt;/h4&gt;&lt;p cid=&quot;n132&quot; mdtype=&quot;paragraph&quot;&gt;has()&amp;nbsp;方法返回一个布尔值来指示对应的值是否存在于&amp;nbsp;&lt;code&gt;Set&lt;/code&gt;&amp;nbsp;对象中。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;setObj&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Set();
setObj.add({&amp;nbsp;x:&amp;nbsp;5,&amp;nbsp;y:&amp;nbsp;20&amp;nbsp;}).add({&amp;nbsp;x:&amp;nbsp;20,&amp;nbsp;y:&amp;nbsp;30&amp;nbsp;}).add(&amp;#39;circle&amp;#39;);
console.log(setObj.has({&amp;nbsp;x:&amp;nbsp;20,&amp;nbsp;y:&amp;nbsp;30}));&amp;nbsp;//&amp;nbsp;false,不是一个对象的引用
console.log(setObj.has(&amp;#39;circle&amp;#39;));&amp;nbsp;//true&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Set&quot;&gt;https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Set&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;2.3 实例的属性&lt;/h3&gt;&lt;p cid=&quot;n138&quot; mdtype=&quot;paragraph&quot;&gt;size&amp;nbsp;属性将会返回&amp;nbsp;&lt;code&gt;Set&lt;/code&gt;&amp;nbsp;对象中（唯一的）元素的个数。&lt;/p&gt;&lt;p cid=&quot;n140&quot; mdtype=&quot;paragraph&quot;&gt;&lt;code&gt;size&lt;/code&gt;&amp;nbsp;的值是一个整数，表示&amp;nbsp;&lt;code&gt;Set&lt;/code&gt;&amp;nbsp;对象有多少条目。&lt;code&gt;size&lt;/code&gt;&amp;nbsp;的 set 访问函数是&amp;nbsp;&lt;code&gt;undefined&lt;/code&gt;；你不能改变这个属性。 也就是只能读不能写。&lt;/p&gt;&lt;h3&gt;2.4 遍历&lt;/h3&gt;&lt;h4&gt;2.4.1 forEach()&lt;/h4&gt;&lt;p cid=&quot;n144&quot; mdtype=&quot;paragraph&quot;&gt;forEach()&amp;nbsp;方法对&amp;nbsp;&lt;code&gt;Set&lt;/code&gt;&amp;nbsp;对象中的每个值按插入顺序执行一次提供的函数。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;setObj.forEach(item&amp;nbsp;=&amp;gt;&amp;nbsp;console.log(item))&lt;/pre&gt;&lt;h4&gt;2.4.2 for ... of&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;for(const&amp;nbsp;item&amp;nbsp;of&amp;nbsp;setObj){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(item);
}&lt;/pre&gt;&lt;h3&gt;2.5 应用场景&lt;/h3&gt;&lt;h4&gt;2.5.1 和数组的转换&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;数组去重
const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;[1,1,2,2,3,3,4,5];
//const&amp;nbsp;newArr&amp;nbsp;=&amp;nbsp;Array.from(new&amp;nbsp;Set(arr));
const&amp;nbsp;newArr&amp;nbsp;=&amp;nbsp;[...new&amp;nbsp;Set(arr)];
console.log(newArr);&amp;nbsp;//&amp;nbsp;[1,&amp;nbsp;2,&amp;nbsp;3,&amp;nbsp;4,&amp;nbsp;5]&lt;/pre&gt;&lt;h4&gt;2.5.2 和字符串相关&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;str1&amp;nbsp;=&amp;nbsp;&amp;#39;javascript&amp;#39;;
let&amp;nbsp;str2&amp;nbsp;=&amp;nbsp;&amp;#39;JAvaScript&amp;#39;;
let&amp;nbsp;s1&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Set(str1);
let&amp;nbsp;s2&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Set(str2);
//大小写敏感
console.log(s1);&amp;nbsp;//Set(9)&amp;nbsp;{&amp;#39;j&amp;#39;,&amp;nbsp;&amp;#39;a&amp;#39;,&amp;nbsp;&amp;#39;v&amp;#39;,&amp;nbsp;&amp;#39;s&amp;#39;,&amp;nbsp;&amp;#39;c&amp;#39;,&amp;nbsp;…}
console.log(s2);&amp;nbsp;//Set(10)&amp;nbsp;{&amp;#39;J&amp;#39;,&amp;nbsp;&amp;#39;A&amp;#39;,&amp;nbsp;&amp;#39;v&amp;#39;,&amp;nbsp;&amp;#39;a&amp;#39;,&amp;nbsp;&amp;#39;S&amp;#39;,&amp;nbsp;…}&lt;/pre&gt;&lt;h2&gt;3、Map数据结构&lt;/h2&gt;&lt;p cid=&quot;n155&quot; mdtype=&quot;paragraph&quot;&gt;Map&amp;nbsp;对象保存键值对，并且能够记住键的原始插入顺序。任何值（对象或者基本类型）都可以作为一个键或一个值。&lt;/p&gt;&lt;h3&gt;3.1 对键值的操作&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;创建一个map实例
const&amp;nbsp;myMap&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Map();
//&amp;nbsp;这种方式赋值不能改变map的数据结构，所以不推荐
//&amp;nbsp;myMap.name&amp;nbsp;=&amp;nbsp;&amp;#39;mrszhao&amp;#39;;
//&amp;nbsp;正确的方式，使用set方法
myMap.set(&amp;#39;name&amp;#39;,&amp;nbsp;&amp;#39;mrszhao&amp;#39;);
myMap.set(&amp;#39;age&amp;#39;,&amp;nbsp;18);
myMap.set(&amp;#39;city&amp;#39;,&amp;nbsp;&amp;#39;成都&amp;#39;);
myMap.set(&amp;#39;city&amp;#39;,&amp;nbsp;&amp;#39;重庆&amp;#39;);
//&amp;nbsp;使用get方法获取键的值
console.log(myMap.get(&amp;#39;city&amp;#39;));
//&amp;nbsp;size属性获取键值对的数量
console.log(myMap.size);
//&amp;nbsp;删除键值对，返回布尔值
myMap.delete(&amp;#39;age&amp;#39;);
//&amp;nbsp;判断知否存在某个键，返回布尔值
console.log(myMap.has(&amp;#39;name&amp;#39;))
console.log(myMap);&lt;/pre&gt;&lt;p&gt;注意：键名具有唯一性，重复设置，后面的值会覆盖前面的值，而且，键值对是根据设置的顺序保存的。&lt;/p&gt;&lt;h3&gt;3.2 键名可以是任意的数据类型&lt;/h3&gt;&lt;p cid=&quot;n162&quot; mdtype=&quot;paragraph&quot;&gt;object对象的键名只能是string和symbol，而map数据的键名可以是任意数据类型，包括复杂数据类型。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//对象的键名会被转成字符串，对象转成字符串是[object&amp;nbsp;Object]
const&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[Symbol()]:&amp;nbsp;&amp;#39;mrszhaoObj&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;&amp;#39;诸葛&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1:&amp;nbsp;1,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;true:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[{a:&amp;nbsp;1}]:&amp;nbsp;&amp;#39;a&amp;#39;
}
console.log(obj);
obj[{b:&amp;nbsp;1}]&amp;nbsp;=&amp;nbsp;&amp;#39;b&amp;#39;;
console.log(Object.keys(obj))
console.log(obj[&amp;#39;[object&amp;nbsp;Object]&amp;#39;])&lt;/pre&gt;&lt;p&gt;map的优势在于可以使用对象作为键名。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;o&amp;nbsp;=&amp;nbsp;{b:&amp;nbsp;2};
myMap.set({a:&amp;nbsp;1},&amp;nbsp;&amp;#39;a&amp;#39;);
myMap.set(o,&amp;nbsp;&amp;#39;b&amp;#39;);
myMap.set(function&amp;nbsp;a(){}&amp;nbsp;,&amp;nbsp;1);
myMap.set(true,&amp;nbsp;1);
//对象的key只能出现一次&amp;nbsp;&amp;nbsp;要用对象来设键名的时候，一定要在外面设变量
//&amp;nbsp;因为{}&amp;nbsp;===&amp;nbsp;{}&amp;nbsp;false
console.log(map.get({a:&amp;nbsp;1}));&amp;nbsp;//undefined
console.log(map.get(o));&amp;nbsp;//&amp;nbsp;&amp;#39;b&amp;#39;&lt;/pre&gt;&lt;h3&gt;3.3 map的遍历&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;第一个参数是value,第二个参数是key
&amp;nbsp;myMap.forEach((value,&amp;nbsp;key)&amp;nbsp;=&amp;gt;&amp;nbsp;console.log(key,&amp;nbsp;value));&lt;/pre&gt;&lt;p&gt;因为拥有迭代器属性，可以使用for...of&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;遍历出来的item是一个包含key和value的数组
//&amp;nbsp;使用数组的解构方式
for(const&amp;nbsp;[key,&amp;nbsp;value]&amp;nbsp;of&amp;nbsp;myMap){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(key,&amp;nbsp;value)
}&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//只遍历键名。myMap.keys()返回一个有迭代器的对象，所以可以用for...of
for(const&amp;nbsp;key&amp;nbsp;of&amp;nbsp;myMap.keys()){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(key)
}
//&amp;nbsp;只遍历值
for(const&amp;nbsp;value&amp;nbsp;of&amp;nbsp;myMap.values()){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(value)
}&lt;/pre&gt;&lt;h3&gt;3.4 map和数组的转换&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;arrMap&amp;nbsp;=&amp;nbsp;[[&amp;#39;key1&amp;#39;,&amp;nbsp;&amp;#39;value1&amp;#39;],&amp;nbsp;[&amp;#39;key2&amp;#39;,&amp;nbsp;&amp;#39;value2&amp;#39;]];
//使用常规的&amp;nbsp;Map&amp;nbsp;构造函数可以将一个二维键值对数组转换成一个&amp;nbsp;Map&amp;nbsp;对象
const&amp;nbsp;myMap1&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Map(arrMap);&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;const&amp;nbsp;newArr&amp;nbsp;=&amp;nbsp;Array.from(myMap1);
//最简单的是使用...扩展运算符展开对象，再放入数组。
&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;newArr&amp;nbsp;=&amp;nbsp;[...myMap];&lt;/pre&gt;&lt;p cid=&quot;n179&quot; mdtype=&quot;paragraph&quot;&gt;更多Map和Object对象的差别，可以查看文档：&lt;/p&gt;&lt;p cid=&quot;n181&quot; mdtype=&quot;paragraph&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map&quot;&gt;https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;4、Object相关&lt;/h2&gt;&lt;h3&gt;4.1 Object.assign()&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;Object.assign(target,&amp;nbsp;...sources)&lt;/pre&gt;&lt;p cid=&quot;n188&quot; mdtype=&quot;paragraph&quot;&gt;Object.assign()&amp;nbsp;方法将所有可枚举（&lt;code&gt;Object.propertyIsEnumerable()&lt;/code&gt;&amp;nbsp;返回 true）的自有（&lt;code&gt;Object.hasOwnProperty()&lt;/code&gt;&amp;nbsp;返回 true）属性从一个或多个源对象复制到目标对象，返回修改后的对象。&lt;/p&gt;&lt;p cid=&quot;n190&quot; mdtype=&quot;paragraph&quot;&gt;如果目标对象与源对象具有相同的&amp;nbsp;key，则目标对象中的属性将被源对象中的属性覆盖，后面的源对象的属性将类似地覆盖前面的源对象的属性。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;target&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:&amp;nbsp;1,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b:&amp;nbsp;2
}
const&amp;nbsp;source1&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:&amp;nbsp;2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c:&amp;nbsp;3
}
const&amp;nbsp;source2&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:&amp;nbsp;3,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;d:&amp;nbsp;4
}
const&amp;nbsp;result&amp;nbsp;=&amp;nbsp;Object.assign(target,&amp;nbsp;source1,&amp;nbsp;source2);
console.log(result,&amp;nbsp;result&amp;nbsp;===&amp;nbsp;target);&lt;/pre&gt;&lt;p&gt;点击空白页面产生小球，点击小球删除自己。&lt;a href=&quot;http://mrszhao.com/zb_users/upload/2023/07/randomBall.html&quot; target=&quot;_blank&quot; title=&quot;点击页面产生随机颜色的小球&quot;&gt;试试&lt;/a&gt;。看到空白页面使劲点。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;Circle(option)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;option&amp;nbsp;=&amp;nbsp;option&amp;nbsp;||&amp;nbsp;{};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.shape&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;r:&amp;nbsp;30,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bgColor:&amp;nbsp;&amp;#39;#f60&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x:&amp;nbsp;0,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y:&amp;nbsp;0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Object.assign(this.shape,&amp;nbsp;option);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Circle.prototype.removeCircle&amp;nbsp;=&amp;nbsp;function()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;我被干掉了&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;oHTML&amp;nbsp;=&amp;nbsp;document.documentElement;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oHTML.addEventListener(&amp;#39;click&amp;#39;,&amp;nbsp;function&amp;nbsp;(e)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;circle&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Circle({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;r:&amp;nbsp;getRandom(20,&amp;nbsp;50),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bgColor:&amp;nbsp;`rgba(${getRandom(0,&amp;nbsp;255)},${getRandom(0,&amp;nbsp;255)},${getRandom(0,&amp;nbsp;255)},&amp;nbsp;${Math.random()})`,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x:&amp;nbsp;e.x,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y:&amp;nbsp;e.y,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(circle);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;oDiv&amp;nbsp;=&amp;nbsp;document.createElement(&amp;#39;div&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oDiv.style.cssText&amp;nbsp;=&amp;nbsp;`width:${circle.shape.r&amp;nbsp;*&amp;nbsp;2}px;height:${circle.shape.r&amp;nbsp;*&amp;nbsp;2}px;background-color:${circle.shape.bgColor};border-radius:50%;position:absolute;left:${circle.shape.x&amp;nbsp;-&amp;nbsp;circle.shape.r}px;top:${circle.shape.y&amp;nbsp;-&amp;nbsp;circle.shape.r}px;transition:0.2s`;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;document.body.appendChild(oDiv);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oDiv.addEventListener(&amp;#39;click&amp;#39;,&amp;nbsp;function(e)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.remove();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;circle.removeCircle();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.stopPropagation();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;getRandom(min,&amp;nbsp;max)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;Math.floor(Math.random()&amp;nbsp;*&amp;nbsp;(max&amp;nbsp;-&amp;nbsp;min&amp;nbsp;+&amp;nbsp;1)&amp;nbsp;+&amp;nbsp;min);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;4.2 Object.is()&lt;/h3&gt;&lt;p cid=&quot;n197&quot; mdtype=&quot;paragraph&quot;&gt;Object.is()&amp;nbsp;方法判断两个值是否为同一个值。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;Object.is(value1,&amp;nbsp;value2);&lt;/pre&gt;&lt;p&gt;Object.is的判断规则和==和===都不同。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;console.log(Object.is(+0,&amp;nbsp;-0),&amp;nbsp;+0&amp;nbsp;===&amp;nbsp;-0);&amp;nbsp;//&amp;nbsp;false&amp;nbsp;true
console.log(Object.is(NaN,&amp;nbsp;NaN),&amp;nbsp;NaN&amp;nbsp;===&amp;nbsp;NaN);&amp;nbsp;//true&amp;nbsp;false
console.log(Object.is(undefined,&amp;nbsp;null),&amp;nbsp;undefined&amp;nbsp;==&amp;nbsp;null);&amp;nbsp;//false&amp;nbsp;true&lt;/pre&gt;&lt;h3&gt;4.3 Object.create()&lt;/h3&gt;&lt;p cid=&quot;n204&quot; mdtype=&quot;paragraph&quot;&gt;Object.create()&amp;nbsp;方法用于创建一个新对象，使用现有的对象来作为新创建对象的原型（prototype）。&lt;/p&gt;&lt;p&gt;比如下面这个案例，点击页面产生一个圆，点击圆本身，会弹出它的面积。&lt;a href=&quot;http://mrszhao.com/zb_users/upload/2023/07/borderCircle.html&quot; target=&quot;_blank&quot; title=&quot;点击页面产生圆&quot;&gt;试试&lt;/a&gt;。&lt;br/&gt;&lt;/p&gt;&lt;p&gt;核心代码：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;创建一个大类&amp;nbsp;圆，有半径，x坐标,&amp;nbsp;y坐标三个属性
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;Circle(r&amp;nbsp;=&amp;nbsp;20,&amp;nbsp;x&amp;nbsp;=&amp;nbsp;0,&amp;nbsp;y&amp;nbsp;=&amp;nbsp;0)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.r&amp;nbsp;=&amp;nbsp;r;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.x&amp;nbsp;=&amp;nbsp;x;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.y&amp;nbsp;=&amp;nbsp;y;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;有一个原型上的获取面积的方法
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Circle.prototype.getArea&amp;nbsp;=&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;Math.floor(Math.PI&amp;nbsp;*&amp;nbsp;(this.r&amp;nbsp;**&amp;nbsp;2));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;创建一个子类，产生有背景颜色的圆
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;BgcolorCircle(bgcolor&amp;nbsp;=&amp;nbsp;&amp;#39;#000&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.bgcolor&amp;nbsp;=&amp;nbsp;bgcolor;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;执行大类的构造函数，让子类也有这三个属性，并且有默认值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Circle.call(this);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;把大类的原型对象当作小类的原型对象的原型，小类的实例也可以访问大类原型上的方法
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BgcolorCircle.prototype&amp;nbsp;=&amp;nbsp;Object.create(Circle.prototype);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果不指定构造函数，会默认指向Circle上级对象
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BgcolorCircle.prototype.constructor&amp;nbsp;=&amp;nbsp;BgcolorCircle;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;oHTML&amp;nbsp;=&amp;nbsp;document.documentElement;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oHTML.addEventListener(&amp;#39;click&amp;#39;,&amp;nbsp;function&amp;nbsp;(e)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;cc&amp;nbsp;=&amp;nbsp;new&amp;nbsp;BgcolorCircle();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cc.r&amp;nbsp;=&amp;nbsp;getRandom(10,&amp;nbsp;100);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cc.x&amp;nbsp;=&amp;nbsp;e.x;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cc.y&amp;nbsp;=&amp;nbsp;e.y;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cc.bgcolor&amp;nbsp;=&amp;nbsp;`rgba(${getRandom(70,&amp;nbsp;255)},${getRandom(70,&amp;nbsp;255)},${getRandom(70,&amp;nbsp;255)})`;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;oDiv&amp;nbsp;=&amp;nbsp;document.createElement(&amp;#39;div&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oDiv.style.cssText&amp;nbsp;=&amp;nbsp;`width:&amp;nbsp;${cc.r&amp;nbsp;*&amp;nbsp;2}px;height:${cc.r&amp;nbsp;*&amp;nbsp;2}px;position:absolute;left:${cc.x&amp;nbsp;-&amp;nbsp;cc.r}px;top:${cc.y&amp;nbsp;-&amp;nbsp;cc.r}px;background-color:&amp;nbsp;${cc.bgcolor};border-radius:50%`;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;document.body.appendChild(oDiv);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oDiv.addEventListener(&amp;#39;click&amp;#39;,&amp;nbsp;function&amp;nbsp;(e)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert(`我的面积是：${cc.getArea()}`);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.stopPropagation();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;getRandom(min,&amp;nbsp;max)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;Math.floor(Math.random()&amp;nbsp;*&amp;nbsp;(max&amp;nbsp;-&amp;nbsp;min&amp;nbsp;+&amp;nbsp;1)&amp;nbsp;+&amp;nbsp;min);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h2&gt;5、class类&lt;/h2&gt;&lt;p&gt;看看Class类这个语法糖有多甜。&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;5.1 声明类&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;类声明，没有提升，先声明再实例化
class&amp;nbsp;Circle&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//用于创建和初始化一个由class创建的对象
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;constructor(r&amp;nbsp;=&amp;nbsp;20,&amp;nbsp;x&amp;nbsp;=&amp;nbsp;0,&amp;nbsp;y&amp;nbsp;=&amp;nbsp;0)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.r&amp;nbsp;=&amp;nbsp;r;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.x&amp;nbsp;=&amp;nbsp;x;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.y&amp;nbsp;=&amp;nbsp;y;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;getter&amp;nbsp;只读属性
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&amp;nbsp;area()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this.getArea();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;原型方法
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;getArea()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;(Math.PI&amp;nbsp;*&amp;nbsp;(this.r&amp;nbsp;**&amp;nbsp;2)).toFixed(2);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

const&amp;nbsp;c&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Circle(50);
console.log(c);
console.log(c.area);
console.log(c.getArea());&lt;/pre&gt;&lt;h3&gt;5.2 静态属性和方法&lt;/h3&gt;&lt;p cid=&quot;n211&quot; mdtype=&quot;paragraph&quot;&gt;不能在类的实例上调用静态方法，而应该通过类本身调用。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;类声明，没有提升，先声明再实例化
class&amp;nbsp;Circle&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//用于创建和初始化一个由class创建的对象
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;constructor(r&amp;nbsp;=&amp;nbsp;20,&amp;nbsp;x&amp;nbsp;=&amp;nbsp;0,&amp;nbsp;y&amp;nbsp;=&amp;nbsp;0)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.r&amp;nbsp;=&amp;nbsp;r;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.x&amp;nbsp;=&amp;nbsp;x;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.y&amp;nbsp;=&amp;nbsp;y;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;getter&amp;nbsp;只读属性
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&amp;nbsp;area()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this.getArea();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;静态属性，只有类能访问，实例不能访问
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&amp;nbsp;proname&amp;nbsp;=&amp;nbsp;&amp;#39;Circle&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;原型方法
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;getArea()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;(Math.PI&amp;nbsp;*&amp;nbsp;(this.r&amp;nbsp;**&amp;nbsp;2)).toFixed(2);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;静态方法
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&amp;nbsp;createDefaultCircle()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;new&amp;nbsp;Circle();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
//&amp;nbsp;只能类访问静态属性和静态方法
console.log(Circle.proname);
console.log(Circle.createDefaultCircle());&lt;/pre&gt;&lt;h3&gt;5.3 extends扩展子类&lt;/h3&gt;&lt;p cid=&quot;n215&quot; mdtype=&quot;paragraph&quot;&gt;extends&amp;nbsp;关键字用于类声明中，以创建一个类，该类是另一个类的子类。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;class&amp;nbsp;ChildClass&amp;nbsp;extends&amp;nbsp;ParentClass&amp;nbsp;{&amp;nbsp;...&amp;nbsp;}&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;使用extends扩展内置对象,产生一个内置对象的子类
class&amp;nbsp;myDate&amp;nbsp;extends&amp;nbsp;Date&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;constructor(date&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Date())&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;super&amp;nbsp;关键字用于调用对象的父对象上的函数。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;调用超类构造函数并执行。相当于Circle.call(this);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;并把子类的参数传递给父类。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;super(date);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;getFormattedDate()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;week&amp;nbsp;=&amp;nbsp;[&amp;#39;星期天&amp;#39;,&amp;nbsp;&amp;#39;星期一&amp;#39;,&amp;nbsp;&amp;#39;星期二&amp;#39;,&amp;nbsp;&amp;#39;星期三&amp;#39;,&amp;nbsp;&amp;#39;星期四&amp;#39;,&amp;nbsp;&amp;#39;星期五&amp;#39;,&amp;nbsp;&amp;#39;星期六&amp;#39;];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;date&amp;nbsp;=&amp;nbsp;this.getDate();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;month&amp;nbsp;=&amp;nbsp;this.getMonth()&amp;nbsp;+&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;year&amp;nbsp;=&amp;nbsp;this.getFullYear();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;date&amp;nbsp;=&amp;nbsp;date&amp;nbsp;&amp;lt;&amp;nbsp;10&amp;nbsp;?&amp;nbsp;&amp;#39;0&amp;#39;&amp;nbsp;+&amp;nbsp;date&amp;nbsp;:&amp;nbsp;date;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;month&amp;nbsp;=&amp;nbsp;month&amp;nbsp;&amp;lt;&amp;nbsp;10&amp;nbsp;?&amp;nbsp;&amp;#39;0&amp;#39;&amp;nbsp;+&amp;nbsp;month&amp;nbsp;:&amp;nbsp;month;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;`${year}.${month}.${date}&amp;nbsp;${week[this.getDay()]}`;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&amp;nbsp;

const&amp;nbsp;mydate&amp;nbsp;=&amp;nbsp;new&amp;nbsp;myDate();
console.log(mydate.getFormattedDate());
const&amp;nbsp;mydate1&amp;nbsp;=&amp;nbsp;new&amp;nbsp;myDate(&amp;#39;2023-10-1&amp;#39;)
console.log(mydate1.getFormattedDate());&lt;/pre&gt;&lt;p&gt;扩展Circle的子类对象&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;class&amp;nbsp;ColorCircle&amp;nbsp;extends&amp;nbsp;Circle&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;constructor(bgcolor&amp;nbsp;=&amp;nbsp;&amp;#39;#000&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果子类中定义了构造函数，那么它必须先调用&amp;nbsp;super()&amp;nbsp;才能使用&amp;nbsp;this&amp;nbsp;。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;super();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;console.log(super());//返回了子对象，后面才能使用this来指向子对象。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.bgcolor&amp;nbsp;=&amp;nbsp;bgcolor;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

const&amp;nbsp;bgcircle&amp;nbsp;=&amp;nbsp;new&amp;nbsp;ColorCircle(&amp;#39;#f30&amp;#39;);
console.log(bgcircle);
bgcircle.r&amp;nbsp;=&amp;nbsp;30;
console.log(bgcircle.area);

class&amp;nbsp;BorderCircle&amp;nbsp;extends&amp;nbsp;Circle&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;constructor(border&amp;nbsp;=&amp;nbsp;&amp;#39;1px&amp;nbsp;solid&amp;nbsp;#000&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;super();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.border&amp;nbsp;=border;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

const&amp;nbsp;bordercircle&amp;nbsp;=&amp;nbsp;new&amp;nbsp;BorderCircle();
console.log(bordercircle);
bordercircle.border&amp;nbsp;=&amp;nbsp;`5px&amp;nbsp;solid&amp;nbsp;${bgcircle.bgcolor}`
bordercircle.r&amp;nbsp;=&amp;nbsp;40;
console.log(bordercircle.area);&lt;/pre&gt;&lt;p&gt;现在Class类的写法比起以前原型的复杂写法看起来要清爽很多。&lt;/p&gt;&lt;p&gt;还有一些高级的内容，比如Promise异步、代理等等，后面有时间再写了。&lt;br/&gt;&lt;/p&gt;&lt;p&gt; © Copyright Birdol.Com 2006-2014.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/341.html&quot; target=&quot;_blank&quot;&gt;继续阅读《JavaScript(ES6)的常用特性！(下)》的全文内容...&lt;/a&gt;&lt;/p&gt;&lt;p&gt;分类: JavaScript教程 | Tags: &lt;a href=&quot;http://mrszhao.com/tags-319.html&quot;&gt;ES6&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-320.html&quot;&gt;Set&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-321.html&quot;&gt;Map&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-322.html&quot;&gt;Class&lt;/a&gt;， | &lt;a href=&quot;http://mrszhao.com/post/341.html#comment&quot; target=&quot;_blank&quot;&gt;添加评论&lt;/a&gt;(0)&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/341.html#comment&quot; target=&quot;_blank&quot;&gt;还没有评论，您来说两句？&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;相关文章:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/343.html&quot;&gt;用ES6写了一个todos，本地任务清单！&lt;/a&gt; (2023-07-22)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/342.html&quot;&gt; JavaScript(ES6)的常用特性！(上)&lt;/a&gt; (2023-07-18)  &lt;/li&gt;&lt;/ul&gt;&lt;a target=&quot;_blank&quot; title=&quot;阿里云优惠&quot; href=&quot;http://www.birdol.com/redirect/?s=6&quot;&gt;&lt;img alt=&quot;Z-Blog&quot; src=&quot;http://www.birdol.com/aliyun/qingdao950x90.jpg&quot;&gt;&lt;/a&gt;</description><pubDate>Thu, 20 Jul 2023 17:25:06 +0800</pubDate></item><item><title> JavaScript(ES6)的常用特性！(上)</title><link>http://mrszhao.com/post/342.html</link><description>&lt;p&gt;这个版本算是JavaScript划时代的一个升级了，从ES3、ES5、ES6，为什么没有ES4，其实ES5和ES6加起来就是曾经因为跨度太大导致流产的ES4.&lt;br/&gt;&lt;/p&gt;&lt;p&gt;这个版本升级的力度很大，有了很多新东西，需要好好掌握。&lt;/p&gt;&lt;h2&gt;1、ES6介绍&lt;/h2&gt;&lt;p cid=&quot;n41&quot; mdtype=&quot;paragraph&quot;&gt;ECMAScript 6.0（以下简称 ES6）是 JavaScript 语言的下一代标准，已经在 2015 年 6 月正式发布了。它的目标，是使得 JavaScript 语言可以用来编写复杂的大型应用程序，成为企业级开发语言。&lt;/p&gt;&lt;p cid=&quot;n43&quot; mdtype=&quot;paragraph&quot;&gt;2011 年，ECMAScript 5.1 版发布后，就开始制定 6.0 版了。因此，ES6 这个词的原意，就是指 JavaScript 语言的下一个版本。&lt;/p&gt;&lt;p cid=&quot;n45&quot; mdtype=&quot;paragraph&quot;&gt;标准在每年的 6 月份正式发布一次，作为当年的正式版本。接下来的时间，就在这个版本的基础上做改动，直到下一年的 6 月份，草案就自然变成了新一年的版本。这样一来，就不需要以前的版本号了，只要用年份标记就可以了。&lt;/p&gt;&lt;p cid=&quot;n47&quot; mdtype=&quot;paragraph&quot;&gt;ES6 的第一个版本，就这样在 2015 年 6 月发布了，正式名称就是《ECMAScript 2015 标准》（简称 ES2015）。2016 年 6 月，小幅修订的《ECMAScript 2016 标准》（简称 ES2016）如期发布，这个版本可以看作是 ES6.1 版，因为两者的差异非常小（只新增了数组实例的&lt;code&gt;includes&lt;/code&gt;方法和指数运算符），基本上是同一个标准。根据计划，2017 年 6 月发布 ES2017 标准。&lt;/p&gt;&lt;p cid=&quot;n49&quot; mdtype=&quot;paragraph&quot;&gt;因此，ES6 既是一个历史名词，也是一个泛指，含义是 5.1 版以后的 JavaScript 的下一代标准，涵盖了 ES2015、ES2016、ES2017 等等，而 ES2015 则是正式名称，特指该年发布的正式版本的语言标准。本书中提到 ES6 的地方，一般是指 ES2015 标准，但有时也是泛指“下一代 JavaScript 语言”。&lt;/p&gt;&lt;h2&gt;2、块作用域声明&lt;/h2&gt;&lt;p cid=&quot;n52&quot; mdtype=&quot;paragraph&quot;&gt;在ES6以前，只有全局和函数局部作用域，需要创建局部作用域，最普通的方法除了普通的函数声明之外，就是立即调用函数表达式（IIFE）。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;a&amp;nbsp;=&amp;nbsp;10;
(function&amp;nbsp;IIFE(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;a&amp;nbsp;=&amp;nbsp;20;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(a);
})();
console.log(a);&lt;/pre&gt;&lt;h3&gt;2.1 let声明&lt;/h3&gt;&lt;p cid=&quot;n56&quot; mdtype=&quot;paragraph&quot;&gt;在ES6中，只需要一对{}就可以创建一个块作用域。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;a&amp;nbsp;=&amp;nbsp;2;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(a&amp;nbsp;&amp;gt;&amp;nbsp;1){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;b&amp;nbsp;=&amp;nbsp;a&amp;nbsp;*&amp;nbsp;3;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(b);&amp;nbsp;//&amp;nbsp;6
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;a;&amp;nbsp;i&amp;nbsp;&amp;lt;=&amp;nbsp;b;&amp;nbsp;i++){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;j&amp;nbsp;=&amp;nbsp;i&amp;nbsp;+&amp;nbsp;10;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(j);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;c&amp;nbsp;=&amp;nbsp;a&amp;nbsp;+&amp;nbsp;b;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(c);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
思考：哪些变量只存在于if语句内部？哪些变量只存在于for循环内部？&lt;/pre&gt;&lt;h4&gt;2.1.1 var变量提升，let变量暂时性死区&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(a);&amp;nbsp;//undefined
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(b);&amp;nbsp;//ReferenceError&amp;nbsp;临时死亡区(TDZ)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;a;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;b;
}&lt;/pre&gt;&lt;p cid=&quot;n61&quot; mdtype=&quot;paragraph&quot;&gt;不管是否显性赋值，都不能在let b语句运行之前访问b。&lt;/p&gt;&lt;p cid=&quot;n63&quot; mdtype=&quot;paragraph&quot;&gt;对于TDZ值和未声明值(以及声明过的)，typeof结果是不相同的。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//a未声明
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(typeof&amp;nbsp;a&amp;nbsp;===&amp;nbsp;&amp;#39;undefined&amp;#39;){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;变量没有声明&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//b声明了，但是还处于TDZ
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(typeof&amp;nbsp;b&amp;nbsp;===&amp;nbsp;&amp;#39;undefined&amp;#39;){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//ReferenceError
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;b;
}&lt;/pre&gt;&lt;p&gt;这里a是未声明的，所以typeof是检查它是否存在的唯一安全的方法，而typeof b 会抛出TDZ错误，因为代码后面有一个let b 声明。&lt;/p&gt;&lt;h4&gt;2.1.2 let + for&lt;/h4&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;funcs&amp;nbsp;=&amp;nbsp;[];
for&amp;nbsp;(var&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;5;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;funcs.push(function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(i);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
}
funcs[0]();&amp;nbsp;//&amp;nbsp;5
funcs[1]();&amp;nbsp;//&amp;nbsp;5

//let&amp;nbsp;方法

var&amp;nbsp;funcs&amp;nbsp;=&amp;nbsp;[];
for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;5;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;funcs.push(function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(i);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
}
funcs[0]();&amp;nbsp;//&amp;nbsp;0
funcs[1]();&amp;nbsp;//&amp;nbsp;1&lt;/pre&gt;&lt;p cid=&quot;n70&quot; mdtype=&quot;paragraph&quot;&gt;for循环头部的let i 不只为for循环本身声明了一个i，而是为循环的每一次迭代都重新声明了一个新的i。这意味着循环迭代的函数会封闭一个新的i。&lt;/p&gt;&lt;p cid=&quot;n72&quot; mdtype=&quot;paragraph&quot;&gt;等同于如下代码的功能：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;funcs&amp;nbsp;=&amp;nbsp;[];
for&amp;nbsp;(var&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;5;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;j&amp;nbsp;=&amp;nbsp;i;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;funcs.push(function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(j);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
}
funcs[0]();&amp;nbsp;//&amp;nbsp;0
funcs[1]();&amp;nbsp;//&amp;nbsp;1&lt;/pre&gt;&lt;p&gt;let放在for...in和for...of循环中也是一样的。&lt;/p&gt;&lt;h3&gt;2.2 const声明&lt;/h3&gt;&lt;p cid=&quot;n78&quot; mdtype=&quot;paragraph&quot;&gt;用于创建常量。&lt;/p&gt;&lt;p cid=&quot;n80&quot; mdtype=&quot;paragraph&quot;&gt;常量是一个设定了初始值之后就只读的变量。&lt;/p&gt;&lt;p cid=&quot;n82&quot; mdtype=&quot;paragraph&quot;&gt;这个变量的值在声明时设定之后就不允许改变。const声明必须要有显式的初始值。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;PI&amp;nbsp;=&amp;nbsp;3.14;
const&amp;nbsp;a&amp;nbsp;=&amp;nbsp;undefined;&amp;nbsp;//&amp;nbsp;如果需要一个值为undefined的常量，就要声明并初始化。
console.log(PI);//&amp;nbsp;3.14
PI&amp;nbsp;=&amp;nbsp;3.1415926;&amp;nbsp;//&amp;nbsp;TypeError&lt;/pre&gt;&lt;p cid=&quot;n85&quot; mdtype=&quot;paragraph&quot;&gt;常量不是对这个值本身的限制，而是对赋值的那个变量的限制。&lt;/p&gt;&lt;p cid=&quot;n87&quot; mdtype=&quot;paragraph&quot;&gt;这个值并没有因为const被锁定或者不可变，只是赋值本身不可变。&lt;/p&gt;&lt;p cid=&quot;n89&quot; mdtype=&quot;paragraph&quot;&gt;如果这个值是复杂值，比如数组或者对象，其内容仍然是可以修改的。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;a&amp;nbsp;=&amp;nbsp;[1,2];
a.push(3);
console.log(a);&amp;nbsp;//&amp;nbsp;[1,2,3]
a&amp;nbsp;=&amp;nbsp;10;&amp;nbsp;//&amp;nbsp;TypeError&lt;/pre&gt;&lt;p cid=&quot;n92&quot; mdtype=&quot;paragraph&quot;&gt;变量a持有一个指向数组的地址引用，数组本身是可以改变的，只是这个地址引用不可以变化。&lt;/p&gt;&lt;p cid=&quot;n94&quot; mdtype=&quot;paragraph&quot;&gt;将一个对象或数组作为常量赋值，意味着这个值在这个常量的词法作用域结束之前不会被垃圾回收，因为指向这个值的引用没有清除。所以如果不想出现这种情况，最好不要用常量指向复杂数据类型。&lt;/p&gt;&lt;h3&gt;2.3 块作用域函数&lt;/h3&gt;&lt;p cid=&quot;n97&quot; mdtype=&quot;paragraph&quot;&gt;从ES6开始，块内声明的函数，其作用域在这个块内。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foo();&amp;nbsp;//可以调用
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
foo();&amp;nbsp;//&amp;nbsp;ReferenceError&lt;/pre&gt;&lt;p&gt;要注意以下这种行为，在ES6中会报错&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;if(something){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;1&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}else{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;2&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;
}
foo();&amp;nbsp;//&amp;nbsp;在ES6以前，不管something是什么，foo()都会打印2，因为两个函数声明都会被提升到块外面，第二个总是会覆盖前面的函数声明。在ES6中，最后一行会抛出ReferenceError&lt;/pre&gt;&lt;h2&gt;3、spread/rest&lt;/h2&gt;&lt;p cid=&quot;n104&quot; mdtype=&quot;paragraph&quot;&gt;ES6引入的新运算符...，通常称为spread或rest(展开或收集)运算符，取决于它在哪里如何使用。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(x,y,z){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(x,y,z);
}
foo(...[1,2,3]);

let&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;[1,2,3];
//&amp;nbsp;老方法，用apply实现，数组可以作为参数。
//&amp;nbsp;let&amp;nbsp;oNull&amp;nbsp;=&amp;nbsp;Object.create(null);
//&amp;nbsp;console.log(Math.max.apply(oNull,arr));
//&amp;nbsp;当...用在可以被遍历的对象前，比如数组，它会把这个变量展开spread为各个独立的值。
let&amp;nbsp;max&amp;nbsp;=&amp;nbsp;Math.max(...arr);
console.log(max);&lt;/pre&gt;&lt;p&gt;还可以在其他上下文中用来展开一个值，比如：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;a&amp;nbsp;=&amp;nbsp;[1,2,3];
let&amp;nbsp;b&amp;nbsp;=&amp;nbsp;[&amp;#39;a&amp;#39;,...a,&amp;#39;b&amp;#39;];
console.log(b);&amp;nbsp;//[&amp;#39;a&amp;#39;,&amp;nbsp;1,&amp;nbsp;2,&amp;nbsp;3,&amp;nbsp;&amp;#39;b&amp;#39;]
//&amp;nbsp;老方法，用concat合并数组。
console.log([&amp;#39;a&amp;#39;].concat(a,&amp;#39;b&amp;#39;));&lt;/pre&gt;&lt;p&gt;除了spread展开之外，还可以反向操作，把一系列值收集到一起成为一个数组。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//z表示：把剩下的参数收集到一起组成一个名为z的数组
function&amp;nbsp;foo(x,y,...z){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(x,y,z);
}
foo(1,2,3,4,5);&amp;nbsp;//&amp;nbsp;1&amp;nbsp;2&amp;nbsp;[3,4,5]&lt;/pre&gt;&lt;p&gt;如果没有命名参数的话，就会收集所有的参数：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//这里的...表示收集,可以叫做rest参数，表示收集其余的参数。
function&amp;nbsp;foo(...args){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;老方法，获得除第一个后面所有的参数
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(Array.prototype.slice.call(arguments,1));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;新方法
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(args.slice(1));&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(args);&amp;nbsp;//[1,&amp;nbsp;2,&amp;nbsp;3,&amp;nbsp;4]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//这里的...表示扩展，把数组扩展成单个的值。这里很好的展示了...运算符对称而又相反的用法。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(...args);&amp;nbsp;//1&amp;nbsp;2&amp;nbsp;3&amp;nbsp;4
}
foo(1,2,3,4);&lt;/pre&gt;&lt;h2&gt;4、默认参数值&lt;/h2&gt;&lt;p cid=&quot;n117&quot; mdtype=&quot;paragraph&quot;&gt;当函数的参数可以缺省的时候，需要设置一个默认的值。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(x,&amp;nbsp;y)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//这种默认值设置，当参数可以为0的时候会出错。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x&amp;nbsp;=&amp;nbsp;x&amp;nbsp;||&amp;nbsp;10;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y&amp;nbsp;=&amp;nbsp;y&amp;nbsp;||&amp;nbsp;20;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;x&amp;nbsp;+&amp;nbsp;y;
}
console.log(foo());
//&amp;nbsp;当x为0的时候，会出错，因为&amp;nbsp;0&amp;nbsp;||&amp;nbsp;10&amp;nbsp;,会返回10
console.log(foo(0,&amp;nbsp;10));
console.log(foo(10))&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;修正参数可以为0的时候,也意味着除了undefined之外的任何值都可以传入。
//&amp;nbsp;如果传入undefined，在这里还是表示该参数缺省。
function&amp;nbsp;foo(x,&amp;nbsp;y)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x&amp;nbsp;=&amp;nbsp;(x&amp;nbsp;!==&amp;nbsp;undefined)&amp;nbsp;?&amp;nbsp;x&amp;nbsp;:&amp;nbsp;10;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y&amp;nbsp;=&amp;nbsp;(y&amp;nbsp;!==&amp;nbsp;undefined)&amp;nbsp;?&amp;nbsp;y&amp;nbsp;:&amp;nbsp;20;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;x&amp;nbsp;+&amp;nbsp;y;
}
console.log(foo());
console.log(foo(0,&amp;nbsp;10));
console.log(foo(10));
//&amp;nbsp;表示第一个参数缺省。
console.log(foo(undefined,10));&amp;nbsp;//&amp;nbsp;20&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//但是如果参数需要传递undefined&amp;nbsp;，可以通过它不存在于arguments中来确定这个参数是否被省略。
function&amp;nbsp;foo(x,y){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(arguments);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;这里&amp;nbsp;in&amp;nbsp;表示属性是否存在于对象中，0表示的是下标。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x&amp;nbsp;=&amp;nbsp;(0&amp;nbsp;in&amp;nbsp;arguments)&amp;nbsp;?&amp;nbsp;x&amp;nbsp;:&amp;nbsp;10;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y&amp;nbsp;=&amp;nbsp;(1&amp;nbsp;in&amp;nbsp;arguments)&amp;nbsp;?&amp;nbsp;y&amp;nbsp;:&amp;nbsp;20;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;x&amp;nbsp;+&amp;nbsp;y;
}
console.log(foo());&amp;nbsp;//&amp;nbsp;30
console.log(foo(10,undefined));&amp;nbsp;//&amp;nbsp;NaN&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;但是如果不能传递任何值，甚至undefined也不行，来表明“我省略了这个参数”，那么如何省略第一个参数呢？
//&amp;nbsp;foo(,10)这是不合法的语法，而在函数参数中，undefined和缺失是无法区分的
//&amp;nbsp;所以，只能缺省右侧的参数，而不能省略位于参数列表中间或者起始处的参数。
//&amp;nbsp;ES6新增了一个有用的语法来改进为缺失参数赋默认值的流程。
//&amp;nbsp;这里的x&amp;nbsp;=&amp;nbsp;10更像是x&amp;nbsp;!==&amp;nbsp;undefined&amp;nbsp;?&amp;nbsp;x&amp;nbsp;:&amp;nbsp;10
function&amp;nbsp;foo(x&amp;nbsp;=&amp;nbsp;10,y&amp;nbsp;=&amp;nbsp;20){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;x&amp;nbsp;+&amp;nbsp;y;
}
console.log(foo());&amp;nbsp;//&amp;nbsp;30
console.log(foo(5));&amp;nbsp;//&amp;nbsp;25
console.log(foo(0,10));&amp;nbsp;//&amp;nbsp;10
console.log(foo(5,undefined));&amp;nbsp;//&amp;nbsp;25&amp;nbsp;，丢掉undefined，用默认值
console.log(foo(5,null));&amp;nbsp;//&amp;nbsp;null转成了0
console.log(foo(undefined,5));&amp;nbsp;//&amp;nbsp;15&amp;nbsp;，undefined转成默认值。
console.log(foo(null,5));&amp;nbsp;//&amp;nbsp;5
console.log(foo(null,undefined));&amp;nbsp;//&amp;nbsp;20
console.log(foo(&amp;#39;&amp;#39;,undefined));&amp;nbsp;//&amp;nbsp;&amp;#39;20&amp;#39;
console.log(foo(&amp;#39;&amp;nbsp;&amp;#39;,undefined));&amp;nbsp;//&amp;nbsp;&amp;#39;&amp;nbsp;20&amp;#39;
console.log(foo(true,undefined));&amp;nbsp;//&amp;nbsp;21&amp;nbsp;true被强制转成1
console.log(foo(true,false));&amp;nbsp;//&amp;nbsp;1&amp;nbsp;true被强制转成1，false强制转成0&lt;/pre&gt;&lt;h2&gt;5、解构&lt;/h2&gt;&lt;p cid=&quot;n126&quot; mdtype=&quot;paragraph&quot;&gt;ES6引入了一个新的语法特性，名为解构（destructuring）,把这个功能看作是一个结构化赋值（structured assignment）方法。&lt;/p&gt;&lt;p cid=&quot;n128&quot; mdtype=&quot;paragraph&quot;&gt;以前的手动赋值方法：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[1,&amp;nbsp;2,&amp;nbsp;3];
}
let&amp;nbsp;temp&amp;nbsp;=&amp;nbsp;foo();
//手动赋值
let&amp;nbsp;a&amp;nbsp;=&amp;nbsp;temp[0],&amp;nbsp;b&amp;nbsp;=&amp;nbsp;temp[1],&amp;nbsp;c&amp;nbsp;=&amp;nbsp;temp[2];
console.log(a,&amp;nbsp;b,&amp;nbsp;c);

function&amp;nbsp;bar()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x:&amp;nbsp;4,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y:&amp;nbsp;5,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;z:&amp;nbsp;6
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
}
let&amp;nbsp;tmp&amp;nbsp;=&amp;nbsp;bar();
//手动赋值
let&amp;nbsp;x&amp;nbsp;=&amp;nbsp;tmp.x,&amp;nbsp;y&amp;nbsp;=&amp;nbsp;tmp.y,&amp;nbsp;z&amp;nbsp;=&amp;nbsp;tmp.z;
console.log(x,&amp;nbsp;y,&amp;nbsp;z)&lt;/pre&gt;&lt;p cid=&quot;n131&quot; mdtype=&quot;paragraph&quot;&gt;可以把将&lt;strong&gt;数组或者对象属性中带索引的值手动赋值&lt;/strong&gt;看做结构化赋值。&lt;/p&gt;&lt;p cid=&quot;n133&quot; mdtype=&quot;paragraph&quot;&gt;ES6为解构新增了一个专门语法，专用于&lt;strong&gt;数组解构&lt;/strong&gt;和&lt;strong&gt;对象解构&lt;/strong&gt;。&lt;/p&gt;&lt;p cid=&quot;n135&quot; mdtype=&quot;paragraph&quot;&gt;这个语法消除了前面代码中对临时变量tmp的需求，使代码简洁更多。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[1,&amp;nbsp;2,&amp;nbsp;3];
}
function&amp;nbsp;bar()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x:&amp;nbsp;4,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y:&amp;nbsp;5,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;z:&amp;nbsp;6
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
}
let&amp;nbsp;[a,&amp;nbsp;b,&amp;nbsp;c]&amp;nbsp;=&amp;nbsp;foo();
let&amp;nbsp;{&amp;nbsp;x:&amp;nbsp;x,&amp;nbsp;y:&amp;nbsp;y,&amp;nbsp;z:&amp;nbsp;z&amp;nbsp;}&amp;nbsp;=&amp;nbsp;bar();
console.log(a,&amp;nbsp;b,&amp;nbsp;c);
console.log(x,&amp;nbsp;y,&amp;nbsp;z);&lt;/pre&gt;&lt;h3&gt;5.1 对象属性赋值模式&lt;/h3&gt;&lt;p cid=&quot;n139&quot; mdtype=&quot;paragraph&quot;&gt;当对象的属性名和要赋值的变量名相同，语法还可以更简洁一些：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;bar()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x:&amp;nbsp;4,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y:&amp;nbsp;5,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;z:&amp;nbsp;6
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
}
let&amp;nbsp;{&amp;nbsp;x,y,z&amp;nbsp;}&amp;nbsp;=&amp;nbsp;bar();
console.log(x,&amp;nbsp;y,&amp;nbsp;z);&lt;/pre&gt;&lt;p&gt;省略了x:这个部分，如果有需要把属性赋值给非同名变量，则：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;bar()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x:&amp;nbsp;4,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y:&amp;nbsp;5,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;z:&amp;nbsp;6
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
}
let&amp;nbsp;{&amp;nbsp;x:&amp;nbsp;bam,&amp;nbsp;y:&amp;nbsp;baz,&amp;nbsp;z:&amp;nbsp;bap&amp;nbsp;}&amp;nbsp;=&amp;nbsp;bar();
console.log(bam,baz,bap);&lt;/pre&gt;&lt;p cid=&quot;n145&quot; mdtype=&quot;paragraph&quot;&gt;在对象字面量或者常规的赋值语句中，都是target:source模式，或者说是：property-alias( 属性别名 ):value模式。&lt;/p&gt;&lt;p cid=&quot;n147&quot; mdtype=&quot;paragraph&quot;&gt;但是在对象解构赋值的时候，反转了target:source模式。变成了source:target。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;aa&amp;nbsp;=&amp;nbsp;10;&amp;nbsp;bb&amp;nbsp;=&amp;nbsp;20;
//&amp;nbsp;对象字面量是target:source模式
let&amp;nbsp;o&amp;nbsp;=&amp;nbsp;{&amp;nbsp;x:&amp;nbsp;aa,&amp;nbsp;y:&amp;nbsp;bb&amp;nbsp;};
//&amp;nbsp;对象解构赋值是source:target模式
//&amp;nbsp;如果省略了x:&amp;nbsp;，相当于把aa的值赋值给了AA，bb的值赋值给了BB。
//&amp;nbsp;对称性可以帮助解释为什么ES6这个语法模式进行了反转，虽然脑子有点不习惯。
let&amp;nbsp;{&amp;nbsp;x:&amp;nbsp;AA,&amp;nbsp;y:&amp;nbsp;BB&amp;nbsp;}&amp;nbsp;=&amp;nbsp;o;
console.log(AA,&amp;nbsp;BB);&amp;nbsp;//&amp;nbsp;10&amp;nbsp;20&lt;/pre&gt;&lt;p&gt;可以不用临时变量解决“交换两个变量”这个经典问题：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;x&amp;nbsp;=&amp;nbsp;10,&amp;nbsp;y&amp;nbsp;=&amp;nbsp;20;
//&amp;nbsp;老方法
//&amp;nbsp;let&amp;nbsp;temp&amp;nbsp;=&amp;nbsp;0;
//&amp;nbsp;temp&amp;nbsp;=&amp;nbsp;x;
//&amp;nbsp;x&amp;nbsp;=&amp;nbsp;y;
//&amp;nbsp;y&amp;nbsp;=&amp;nbsp;temp;
//&amp;nbsp;console.log(x,y);&amp;nbsp;//&amp;nbsp;20&amp;nbsp;10
//&amp;nbsp;新方法
[y,x]&amp;nbsp;=&amp;nbsp;[x,y];
console.log(x,y);&amp;nbsp;//&amp;nbsp;20&amp;nbsp;10&lt;/pre&gt;&lt;h3&gt;5.2 重复赋值&lt;/h3&gt;&lt;p&gt;对象解构形式允许多次列出同一个源属性。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;{a:x,a:y}&amp;nbsp;=&amp;nbsp;{a:1};
console.log(x,y);&lt;/pre&gt;&lt;h3&gt;5.3 缺省&lt;/h3&gt;&lt;p cid=&quot;n162&quot; mdtype=&quot;paragraph&quot;&gt;对于数组解构赋值和对象解构赋值，不需要把存在的所有值都用来赋值。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[1,&amp;nbsp;2,&amp;nbsp;3];
}
function&amp;nbsp;bar()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x:&amp;nbsp;4,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y:&amp;nbsp;5,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;z:&amp;nbsp;6
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
}
//&amp;nbsp;因为数组是按照顺序解构的，所以第一个值不要的时候，还是要有占位。
let&amp;nbsp;[,b]&amp;nbsp;=&amp;nbsp;foo();
let&amp;nbsp;{x,z}&amp;nbsp;=&amp;nbsp;bar();
console.log(b,x,z);&amp;nbsp;//&amp;nbsp;2&amp;nbsp;4&amp;nbsp;6&lt;/pre&gt;&lt;p&gt;当然，如果超过了可以解构的值，多余的值会被赋为undefined.&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[1,&amp;nbsp;2,&amp;nbsp;3];
}
function&amp;nbsp;bar()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x:&amp;nbsp;4,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y:&amp;nbsp;5,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;z:&amp;nbsp;6
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
}
let&amp;nbsp;[,,c,d]&amp;nbsp;=&amp;nbsp;foo();
let&amp;nbsp;{w,z}&amp;nbsp;=&amp;nbsp;bar();
console.log(c,d,w,z);&amp;nbsp;//&amp;nbsp;3&amp;nbsp;undefined&amp;nbsp;undefined&amp;nbsp;6&lt;/pre&gt;&lt;p cid=&quot;n168&quot; mdtype=&quot;paragraph&quot;&gt;这个特性也是符合“undefined就是缺失”的原则。&lt;/p&gt;&lt;p cid=&quot;n170&quot; mdtype=&quot;paragraph&quot;&gt;...运算符也可以执行解构赋值同样的操作：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[1,&amp;nbsp;2,&amp;nbsp;3];
}
//&amp;nbsp;...b收集了其余的值，组成一个数组。
//&amp;nbsp;在ES6中还没有通过...展开和集合对象的特性。
let&amp;nbsp;[a,...b]&amp;nbsp;=&amp;nbsp;foo();
console.log(a,b);&amp;nbsp;//1&amp;nbsp;[2,&amp;nbsp;3]&lt;/pre&gt;&lt;h3&gt;5.4 默认值解构&lt;/h3&gt;&lt;p cid=&quot;n174&quot; mdtype=&quot;paragraph&quot;&gt;使用和前面函数参数默认值类似的=语法，解构也可以提供一个用来赋值的默认值。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[1,&amp;nbsp;2,&amp;nbsp;3];
}
function&amp;nbsp;bar()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x:&amp;nbsp;4,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y:&amp;nbsp;5,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;z:&amp;nbsp;6
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
}
let&amp;nbsp;[a&amp;nbsp;=&amp;nbsp;0,&amp;nbsp;b&amp;nbsp;=&amp;nbsp;0,&amp;nbsp;c&amp;nbsp;=&amp;nbsp;0,&amp;nbsp;d&amp;nbsp;=&amp;nbsp;4]&amp;nbsp;=&amp;nbsp;foo();
console.log(a,&amp;nbsp;b,&amp;nbsp;c,&amp;nbsp;d);&amp;nbsp;//&amp;nbsp;1&amp;nbsp;2&amp;nbsp;3&amp;nbsp;4

let&amp;nbsp;{&amp;nbsp;x&amp;nbsp;=&amp;nbsp;0,&amp;nbsp;y&amp;nbsp;=&amp;nbsp;0,&amp;nbsp;z&amp;nbsp;=&amp;nbsp;0,&amp;nbsp;w&amp;nbsp;=&amp;nbsp;10&amp;nbsp;}&amp;nbsp;=&amp;nbsp;bar();
console.log(x,&amp;nbsp;y,&amp;nbsp;z,&amp;nbsp;w);&amp;nbsp;//&amp;nbsp;4&amp;nbsp;5&amp;nbsp;6&amp;nbsp;10&lt;/pre&gt;&lt;p&gt;或者，属性名和变量名不同的时候：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;bar()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x:&amp;nbsp;4,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y:&amp;nbsp;5,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;z:&amp;nbsp;6
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
}
let&amp;nbsp;{&amp;nbsp;x,&amp;nbsp;y,&amp;nbsp;z,&amp;nbsp;w:&amp;nbsp;WW&amp;nbsp;=&amp;nbsp;20&amp;nbsp;}&amp;nbsp;=&amp;nbsp;bar();
console.log(x,&amp;nbsp;y,&amp;nbsp;z,&amp;nbsp;WW);&amp;nbsp;//4&amp;nbsp;5&amp;nbsp;6&amp;nbsp;20&lt;/pre&gt;&lt;h3&gt;5.5 嵌套解构&lt;/h3&gt;&lt;p cid=&quot;n181&quot; mdtype=&quot;paragraph&quot;&gt;如果解构的值中有嵌套的对象或者数组，也可以解构这些嵌套的值：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;a1&amp;nbsp;=&amp;nbsp;[1,&amp;nbsp;[2,&amp;nbsp;3,&amp;nbsp;4],&amp;nbsp;5];
let&amp;nbsp;o1&amp;nbsp;=&amp;nbsp;{&amp;nbsp;x:&amp;nbsp;{&amp;nbsp;y:&amp;nbsp;{&amp;nbsp;z:&amp;nbsp;6&amp;nbsp;}&amp;nbsp;}&amp;nbsp;};
let&amp;nbsp;[a,&amp;nbsp;[b,&amp;nbsp;c,&amp;nbsp;d],&amp;nbsp;e]&amp;nbsp;=&amp;nbsp;a1;
let&amp;nbsp;{&amp;nbsp;x:&amp;nbsp;{&amp;nbsp;y:&amp;nbsp;{&amp;nbsp;z:&amp;nbsp;w&amp;nbsp;}&amp;nbsp;}&amp;nbsp;}&amp;nbsp;=&amp;nbsp;o1;
console.log(a,b,c,d,e);&amp;nbsp;//&amp;nbsp;1&amp;nbsp;2&amp;nbsp;3&amp;nbsp;4&amp;nbsp;5
console.log(w);&amp;nbsp;//&amp;nbsp;6&lt;/pre&gt;&lt;p&gt;把嵌套解构当作一种展平对象名字空间的简单方法 .&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;App&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;model:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;User:&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{//...}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

}
//&amp;nbsp;老方法
let&amp;nbsp;User&amp;nbsp;=&amp;nbsp;App.model.User;
//&amp;nbsp;新方法
let&amp;nbsp;{&amp;nbsp;model:&amp;nbsp;{&amp;nbsp;User&amp;nbsp;}&amp;nbsp;}&amp;nbsp;=&amp;nbsp;App;&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;APP&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;methods:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;say1()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;&amp;#39;hello&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;say2()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;&amp;#39;world&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

}
console.log(APP.methods.say1());
console.log(APP.methods.say2());

//&amp;nbsp;const&amp;nbsp;say1&amp;nbsp;=&amp;nbsp;APP.methods.say1;
//&amp;nbsp;const&amp;nbsp;say2&amp;nbsp;=&amp;nbsp;APP.methods.say2;
//&amp;nbsp;console.log(say1());
//&amp;nbsp;console.log(say2());

const&amp;nbsp;{&amp;nbsp;methods:&amp;nbsp;{&amp;nbsp;say1&amp;nbsp;},&amp;nbsp;methods:&amp;nbsp;{&amp;nbsp;say2&amp;nbsp;}&amp;nbsp;}&amp;nbsp;=&amp;nbsp;APP;
console.log(say1());
console.log(say2());&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;APP&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;say1()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;&amp;#39;hello&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;say2()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;&amp;#39;world&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
const&amp;nbsp;{&amp;nbsp;say1,&amp;nbsp;say2&amp;nbsp;}&amp;nbsp;=&amp;nbsp;APP;
console.log(say1());
console.log(say2());&lt;/pre&gt;&lt;h2&gt;6、对象字面量扩展&lt;/h2&gt;&lt;p cid=&quot;n192&quot; mdtype=&quot;paragraph&quot;&gt;ES6为普通{}对象字面量新增了几个重要的便利扩展。&lt;/p&gt;&lt;h3&gt;6.1 简洁属性&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;x&amp;nbsp;=&amp;nbsp;2,y&amp;nbsp;=&amp;nbsp;3,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;o&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x:x,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y:y
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;p&gt;当需要定义一个与某个标识符同名的属性的时候，可以把x:x简写成x。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;x&amp;nbsp;=&amp;nbsp;2,y&amp;nbsp;=&amp;nbsp;3,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;o&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;6.2 简洁方法&lt;/h3&gt;&lt;p cid=&quot;n200&quot; mdtype=&quot;paragraph&quot;&gt;关联到对象字面量属性上的函数也有简洁形式。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;o&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x:function(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y:function(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;在ES6中可以简写：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;o&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;这种简洁方式都是使用了匿名函数表达式，所以针对需要递归，需要函数的词法标识符的时候就不可取了。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;getSum:&amp;nbsp;function&amp;nbsp;getSum(num)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(num&amp;nbsp;===&amp;nbsp;1)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;num&amp;nbsp;+&amp;nbsp;getSum(num&amp;nbsp;-&amp;nbsp;1);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
console.log(obj.getSum(5))&lt;/pre&gt;&lt;p&gt;比如下面的这段代码：产生两个随机数字，然后用大的减去小的。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;run(o)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;x&amp;nbsp;=&amp;nbsp;getRandom(0,&amp;nbsp;100);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;y&amp;nbsp;=&amp;nbsp;getRandom(0,&amp;nbsp;100);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(`x:${x},y:${y}`);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;console.log(o.calc.name);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//通过o.属性名来调用函数，是函数的公开名称
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;o.calc(x,&amp;nbsp;y);
}
let&amp;nbsp;result&amp;nbsp;=&amp;nbsp;run({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;calc:&amp;nbsp;function&amp;nbsp;calc(x,&amp;nbsp;y)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(x&amp;nbsp;&amp;gt;&amp;nbsp;y)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//递归，调用函数本身，calc是函数自身的词法标识符，不是对象的属性名称。用于在其自身内部递归调用函数。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;calc(y,&amp;nbsp;x);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;y&amp;nbsp;-&amp;nbsp;x;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

})
function&amp;nbsp;getRandom(min,&amp;nbsp;max)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;Math.floor(Math.random()&amp;nbsp;*&amp;nbsp;(max&amp;nbsp;-&amp;nbsp;min&amp;nbsp;+&amp;nbsp;1)&amp;nbsp;+&amp;nbsp;min);
}
console.log(result);&lt;/pre&gt;&lt;p&gt;如果把上面的代码进行ES6简洁：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;result&amp;nbsp;=&amp;nbsp;run({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;calc(x,&amp;nbsp;y)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(x&amp;nbsp;&amp;gt;&amp;nbsp;y)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//这种ES6的简洁形式，失去了函数本身的词法标识符，就不能递归调用自身了。会报ReferenceError错误。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;calc(y,&amp;nbsp;x);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;y&amp;nbsp;-&amp;nbsp;x;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
})&lt;/pre&gt;&lt;p&gt;这段ES6的代码会被解释成：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;result&amp;nbsp;=&amp;nbsp;run({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;calc:&amp;nbsp;function&amp;nbsp;(x,&amp;nbsp;y)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(x&amp;nbsp;&amp;gt;&amp;nbsp;y)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//这时候calc作为属性就不能这样使用了。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;calc(y,&amp;nbsp;x);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;y&amp;nbsp;-&amp;nbsp;x;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
})&lt;/pre&gt;&lt;p&gt;所以对于简洁方法应该只在不需要它们执行递归或者事件绑定/解绑定的时候使用。否则的话，还是按照老式的calc:function calc(...)方法来定义吧。&lt;/p&gt;&lt;h3&gt;6.3 Getter/Setter&lt;/h3&gt;&lt;p cid=&quot;n223&quot; mdtype=&quot;paragraph&quot;&gt;曾经的getter和setter的写法：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;&amp;nbsp;曾经的getter&amp;nbsp;setter

let&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;id:&amp;nbsp;10,
}
Object.defineProperty(obj,&amp;nbsp;&amp;#39;id&amp;#39;,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get:&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this._id&amp;nbsp;++;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set:&amp;nbsp;function&amp;nbsp;(val)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this._id&amp;nbsp;=&amp;nbsp;val;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
})
console.log(obj.id);&amp;nbsp;//&amp;nbsp;NaN&amp;nbsp;&amp;nbsp;&amp;nbsp;undefined++&amp;nbsp;=&amp;gt;&amp;nbsp;NaN
obj.id&amp;nbsp;=&amp;nbsp;12;
console.log(obj.id);&amp;nbsp;//&amp;nbsp;12
console.log(obj.id);&amp;nbsp;//&amp;nbsp;13
console.log(obj.id);&amp;nbsp;//&amp;nbsp;14&lt;/pre&gt;&lt;p&gt;简写形式：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;id:&amp;nbsp;10,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&amp;nbsp;id()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this._id++;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set&amp;nbsp;id(val)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this._id&amp;nbsp;=&amp;nbsp;val;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

console.log(obj.id);&amp;nbsp;//&amp;nbsp;NaN
obj.id&amp;nbsp;=&amp;nbsp;12;
console.log(obj.id);&amp;nbsp;//&amp;nbsp;12
console.log(obj.id);&amp;nbsp;//&amp;nbsp;13
console.log(obj.id);&amp;nbsp;//&amp;nbsp;14&lt;/pre&gt;&lt;h3&gt;7、插入字符串字面量（模板字面量）&lt;/h3&gt;&lt;p cid=&quot;n230&quot; mdtype=&quot;paragraph&quot;&gt;使用`作为界定符，这样的字符串字面值支持嵌入基本的字符串插入表达式，会被自动解析和求值。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;name&amp;nbsp;=&amp;nbsp;&amp;#39;诸葛亮&amp;#39;;
//&amp;nbsp;用``来包围，会被解释为一个字符串字面量，其中任何${}形式的表达式都会被立即在线解析求值。
//&amp;nbsp;这种形式的解析求值就是插入（比模板要精确一些）
let&amp;nbsp;greeting&amp;nbsp;=&amp;nbsp;`Hello,${name}`;
console.log(greeting)&lt;/pre&gt;&lt;p&gt;插入字符串字面量的一个优点就是可以分散在多行：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;name&amp;nbsp;=&amp;nbsp;&amp;#39;诸葛亮&amp;#39;;
//&amp;nbsp;用``来包围，会被解释为一个字符串字面量，其中任何${}形式的表达式都会被立即在线解析求值。
//&amp;nbsp;这种形式的解析求值就是插入（比模板要精确一些）
let&amp;nbsp;greeting&amp;nbsp;=&amp;nbsp;`Hello,${name},
你是我的偶像，羽扇纶巾，运筹帷幄之中，决胜千里之外，鞠躬尽瘁，死而后已！`;
console.log(greeting)&lt;/pre&gt;&lt;h3&gt;7.1 插入表达式&lt;/h3&gt;&lt;p cid=&quot;n237&quot; mdtype=&quot;paragraph&quot;&gt;在${...}内可以出现任何合法的表达式，包括函数调用、在线函数表达式调用、设置其它插入字符串字面量&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;getUpper(str){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;str.toUpperCase();
}

let&amp;nbsp;name&amp;nbsp;=&amp;nbsp;&amp;#39;daisy&amp;#39;;
let&amp;nbsp;str&amp;nbsp;=&amp;nbsp;`Hello,${getUpper(name)}`;
console.log(str)&lt;/pre&gt;&lt;h2&gt;8、箭头函数&lt;/h2&gt;&lt;p cid=&quot;n243&quot; mdtype=&quot;paragraph&quot;&gt;理解使用普通函数基于this带来的困扰，这是新的ES6箭头函数=&amp;gt;特性引入的主要动因。&lt;/p&gt;&lt;p cid=&quot;n245&quot; mdtype=&quot;paragraph&quot;&gt;箭头函数定义包括一个参数列表（零个或多个参数，如果参数个数不是一个的话要用(...)包围起来），然后是标识=&amp;gt;，函数体放在最后。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(x,y){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;x&amp;nbsp;+&amp;nbsp;y;
}
//箭头函数
var&amp;nbsp;foo&amp;nbsp;=&amp;nbsp;(x,y)&amp;nbsp;=&amp;gt;&amp;nbsp;x&amp;nbsp;+&amp;nbsp;y;&lt;/pre&gt;&lt;p cid=&quot;n248&quot; mdtype=&quot;paragraph&quot;&gt;只有在函数体的表达式个数多于1个，或者函数体包含非表达式语句的时候才需要用{...}包围。&lt;/p&gt;&lt;p cid=&quot;n250&quot; mdtype=&quot;paragraph&quot;&gt;如果只有一个表达式，并且省略了包围的{...}的话，则意味着表达式前面有一个隐含的return。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;fn1&amp;nbsp;=&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;12;
var&amp;nbsp;fn2&amp;nbsp;=&amp;nbsp;x&amp;nbsp;=&amp;gt;&amp;nbsp;x&amp;nbsp;*&amp;nbsp;12;
var&amp;nbsp;fn3&amp;nbsp;=&amp;nbsp;(x,y)&amp;nbsp;=&amp;gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;z&amp;nbsp;=&amp;nbsp;x&amp;nbsp;*&amp;nbsp;2&amp;nbsp;+&amp;nbsp;y;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y++;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x&amp;nbsp;*=&amp;nbsp;3;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;(x&amp;nbsp;+&amp;nbsp;y&amp;nbsp;+&amp;nbsp;z)&amp;nbsp;/&amp;nbsp;2
}&lt;/pre&gt;&lt;p cid=&quot;n253&quot; mdtype=&quot;paragraph&quot;&gt;箭头函数总是函数表达式，并不存在箭头函数声明。&lt;/p&gt;&lt;p cid=&quot;n255&quot; mdtype=&quot;paragraph&quot;&gt;箭头函数是匿名函数表达式，它们没有用于递归或者事件绑定/解绑定的命名引用。&lt;/p&gt;&lt;p cid=&quot;n257&quot; mdtype=&quot;paragraph&quot;&gt;箭头函数支持普通函数参数的所有功能，包括默认值、解构、rest参数等。&lt;/p&gt;&lt;p cid=&quot;n259&quot; mdtype=&quot;paragraph&quot;&gt;箭头函数的简洁，使得它很适合这种情况：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;a&amp;nbsp;=&amp;nbsp;[1,2];
var&amp;nbsp;result&amp;nbsp;=&amp;nbsp;a.map(v&amp;nbsp;=&amp;gt;&amp;nbsp;v&amp;nbsp;*&amp;nbsp;2);&lt;/pre&gt;&lt;p cid=&quot;n262&quot; mdtype=&quot;paragraph&quot;&gt;但是=&amp;gt;箭头函数带来的可读性提升与被转化函数的长度负相关。&lt;/p&gt;&lt;p cid=&quot;n264&quot; mdtype=&quot;paragraph&quot;&gt;函数越长，箭头函数带来的好处就越小，函数越短，箭头函数带来的好处就越大。&lt;/p&gt;&lt;p cid=&quot;n266&quot; mdtype=&quot;paragraph&quot;&gt;所以，更合理的做法是只在确实需要简短的在线函数表达式的时候才采用箭头函数，而对于那些一般长度的函数则无需改变。&lt;/p&gt;&lt;p cid=&quot;n268&quot; mdtype=&quot;paragraph&quot;&gt;不只是更短的语法，而是this。&lt;/p&gt;&lt;p cid=&quot;n270&quot; mdtype=&quot;paragraph&quot;&gt;箭头函数的主要设计目的就是以特定的方式改变this的行为特性，解决this相关的一个特殊而又常见的痛点。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name:&amp;nbsp;&amp;#39;诸葛亮&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.name);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//针对定时器的this
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setTimeout(()&amp;nbsp;=&amp;gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.name);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&amp;nbsp;1000)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

obj.fn();&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;点击按钮，每次加一个1
const&amp;nbsp;oBtn&amp;nbsp;=&amp;nbsp;document.querySelector(&amp;#39;button&amp;#39;);
var&amp;nbsp;controller&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;makeRequest:&amp;nbsp;function&amp;nbsp;(num)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oBtn.innerText&amp;nbsp;=&amp;nbsp;num;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;num++;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;保存this对象
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;_this&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oBtn.onclick&amp;nbsp;=&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;当有点击事件的调试，让程序在这里进入调试
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;debugger;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;console.log(this);&amp;nbsp;//oBtn
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;controller.makeRequest(num);&amp;nbsp;//这种方式不安全，有可能对象和标识符的引用关系发生了变化。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;通过闭包访问外层函数的变量_this
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_this.makeRequest(num);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
controller.makeRequest(10);&lt;/pre&gt;&lt;p&gt;在箭头函数内部，this绑定不是动态的，而是词法的。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;controller&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;makeRequest:&amp;nbsp;function&amp;nbsp;(num)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oBtn.innerText&amp;nbsp;=&amp;nbsp;num;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;num++;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oBtn.onclick&amp;nbsp;=&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;箭头函数内部的this指向外层环境的this。这是词法绑定，这时的this不是动态的。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.makeRequest(num);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;如果想灵活运用this，就不要胡乱使用箭头函数，比如：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;firstName:&amp;nbsp;&amp;#39;诸葛&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lastName:&amp;nbsp;&amp;#39;孔明&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fullName()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this.firstName&amp;nbsp;+&amp;nbsp;this.lastName;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sayName()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;`Hi,&amp;nbsp;my&amp;nbsp;name&amp;nbsp;is&amp;nbsp;${this.fullName()}`
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

console.log(window.obj.fullName())
console.log(window.obj.sayName())&lt;/pre&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;controller&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//箭头函数里面的this从包围的作用域中词法继承而来。外围的作用域是全局作用域。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;makeRequest:&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this);//window
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.helper();&amp;nbsp;//报错
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;helper:&amp;nbsp;()&amp;nbsp;=&amp;gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
//虽然是对象.方法的隐式this绑定方式，但是makeRequest方法是箭头函数，它里面的this不指向这个对象了。
controller.makeRequest();&lt;/pre&gt;&lt;p cid=&quot;n285&quot; mdtype=&quot;paragraph&quot;&gt;如果有一个简短单句在线函数表达式，其中唯一的语句是return某个计算出的值，且这个函数内部没有this引用，且没有自身引用（递归、事件绑定/解绑定），且不会要求函数执行这些，那么可以安全地把它重构成箭头函数。&lt;/p&gt;&lt;p cid=&quot;n287&quot; mdtype=&quot;paragraph&quot;&gt;如果有一个内层函数表达式，依赖于在包含它的函数中调用var _this = this或者.bind(this)来确保适当的this绑定，那么这个内层函数表达式应该可以安全地转换为箭头函数。&lt;/p&gt;&lt;p cid=&quot;n289&quot; mdtype=&quot;paragraph&quot;&gt;如果内层函数表达式依赖于封装函数中某种像var args = Array.prototype.slice.call(arguments)来保证arguments的词法复制，那么这个内层函数可以安全转成箭头函数。&lt;/p&gt;&lt;p cid=&quot;n291&quot; mdtype=&quot;paragraph&quot;&gt;所有的其它情况，函数声明、较长的多语句函数表达式、需要词法名称标识符（递归）的函数，以及任何不符合以上几点特征的函数，一般都应该避免箭头函数语句。&lt;/p&gt;&lt;p&gt; © Copyright Birdol.Com 2006-2014.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/342.html&quot; target=&quot;_blank&quot;&gt;继续阅读《 JavaScript(ES6)的常用特性！(上)》的全文内容...&lt;/a&gt;&lt;/p&gt;&lt;p&gt;分类: JavaScript教程 | Tags: &lt;a href=&quot;http://mrszhao.com/tags-319.html&quot;&gt;ES6&lt;/a&gt;， | &lt;a href=&quot;http://mrszhao.com/post/342.html#comment&quot; target=&quot;_blank&quot;&gt;添加评论&lt;/a&gt;(0)&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/342.html#comment&quot; target=&quot;_blank&quot;&gt;还没有评论，您来说两句？&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;相关文章:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/341.html&quot;&gt;JavaScript(ES6)的常用特性！(下)&lt;/a&gt; (2023-07-20)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/343.html&quot;&gt;用ES6写了一个todos，本地任务清单！&lt;/a&gt; (2023-07-22)  &lt;/li&gt;&lt;/ul&gt;&lt;a target=&quot;_blank&quot; title=&quot;阿里云优惠&quot; href=&quot;http://www.birdol.com/redirect/?s=6&quot;&gt;&lt;img alt=&quot;Z-Blog&quot; src=&quot;http://www.birdol.com/aliyun/qingdao950x90.jpg&quot;&gt;&lt;/a&gt;</description><pubDate>Tue, 18 Jul 2023 17:38:17 +0800</pubDate></item><item><title>对象属性的访问、遍历、getter和setter等高级特性！</title><link>http://mrszhao.com/post/340.html</link><description>&lt;p&gt;现在都是框架和组件库的天下，很多学生一上来就说要学框架，对于原生代码嗤之以鼻，觉得都是上古时期的内容，枯燥难懂，效率低下，哪有框架用起来直接起飞。&lt;/p&gt;&lt;p&gt;现在前端这个岗位在2023年仿佛冰冻了一样，这段时间整理以前的资料，有时候也觉得干嘛不直接整理自动化构建和框架的内容，还把几年前的老内容放上来。&lt;/p&gt;&lt;p&gt;也许只是个情怀吧，毕竟自己在这上面走了很久的路，算是鞭尸了……&lt;/p&gt;&lt;h2&gt;1、对象的属性和方法&lt;/h2&gt;&lt;p cid=&quot;n41&quot; mdtype=&quot;paragraph&quot;&gt;如果访问的对象属性是一个函数，大家喜欢使用不一样的叫法以作区分。由于函数很容易被认为是属于某个对象，于是把这种函数称为“方法”。&lt;/p&gt;&lt;p cid=&quot;n43&quot; mdtype=&quot;paragraph&quot;&gt;从技术角度来说，函数永远不会“属于”一个对象，所以把对象内部引用的函数称为对象的方法有点不妥。&lt;/p&gt;&lt;p cid=&quot;n45&quot; mdtype=&quot;paragraph&quot;&gt;虽然函数具有this引用，有时候这些this确实会指向调函位置的对象引用。但是这种用法从本质上并没有把一个函数变成一个对象的“方法”，因为this是在运行时根据调用位置动态绑定的，所以函数和对象的关系最多也只能说是间接关系。&lt;/p&gt;&lt;p cid=&quot;n47&quot; mdtype=&quot;paragraph&quot;&gt;无论对象访问属性返回什么值，每次访问对象的属性就是属性访问，如果属性访问返回的是一个函数，那它也并不是对象的一个“方法”。属性访问返回的函数和其它函数没有任何区别（除了可能发生的隐式绑定this）。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;foo&amp;#39;);
}
var&amp;nbsp;someFoo&amp;nbsp;=&amp;nbsp;foo;
var&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;someFoo:foo
}
foo;&amp;nbsp;//&amp;nbsp;function&amp;nbsp;foo(){...}
someFoo;&amp;nbsp;//function&amp;nbsp;foo(){...}
obj.someFoo;&amp;nbsp;//function&amp;nbsp;foo(){...}&lt;/pre&gt;&lt;p cid=&quot;n50&quot; mdtype=&quot;paragraph&quot;&gt;someFoo和obj.someFoo只是对于同一个函数的不同引用，并不能说明这个函数是特别的或者“属性”某个对象。&lt;/p&gt;&lt;p cid=&quot;n52&quot; mdtype=&quot;paragraph&quot;&gt;如果foo()定义时内部有一个this引用，那这两个函数引用的唯一区别就是obj.someFoo中的this会被隐式绑定到一个对象。&lt;/p&gt;&lt;p cid=&quot;n54&quot; mdtype=&quot;paragraph&quot;&gt;即使在对象中声明一个函数表达式，这个函数也不会“属性”这个对象，它们只是对于相同函数对象的多个引用。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;myobj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foo:function(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;foo&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
var&amp;nbsp;someFoo&amp;nbsp;=&amp;nbsp;myobj.foo;
console.log(someFoo);&amp;nbsp;//&amp;nbsp;function&amp;nbsp;foo(...)
console.log(myobj.foo);//&amp;nbsp;function&amp;nbsp;foo(...)&lt;/pre&gt;&lt;h2&gt;2、对象的复制&lt;/h2&gt;&lt;h3&gt;2.1 深复制&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;anotherFunction(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/*&amp;nbsp;...&amp;nbsp;*/
}
var&amp;nbsp;anotherObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c:true
}
var&amp;nbsp;anotherArr&amp;nbsp;=&amp;nbsp;[];
var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b:anotherObj,&amp;nbsp;//&amp;nbsp;引用，不是副本
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c:anotherArr,&amp;nbsp;//&amp;nbsp;引用
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;d:anotherFunction&amp;nbsp;//引用
}
anotherArr.push(anotherObj,myObj);&lt;/pre&gt;&lt;p cid=&quot;n60&quot; mdtype=&quot;paragraph&quot;&gt;对象之间互相引用，对于深复制来说，会由于循环引用导致死循环。&lt;/p&gt;&lt;p cid=&quot;n62&quot; mdtype=&quot;paragraph&quot;&gt;对于JSON安全的对象来说，有一种巧妙的复制方法：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;newObj&amp;nbsp;=&amp;nbsp;JSON.parse(JSON.stringfy(someObj));&lt;/pre&gt;&lt;p&gt;这种方法需要保证对象是JSON安全的，所以只适用于部分情况。&lt;/p&gt;&lt;h3&gt;2.2 浅复制&lt;/h3&gt;&lt;p cid=&quot;n68&quot; mdtype=&quot;paragraph&quot;&gt;ES6定义了Object.assign()方法来实现浅复制。&lt;/p&gt;&lt;p cid=&quot;n70&quot; mdtype=&quot;paragraph&quot;&gt;该方法的第一个参数是目标对象，后面是一个或者多个源对象。它会遍历一个或多个源对象的所有可枚举(enumerable)的自有键并把它们复制（使用=操作符赋值）到目标对象，最后返回目标对象。&lt;/p&gt;&lt;p cid=&quot;n72&quot; mdtype=&quot;paragraph&quot;&gt;就好像这样：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;anotherFunction(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//..
}
var&amp;nbsp;anotherObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c:true
}
var&amp;nbsp;anotherArr&amp;nbsp;=&amp;nbsp;[];
var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b:anotherObj,&amp;nbsp;//&amp;nbsp;引用，不是副本
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c:anotherArr,&amp;nbsp;//&amp;nbsp;引用
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;d:anotherFunction&amp;nbsp;//引用
}
anotherArr.push(anotherObj,myObj);


var&amp;nbsp;newObj&amp;nbsp;=&amp;nbsp;Object.assign({},myObj);
console.log(newObj.a);&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;2
console.log(newObj.b&amp;nbsp;===&amp;nbsp;myObj.b);&amp;nbsp;&amp;nbsp;//true
console.log(newObj.c&amp;nbsp;===&amp;nbsp;myObj.c);&amp;nbsp;&amp;nbsp;//true
console.log(newObj.d&amp;nbsp;===&amp;nbsp;myObj.d);&amp;nbsp;&amp;nbsp;//true&lt;/pre&gt;&lt;h2&gt;3、属性描述符&lt;/h2&gt;&lt;p cid=&quot;n76&quot; mdtype=&quot;paragraph&quot;&gt;在ES5之前，JavaScript语言本身并没有提供可以直接检测属性特性的方法，比如判断属性是否是只读。&lt;/p&gt;&lt;p cid=&quot;n78&quot; mdtype=&quot;paragraph&quot;&gt;在ES5之后，所有的属性都具备了属性描述符。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2
}
var&amp;nbsp;result&amp;nbsp;=&amp;nbsp;Object.getOwnPropertyDescriptor(myObj,&amp;#39;a&amp;#39;);
console.log(result);&amp;nbsp;//{value:&amp;nbsp;2,&amp;nbsp;writable:&amp;nbsp;true,&amp;nbsp;enumerable:&amp;nbsp;true,&amp;nbsp;configurable:&amp;nbsp;true}&lt;/pre&gt;&lt;p cid=&quot;n81&quot; mdtype=&quot;paragraph&quot;&gt;这个普通的对象myObj的属性描述符不仅仅只有一个value值2，还包含另外三个特性：writable(可写)、enumerable(可枚举)、configurable(可配置)。&lt;/p&gt;&lt;p cid=&quot;n83&quot; mdtype=&quot;paragraph&quot;&gt;在我们创建普通属性时属性描述符会使用默认值。就等于如下代码：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{};
Object.defineProperty(myObj,&amp;#39;a&amp;#39;,{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writable:true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configurable:true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:true
});
console.log(myObj.a);&amp;nbsp;//&amp;nbsp;2&lt;/pre&gt;&lt;p&gt;我们可以使用Object.defineProperty()来添加一个新属性，或者修改一个已有属性（如果这个属性是configurable）并对特性进行配置。&lt;/p&gt;&lt;h3&gt;3.1 writable&lt;/h3&gt;&lt;p cid=&quot;n89&quot; mdtype=&quot;paragraph&quot;&gt;writable决定是否可以修改属性的值。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{};
Object.defineProperty(myObj,&amp;#39;a&amp;#39;,{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writable:false,&amp;nbsp;//不可写
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configurable:true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:true
});
console.log(myObj.a);&amp;nbsp;//&amp;nbsp;2
myObj.a&amp;nbsp;=&amp;nbsp;3;
console.log(myObj.a);&amp;nbsp;//&amp;nbsp;2&lt;/pre&gt;&lt;h3&gt;3.2 configurable&lt;/h3&gt;&lt;p cid=&quot;n93&quot; mdtype=&quot;paragraph&quot;&gt;只要属性是可以配置的，就可以使用defineProperty()方法来修改属性描述符。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2
};
myObj.a&amp;nbsp;=&amp;nbsp;3;
console.log(myObj.a);//3
Object.defineProperty(myObj,&amp;#39;a&amp;#39;,{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:4,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writable:true,&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configurable:false,&amp;nbsp;//不可配置
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:true
});
console.log(myObj.a);&amp;nbsp;//&amp;nbsp;4
myObj.a&amp;nbsp;=&amp;nbsp;5;
console.log(myObj.a);&amp;nbsp;//&amp;nbsp;5

Object.defineProperty(myObj,&amp;#39;a&amp;#39;,{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:6,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writable:true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configurable:true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:true
})&amp;nbsp;&amp;nbsp;//Uncaught&amp;nbsp;TypeError:&amp;nbsp;Cannot&amp;nbsp;redefine&amp;nbsp;property:&amp;nbsp;a&lt;/pre&gt;&lt;p cid=&quot;n96&quot; mdtype=&quot;paragraph&quot;&gt;尝试修改一个不可配置的属性描述符会出错。&lt;/p&gt;&lt;p cid=&quot;n98&quot; mdtype=&quot;paragraph&quot;&gt;把configurable修改成false是单向操作，无法撤销！！&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2
};
myObj.a&amp;nbsp;=&amp;nbsp;3;
console.log(myObj.a);//3
Object.defineProperty(myObj,&amp;#39;a&amp;#39;,{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:4,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writable:true,&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configurable:false,&amp;nbsp;//不可配置
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:true
});
console.log(myObj.a);&amp;nbsp;//&amp;nbsp;4
myObj.a&amp;nbsp;=&amp;nbsp;5;
console.log(myObj.a);&amp;nbsp;//&amp;nbsp;5

Object.defineProperty(myObj,&amp;#39;a&amp;#39;,{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:6,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writable:false,&amp;nbsp;&amp;nbsp;//&amp;nbsp;即使不可配置，还是可以把writable的状态由true改成false，但是无法由false改成true。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configurable:false,&amp;nbsp;//不可配置
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:true
})&amp;nbsp;&amp;nbsp;
console.log(myObj.a);&amp;nbsp;//&amp;nbsp;6

myObj.a&amp;nbsp;=&amp;nbsp;7;&amp;nbsp;//不可再修改
console.log(myObj.a);&amp;nbsp;//&amp;nbsp;6&lt;/pre&gt;&lt;p&gt;configurable:false还会禁止删除这个属性：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2
}
console.log(myObj.a);&amp;nbsp;//&amp;nbsp;2
delete&amp;nbsp;myObj.a;
console.log(myObj.a);&amp;nbsp;//&amp;nbsp;undefined
Object.defineProperty(myObj,&amp;#39;a&amp;#39;,{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:3,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writable:true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configurable:false,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:true
});
console.log(myObj.a);&amp;nbsp;//&amp;nbsp;3
delete&amp;nbsp;myObj.a;&amp;nbsp;//失效了，因为属性是不可配置的。
console.log(myObj.a);&amp;nbsp;//&amp;nbsp;3&lt;/pre&gt;&lt;p&gt;delete只用来删除对象的可删除的属性。如果对象的某个属性是某个对象/函数的最后一个引用者，当delete这个属性之后，这个未引用的对象/函数就可以被垃圾回收。&lt;/p&gt;&lt;h3&gt;3.3 enumerable&lt;/h3&gt;&lt;p cid=&quot;n107&quot; mdtype=&quot;paragraph&quot;&gt;这个属性描述符控制的是属性是否会出现在对象的属性枚举中。&lt;/p&gt;&lt;p cid=&quot;n109&quot; mdtype=&quot;paragraph&quot;&gt;比如说for...in循环，如果把enumerable设置为false，这个属性就不会出现在枚举中，虽然仍然可以正常访问它。&lt;/p&gt;&lt;p cid=&quot;n111&quot; mdtype=&quot;paragraph&quot;&gt;在谷歌调试工具中，不可枚举的属性是淡紫红色，可枚举的属性是深紫红色的。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{};
Object.defineProperty(myObj,&amp;#39;a&amp;#39;,{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:true&amp;nbsp;//让a像普通属性一样可以枚举
})
Object.defineProperty(myObj,&amp;#39;b&amp;#39;,{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:3,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:false,&amp;nbsp;//&amp;nbsp;让b不可枚举
})
//可访问
console.log(myObj.b);&amp;nbsp;//&amp;nbsp;3
//b这个属性在myObj对象中是否存在
console.log(&amp;#39;b&amp;#39;&amp;nbsp;in&amp;nbsp;myObj);&amp;nbsp;//&amp;nbsp;true
//检测b这个属性是不是myObj自身的属性，而不是继承的属性
console.log(myObj.hasOwnProperty(&amp;#39;b&amp;#39;));&amp;nbsp;//&amp;nbsp;true

for(var&amp;nbsp;attr&amp;nbsp;in&amp;nbsp;myObj){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(attr,myObj[attr]);&amp;nbsp;//&amp;nbsp;a&amp;nbsp;2&amp;nbsp;,b没有被遍历出来
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;p cid=&quot;n114&quot; mdtype=&quot;paragraph&quot;&gt;myObj.b可以被访问，确实存在，但是不会出现在for...in循环中，因为只有可枚举的属性才能出现在对象属性的遍历中。&lt;/p&gt;&lt;p cid=&quot;n116&quot; mdtype=&quot;paragraph&quot;&gt;还有一些方法可以区分属性是否可枚举：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{};
Object.defineProperty(myObj,&amp;#39;a&amp;#39;,{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:true,
})
Object.defineProperty(myObj,&amp;#39;b&amp;#39;,{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:3,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:false,
})
console.log(myObj);
//&amp;nbsp;propertyIsEnumerable()检查给定的属性名是否直接存在于对象中（而不是在原型链上）并且满足enumerable:true
console.log(myObj.propertyIsEnumerable(&amp;#39;a&amp;#39;));&amp;nbsp;//&amp;nbsp;true
console.log(myObj.propertyIsEnumerable(&amp;#39;b&amp;#39;));&amp;nbsp;//&amp;nbsp;false
//返回所有可枚举的属性的数组。只查找对象直接包含的属性，不查找原型链。
console.log(Object.keys(myObj));&amp;nbsp;//[&amp;#39;a&amp;#39;]
//返回一个数组，包含所有属性，无论是否可枚举。只查找对象直接包含的属性，不查找原型链。
console.log(Object.getOwnPropertyNames(myObj));&amp;nbsp;//[&amp;#39;a&amp;#39;,&amp;nbsp;&amp;#39;b&amp;#39;]&lt;/pre&gt;&lt;h2&gt;4、遍历&lt;/h2&gt;&lt;p cid=&quot;n122&quot; mdtype=&quot;paragraph&quot;&gt;Object.keys(obj)可以返回obj对象自身可遍历的属性的数组。&lt;/p&gt;&lt;p cid=&quot;n124&quot; mdtype=&quot;paragraph&quot;&gt;Object.getOwnPropertyNames(obj) 可以返回对象自身所有属性，包括不可遍历的属性，也是返回数组。&lt;/p&gt;&lt;p cid=&quot;n126&quot; mdtype=&quot;paragraph&quot;&gt;也可以用for循环去遍历对象属性。&lt;/p&gt;&lt;p cid=&quot;n128&quot; mdtype=&quot;paragraph&quot;&gt;for...in可以遍历对象的可枚举属性（包括prototype原型链），无法直接获取属性值，需要手动获取属性值。&lt;/p&gt;&lt;h3&gt;4.1 for...in&lt;/h3&gt;&lt;p cid=&quot;n131&quot; mdtype=&quot;paragraph&quot;&gt;对于数组来说，使用标准的for循环来遍历值：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;[1,2,3];
for(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;i&amp;nbsp;&amp;lt;&amp;nbsp;arr.length;&amp;nbsp;i++){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(arr[i]);
}&lt;/pre&gt;&lt;p cid=&quot;n134&quot; mdtype=&quot;paragraph&quot;&gt;ES5中增加了一些数组的辅助迭代器，包括forEach()、every()、some()、map()、filter()、reduce()等。每种辅助迭代器都可以接受一个回调函数并把它应用到数组的每个元素上，唯一的区别就是它们对于回调函数返回值的处理方式不同。&lt;/p&gt;&lt;p cid=&quot;n136&quot; mdtype=&quot;paragraph&quot;&gt;forEach()会遍历数组中的所有值并忽略回调函数的返回值。&lt;/p&gt;&lt;p cid=&quot;n138&quot; mdtype=&quot;paragraph&quot;&gt;every()会一直运行直到回调函数返回false。&lt;/p&gt;&lt;p cid=&quot;n140&quot; mdtype=&quot;paragraph&quot;&gt;some()会一直运行直到回调函数返回true。&lt;/p&gt;&lt;p cid=&quot;n142&quot; mdtype=&quot;paragraph&quot;&gt;不要用for...in遍历数组，因为它不仅遍历数字索引，还会遍历出数组的其它属性。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;[1,2,3];
arr.name&amp;nbsp;=&amp;nbsp;&amp;#39;myArr&amp;#39;;
arr.id&amp;nbsp;=&amp;nbsp;&amp;#39;001&amp;#39;;
for(let&amp;nbsp;attr&amp;nbsp;in&amp;nbsp;arr){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(attr);//&amp;#39;0&amp;#39;&amp;nbsp;&amp;#39;1&amp;#39;&amp;nbsp;&amp;#39;2&amp;#39;&amp;nbsp;&amp;#39;name&amp;#39;&amp;nbsp;&amp;#39;id&amp;#39;
}&lt;/pre&gt;&lt;p cid=&quot;n145&quot; mdtype=&quot;paragraph&quot;&gt;用for循环或者forEach()这种迭代器，遍历数组下标时采用的是数字顺序，但是遍历对象属性时的顺序是不确定的。在不同的JavaScript引擎中可能不一样。&lt;/p&gt;&lt;p cid=&quot;n147&quot; mdtype=&quot;paragraph&quot;&gt;因此，在任何不同的环境中需要保证一致性时，一定不要相信任何观察到的属性的顺序，它们是不可靠的。&lt;/p&gt;&lt;h3&gt;4.2 for...of&lt;/h3&gt;&lt;p cid=&quot;n150&quot; mdtype=&quot;paragraph&quot;&gt;ES6增加了一种用来遍历数组的for...of循环语句，可以直接遍历值而不是数组的下标（或者对象的属性，如果对象本身定义了迭代器的话也可以遍历对象）。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;[1,2,3];
for(let&amp;nbsp;val&amp;nbsp;of&amp;nbsp;arr){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(val);
}&lt;/pre&gt;&lt;p cid=&quot;n153&quot; mdtype=&quot;paragraph&quot;&gt;for...of循环首先会向被访问的对象请求一个迭代器对象，然后通过调用迭代器对象的next()方法来遍历所有返回值。&lt;/p&gt;&lt;p cid=&quot;n155&quot; mdtype=&quot;paragraph&quot;&gt;数组有内置的@@iterator,因此for...of可以直接应用在数组上。&lt;/p&gt;&lt;p cid=&quot;n157&quot; mdtype=&quot;paragraph&quot;&gt;使用内置的@@iterator来手动遍历数组，看看它是如何工作的：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;[1,2,3];
//数组的实例有这个属性：Symbol(Symbol.iterator):f&amp;nbsp;values()
let&amp;nbsp;it&amp;nbsp;=&amp;nbsp;arr[Symbol.iterator]();
console.log(it.next());&amp;nbsp;//&amp;nbsp;{value:&amp;nbsp;1,&amp;nbsp;done:&amp;nbsp;false}
console.log(it.next());&amp;nbsp;//&amp;nbsp;{value:&amp;nbsp;2,&amp;nbsp;done:&amp;nbsp;false}
console.log(it.next());&amp;nbsp;//&amp;nbsp;{value:&amp;nbsp;3,&amp;nbsp;done:&amp;nbsp;false}
console.log(it.next());&amp;nbsp;//&amp;nbsp;{value:&amp;nbsp;undefined,&amp;nbsp;done:&amp;nbsp;true}&lt;/pre&gt;&lt;p cid=&quot;n160&quot; mdtype=&quot;paragraph&quot;&gt;使用ES6中的符号Symbol.iterator来获取对象的@@iterator内部属性，引用类似iterator这种特殊的属性时要使用Symbol符号名。&lt;/p&gt;&lt;p cid=&quot;n162&quot; mdtype=&quot;paragraph&quot;&gt;@@iterator本身并不是一个迭代器对象，而是一个返回迭代器对象的函数。函数执行之后，返回的才是迭代器对象。&lt;/p&gt;&lt;p cid=&quot;n164&quot; mdtype=&quot;paragraph&quot;&gt;然后调用迭代器对象的next()方法会返回{value:..,done:..}的值，value是当前遍历的值，done是一个布尔值，表示是否还有可以遍历的值。&lt;/p&gt;&lt;p cid=&quot;n166&quot; mdtype=&quot;paragraph&quot;&gt;和数组不同，普通的对象没有内置的@@iterator，所以无法自动完成for...of遍历，主要是为了避免影响未来的对象类型。&lt;/p&gt;&lt;p cid=&quot;n168&quot; mdtype=&quot;paragraph&quot;&gt;可以为任何想遍历的对象定义@@iterator。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:&amp;nbsp;2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b:&amp;nbsp;3
}
Object.defineProperty(myObj,&amp;nbsp;Symbol.iterator,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//这种属性不需要被枚举
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writable:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configurable:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//设置该迭代器的值是一个函数
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;o&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;idx&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//返回所有可枚举的自身属性的数组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;ks&amp;nbsp;=&amp;nbsp;Object.keys(o);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//迭代器函数执行之后返回一个对象
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//对象里面包含一个next函数，函数返回一个对象
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//这里构成了闭包
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;next:&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:&amp;nbsp;o[ks[idx++]],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;done:&amp;nbsp;(idx&amp;nbsp;&amp;gt;&amp;nbsp;ks.length)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
});

//手动遍历对象
let&amp;nbsp;it&amp;nbsp;=&amp;nbsp;myObj[Symbol.iterator]();
console.log(it.next());//{value:&amp;nbsp;2,&amp;nbsp;done:&amp;nbsp;false}
console.log(it.next());//{value:&amp;nbsp;3,&amp;nbsp;done:&amp;nbsp;false}
console.log(it.next());//{value:&amp;nbsp;undefined,&amp;nbsp;done:&amp;nbsp;true}

//用for...of遍历对象
for(let&amp;nbsp;val&amp;nbsp;of&amp;nbsp;myObj){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(val);
}&lt;/pre&gt;&lt;p&gt;定义一个“无限”迭代器，它永远不会“结束”并且总会返回一个新值（随机数、递增数、唯一标识符等等）。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;无限迭代器
let&amp;nbsp;randoms&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[Symbol.iterator]:function(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;next:function(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{value:Math.random()};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

let&amp;nbsp;pool&amp;nbsp;=&amp;nbsp;[];

for(let&amp;nbsp;val&amp;nbsp;of&amp;nbsp;randoms){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pool.push(val);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//防止无限运行
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(pool.length&amp;nbsp;===&amp;nbsp;100)&amp;nbsp;break;
}
console.log(pool)

//简写形式
let&amp;nbsp;nums&amp;nbsp;=&amp;nbsp;[];
for(;;){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;nums.push(Math.random());
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(nums.length&amp;nbsp;==&amp;nbsp;100){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
console.log(nums);&lt;/pre&gt;&lt;h2&gt;5、[[Get]]和[[Put]]&lt;/h2&gt;&lt;h3&gt;5.1 [[Get]]&lt;/h3&gt;&lt;p cid=&quot;n178&quot; mdtype=&quot;paragraph&quot;&gt;属性访问在实现时有一个微妙却非常重要的细节：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2
}
console.log(myObj.a);&lt;/pre&gt;&lt;p cid=&quot;n181&quot; mdtype=&quot;paragraph&quot;&gt;这是一次属性的访问，但是并不仅仅是在myObj中查找名字为a的属性。&lt;/p&gt;&lt;p cid=&quot;n183&quot; mdtype=&quot;paragraph&quot;&gt;myObj.a在myObj上实际上是实现了[[Get]]操作。对象默认的内置[[Get]]操作首先在对象中查找是否有相同名称的属性，如果找到就会返回这个属性的值。&lt;/p&gt;&lt;p cid=&quot;n185&quot; mdtype=&quot;paragraph&quot;&gt;如果没有找到名称相同的属性，按照[[Get]]算法的定义会执行另外一种非常重要的行为。就是遍历可能存在的[[Prototype]]原型链。&lt;/p&gt;&lt;p cid=&quot;n187&quot; mdtype=&quot;paragraph&quot;&gt;如果无论如何都没有找到名称相同的属性，那[[Get]]操作会返回值undefined。&lt;/p&gt;&lt;p cid=&quot;n189&quot; mdtype=&quot;paragraph&quot;&gt;这种方法和访问变量不一样。如果引用了一个当前词法作用域中不存在的变量，并不会像对象属性一样返回undefined，而是会抛出一个ReferenceError异常。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:undefined
}


console.log(myObj.a);&amp;nbsp;//undefined
console.log(myObj.b);&amp;nbsp;//undefined

console.log(&amp;#39;a&amp;#39;&amp;nbsp;in&amp;nbsp;myObj);&amp;nbsp;//&amp;nbsp;true
console.log(&amp;#39;b&amp;#39;&amp;nbsp;in&amp;nbsp;myObj);&amp;nbsp;//false

console.log(myObj.hasOwnProperty(&amp;#39;a&amp;#39;));&amp;nbsp;//&amp;nbsp;true
console.log(myObj.hasOwnProperty(&amp;#39;b&amp;#39;));&amp;nbsp;//false&lt;/pre&gt;&lt;p&gt;in操作符会检查属性是否在对象及其[[Prototype]]原型链上。hasOwnProperty()只会检查属性是否在myObj对象上，不会检查[[Prototype]]原型链。&lt;/p&gt;&lt;h3&gt;5.2 [[Put]]&lt;/h3&gt;&lt;p cid=&quot;n195&quot; mdtype=&quot;paragraph&quot;&gt;既然有获取属性值的[[Get]]操作，就有对应的[[Put]]操作。&lt;/p&gt;&lt;p cid=&quot;n197&quot; mdtype=&quot;paragraph&quot;&gt;给对象的属性赋值会触发[[Put]]操作，实际的行为取决于许多因素，包括对象中是否已经存在这个属性。&lt;/p&gt;&lt;p cid=&quot;n199&quot; mdtype=&quot;paragraph&quot;&gt;如果已经存在这个属性，[[Put]]算法大致会检查下面这些内容：&lt;/p&gt;&lt;p cid=&quot;n201&quot; mdtype=&quot;paragraph&quot;&gt;1、属性是否是访问描述符？如果是并且存在setter就调用setter。&lt;/p&gt;&lt;p cid=&quot;n203&quot; mdtype=&quot;paragraph&quot;&gt;2、属性的数据描述符中writable是否为false？如果是，在非严格模式下写入失败，严格模式下抛出异常。&lt;/p&gt;&lt;p cid=&quot;n205&quot; mdtype=&quot;paragraph&quot;&gt;3、如果都不是，将该值设置为属性的值。&lt;/p&gt;&lt;p cid=&quot;n207&quot; mdtype=&quot;paragraph&quot;&gt;如果对象中不存在这个属性，[[Put]]操作会更加复杂。&lt;/p&gt;&lt;h2&gt;6、Getter和Setter&lt;/h2&gt;&lt;p cid=&quot;n212&quot; mdtype=&quot;paragraph&quot;&gt;对象默认的[[Get]]和[[Put]]操作分别可以控制对象的属性值的获取和设置。&lt;/p&gt;&lt;p cid=&quot;n214&quot; mdtype=&quot;paragraph&quot;&gt;在ES5中可以适用getter和setter改写默认操作。getter是一个隐藏函数，会在获取属性值时调用。setter也是一个隐藏函数，会在设置属性值时调用。&lt;/p&gt;&lt;p cid=&quot;n216&quot; mdtype=&quot;paragraph&quot;&gt;当为一个属性定义getter、setter时，这个属性会被定义为&amp;quot;访问描述符&amp;quot;。对于访问描述符来说，JavaScript会忽略它们的value和writable特性，取而代之的是关心set和get（还有configurable和enumerable特性）。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//给属性a定义一个getter
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&amp;nbsp;a(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;2;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
Object.defineProperty(myObj,&amp;#39;b&amp;#39;,{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//给b定义一个getter
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get:function(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this.a&amp;nbsp;*&amp;nbsp;2;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//属性b可以枚举
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:true
})

console.log(myObj.a);&amp;nbsp;//&amp;nbsp;2
console.log(myObj.b);&amp;nbsp;//&amp;nbsp;4&lt;/pre&gt;&lt;p&gt;不管是对象文字语法中的get a(){}，还是defineProperty()中的显式定义，二者都会在对象中创建一个不包含值的属性。对于这个属性的访问会自动调用一个隐藏函数，它的返回值会被当作属性访问的返回值。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//默认的[[Get]]操作会被getter覆盖
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:22,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//给属性a定义一个getter
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&amp;nbsp;a(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;2;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},

&amp;nbsp;}
&amp;nbsp;Object.defineProperty(myObj,&amp;#39;b&amp;#39;,{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//给b定义一个getter
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get:function(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this.a&amp;nbsp;*&amp;nbsp;2;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//属性b可以枚举
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:true
&amp;nbsp;})

console.log(myObj.a);&amp;nbsp;//&amp;nbsp;2
//只定义了getter，对属性a进行设置时set操作会忽略赋值操作
myObj.a&amp;nbsp;=&amp;nbsp;3;
console.log(myObj.a);&amp;nbsp;//&amp;nbsp;2
console.log(myObj.b);&amp;nbsp;//&amp;nbsp;4&lt;/pre&gt;&lt;p cid=&quot;n222&quot; mdtype=&quot;paragraph&quot;&gt;为了让属性更合理，还应当定义setter，setter会覆盖单个属性默认的[[Put]]赋值操作。&lt;/p&gt;&lt;p cid=&quot;n224&quot; mdtype=&quot;paragraph&quot;&gt;通常来说getter和setter是成对出现的。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;myObj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&amp;nbsp;a()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//this._a,不能是this.a，否则会接着调用get，然后陷入死循环报错，超过堆栈大小范围。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this._a;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set&amp;nbsp;a(val)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this._a&amp;nbsp;=&amp;nbsp;val&amp;nbsp;*&amp;nbsp;2;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
};
myObj.a&amp;nbsp;=&amp;nbsp;2;
console.log(myObj.a);&lt;/pre&gt;&lt;h2&gt;7、原型链&lt;/h2&gt;&lt;h3&gt;7.1[[Prototype]]&lt;/h3&gt;&lt;p cid=&quot;n229&quot; mdtype=&quot;paragraph&quot;&gt;JavaScript中的对象有一个特殊的[[Prototype]]内置属性，其实就是对于其他对象的引用。&lt;/p&gt;&lt;p cid=&quot;n231&quot; mdtype=&quot;paragraph&quot;&gt;几乎所有的对象在创建时[[Prototype]]属性都会被赋予一个非空的值，除了Object.create(null)。&lt;/p&gt;&lt;p cid=&quot;n233&quot; mdtype=&quot;paragraph&quot;&gt;我们在访问对象的属性时:&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;myObject&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2
}
myObject.a;//2&lt;/pre&gt;&lt;p cid=&quot;n236&quot; mdtype=&quot;paragraph&quot;&gt;当试图访问对象的属性时会触发[[Get]]操作，对于默认的[[Get]]操作来说，第一步就是检查对象本身是否有这个属性， 如果有的话就使用它。&lt;/p&gt;&lt;p cid=&quot;n238&quot; mdtype=&quot;paragraph&quot;&gt;如果a不在myObject中，就需要使用[[Prototype]]原型链了。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;anotherObject&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2
};
//创建一个关联到anotherObject的对象
let&amp;nbsp;myObject&amp;nbsp;=&amp;nbsp;Object.create(anotherObject);
console.log(myObject.a);&amp;nbsp;//&amp;nbsp;2&lt;/pre&gt;&lt;p cid=&quot;n241&quot; mdtype=&quot;paragraph&quot;&gt;Object.create()会创建一个对象并把这个对象的[[Prototype]]关联到指定的对象。是ES5新增的函数。&lt;/p&gt;&lt;p cid=&quot;n243&quot; mdtype=&quot;paragraph&quot;&gt;相当于如下代码：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//polyfill
//&amp;nbsp;如果这个函数不存在
if(!Object.create){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;创建一个函数
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Object.create&amp;nbsp;=&amp;nbsp;function(o){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;创建一个构造函数
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;F(){}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;把构造函数的prototype原型对象指向传递进来的o对象
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;F.prototype&amp;nbsp;=&amp;nbsp;o;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;返回构造函数的一个实例
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;new&amp;nbsp;F();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p cid=&quot;n246&quot; mdtype=&quot;paragraph&quot;&gt;如果anotherObject也找不到a，并且[[Prototype]]原型链不为空null的话，就会继续查找下去。如果找完了整条原型链都没有，则会返回undefined.&lt;/p&gt;&lt;p cid=&quot;n248&quot; mdtype=&quot;paragraph&quot;&gt;for...in遍历对象，任何可以通过 原型链访问到的可枚举的属性都会被遍历。使用in操作符来检查属性是否在对象中存在时，同样会检查对象的整条原型链。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;supperObject&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:&amp;nbsp;2
};
//supperObject是anotherObject的原型
let&amp;nbsp;anotherObject&amp;nbsp;=&amp;nbsp;Object.create(supperObject,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:&amp;nbsp;3,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writable:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configurable:&amp;nbsp;true
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
});
//anotherObject是myObject的原型对象
let&amp;nbsp;myObject&amp;nbsp;=&amp;nbsp;Object.create(anotherObject);
myObject.c&amp;nbsp;=&amp;nbsp;4;

for&amp;nbsp;(let&amp;nbsp;attr&amp;nbsp;in&amp;nbsp;myObject)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(attr);&amp;nbsp;//&amp;nbsp;c&amp;nbsp;a&amp;nbsp;
}

console.log(&amp;#39;b&amp;#39;&amp;nbsp;in&amp;nbsp;myObject);&amp;nbsp;//&amp;nbsp;true&lt;/pre&gt;&lt;h3&gt;7.2 Object.prototype&lt;/h3&gt;&lt;p cid=&quot;n252&quot; mdtype=&quot;paragraph&quot;&gt;所有对象的[[Prototype]]链最终都会指向内置的Object.prototype。由于所有的对象都源于这个Object.prototype对象，所以它包含JavaScript中许多通用的功能。&lt;/p&gt;&lt;p cid=&quot;n254&quot; mdtype=&quot;paragraph&quot;&gt;比如valueOf()、toString()、hasOwnProperty()等都是任何对象实例可以访问的方法。&lt;/p&gt;&lt;p cid=&quot;n256&quot; mdtype=&quot;paragraph&quot;&gt;原型对象中的方法[[Prototype]]: Object 是所有实例可以访问的，constructor属性指向的构造函数下面的方法，比如constructor: ƒ&amp;nbsp;Object() 构造函数下面的方法只有Object对象本身才能访问，实例不能访问。&lt;/p&gt;&lt;h3&gt;7.3 属性设置和屏蔽&lt;/h3&gt;&lt;p cid=&quot;n259&quot; mdtype=&quot;paragraph&quot;&gt;给一个对象设置属性并不仅仅是添加一个新属性或者修改已有的属性值。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;myObject.b&amp;nbsp;=&amp;nbsp;4;&lt;/pre&gt;&lt;p cid=&quot;n262&quot; mdtype=&quot;paragraph&quot;&gt;如果myObject对象中包含名为b的普通数据访问属性，这条赋值语句只会修改已有的属性值。&lt;/p&gt;&lt;p cid=&quot;n264&quot; mdtype=&quot;paragraph&quot;&gt;如果b不是直接存在于myObject中，[[Prototype]]链就会被遍历，类似[[Get]]操作，如果原型链上找不到b，则把b直接添加到myObject上。&lt;/p&gt;&lt;p cid=&quot;n266&quot; mdtype=&quot;paragraph&quot;&gt;如果b存在于原型链上层，赋值语句的行为就会有些 不同。&lt;/p&gt;&lt;p cid=&quot;n268&quot; mdtype=&quot;paragraph&quot;&gt;如果属性名b即出现在myObject中，也出现在myObject的[[Prototype]]链上层，就会发生屏蔽。&lt;/p&gt;&lt;p cid=&quot;n270&quot; mdtype=&quot;paragraph&quot;&gt;myObject中出现的b属性会屏蔽原型链上层的所有b属性，因为myObject.b总是会选择原型链中最底层的b属性。&lt;/p&gt;&lt;p cid=&quot;n272&quot; mdtype=&quot;paragraph&quot;&gt;如果在[[Prototype]]链上层存在名为b的普通数据访问属性，并且没有被标记为只读（writable:false）,那就会直接在myObject上添加一个名为b的新属性，它是屏蔽属性。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;supperObject&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:&amp;nbsp;2
};
let&amp;nbsp;anotherObject&amp;nbsp;=&amp;nbsp;Object.create(supperObject,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:&amp;nbsp;3,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writable:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configurable:&amp;nbsp;true
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
});

let&amp;nbsp;myObject&amp;nbsp;=&amp;nbsp;Object.create(anotherObject);
myObject.b&amp;nbsp;=&amp;nbsp;4;

console.log(myObject.b);&amp;nbsp;//&amp;nbsp;4&lt;/pre&gt;&lt;p&gt;如果在[[Prototype]]链上层存在名为b的普通数据访问属性，并且被标记为只读（writable:false），那么无法修改已有属性或者在myObject上创建屏蔽属性。这条赋值语句会被忽略，不会发生屏蔽。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;supperObject&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:&amp;nbsp;2
};
let&amp;nbsp;anotherObject&amp;nbsp;=&amp;nbsp;Object.create(supperObject,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:&amp;nbsp;3,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writable:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configurable:&amp;nbsp;true
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
});

let&amp;nbsp;myObject&amp;nbsp;=&amp;nbsp;Object.create(anotherObject);
myObject.b&amp;nbsp;=&amp;nbsp;4;

console.log(myObject.b);&amp;nbsp;//&amp;nbsp;3&lt;/pre&gt;&lt;p&gt;如果在[[Prototype]]链上层存在b,并且它是一个setter，那就一定会调用这个setter，b不会被添加到myObject上。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;supperObject&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:&amp;nbsp;2
};
let&amp;nbsp;anotherObject&amp;nbsp;=&amp;nbsp;Object.create(supperObject,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:&amp;nbsp;3,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writable:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configurable:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
});
Object.defineProperty(anotherObject,&amp;nbsp;&amp;#39;b&amp;#39;,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get:&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//_b避免直接使用b导致死循环&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this._b;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set:&amp;nbsp;function&amp;nbsp;(val)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this._b&amp;nbsp;=&amp;nbsp;val&amp;nbsp;*&amp;nbsp;3;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
})

let&amp;nbsp;myObject&amp;nbsp;=&amp;nbsp;Object.create(anotherObject);
myObject.b&amp;nbsp;=&amp;nbsp;4;&amp;nbsp;
console.log(myObject.b);&amp;nbsp;//&amp;nbsp;12&lt;/pre&gt;&lt;p&gt;上面的限制只存在于myObject.b = 4这种赋值语句中，使用Object.defineProperty()则不受限制。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;supperObject&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:&amp;nbsp;2
};
let&amp;nbsp;anotherObject&amp;nbsp;=&amp;nbsp;Object.create(supperObject,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:&amp;nbsp;3,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writable:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configurable:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
});
Object.defineProperty(anotherObject,&amp;nbsp;&amp;#39;b&amp;#39;,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get:&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this._b;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set:&amp;nbsp;function&amp;nbsp;(val)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this._b&amp;nbsp;=&amp;nbsp;val&amp;nbsp;*&amp;nbsp;3;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
})

let&amp;nbsp;myObject&amp;nbsp;=&amp;nbsp;Object.create(anotherObject);
myObject.b&amp;nbsp;=&amp;nbsp;4;

console.log(myObject.b);&amp;nbsp;//&amp;nbsp;12
//这种方式则会产生屏蔽，不受writable:false和setter的影响。
Object.defineProperty(myObject,&amp;nbsp;&amp;#39;b&amp;#39;,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value:&amp;nbsp;5,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writable:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enumerable:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;configurable:&amp;nbsp;true
})
console.log(myObject.b)&amp;nbsp;//&amp;nbsp;5&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt; © Copyright Birdol.Com 2006-2014.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/340.html&quot; target=&quot;_blank&quot;&gt;继续阅读《对象属性的访问、遍历、getter和setter等高级特性！》的全文内容...&lt;/a&gt;&lt;/p&gt;&lt;p&gt;分类: JavaScript教程 | Tags: &lt;a href=&quot;http://mrszhao.com/tags-313.html&quot;&gt;对象&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-314.html&quot;&gt;writable&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-315.html&quot;&gt;enumerable&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-316.html&quot;&gt;configurable&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-317.html&quot;&gt;getter&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-318.html&quot;&gt;setter&lt;/a&gt;， | &lt;a href=&quot;http://mrszhao.com/post/340.html#comment&quot; target=&quot;_blank&quot;&gt;添加评论&lt;/a&gt;(0)&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/340.html#comment&quot; target=&quot;_blank&quot;&gt;还没有评论，您来说两句？&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;相关文章:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/338.html&quot;&gt;用原型重写数组基础方法(上)&lt;/a&gt; (2023-07-13)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/234.html&quot;&gt;JavaScript基础4:Strings 及String Methods&lt;/a&gt; (2019-07-11)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/330.html&quot;&gt;面向对象(构造函数、原型、实例、原型链的关系)&lt;/a&gt; (2021-12-03)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/254.html&quot;&gt;DOM基础1：DOM对象初了解&lt;/a&gt; (2019-08-19)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/342.html&quot;&gt; JavaScript(ES6)的常用特性！(上)&lt;/a&gt; (2023-07-18)  &lt;/li&gt;&lt;/ul&gt;&lt;a target=&quot;_blank&quot; title=&quot;阿里云优惠&quot; href=&quot;http://www.birdol.com/redirect/?s=6&quot;&gt;&lt;img alt=&quot;Z-Blog&quot; src=&quot;http://www.birdol.com/aliyun/qingdao950x90.jpg&quot;&gt;&lt;/a&gt;</description><pubDate>Sun, 16 Jul 2023 16:37:19 +0800</pubDate></item><item><title>用原型重写数组迭代方法(下)</title><link>http://mrszhao.com/post/339.html</link><description>&lt;p&gt;继续把数组后面迭代的方法用原型写出来……&lt;/p&gt;&lt;h3&gt;1、forEach&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;forEach(回调函数)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;功能:就是遍历数组的每一项,并且每一项都要执行一次回调函数的功能.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;不返回值,所以返回函数默认的undefined.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;遍历的是数组的快照，如果中途修改或者删除了数组，不会改变遍历的顺序，所以不要修改数组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.myForEach&amp;nbsp;=&amp;nbsp;function&amp;nbsp;(callback)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arg2&amp;nbsp;=&amp;nbsp;arguments[1]&amp;nbsp;||&amp;nbsp;window;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(typeof&amp;nbsp;callback&amp;nbsp;!==&amp;nbsp;&amp;#39;function&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;Error(&amp;#39;第一个参数必须是函数&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(arr.length&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;arr.length;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;callback.call(arg2,&amp;nbsp;arr[i],&amp;nbsp;i,&amp;nbsp;arr);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;2、map&lt;br/&gt;&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;map(function(item,index){})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;功能:遍历数组的每一项,每一项都要执行回调函数.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;返回值:返回一个新数组,数组的长度和原数组一样.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.myMap&amp;nbsp;=&amp;nbsp;function&amp;nbsp;(callback,&amp;nbsp;scope)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(typeof&amp;nbsp;callback&amp;nbsp;!==&amp;nbsp;&amp;#39;function&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;Error(&amp;#39;参数1必须是一个函数&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;result&amp;nbsp;=&amp;nbsp;[];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(arr.length&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return&amp;nbsp;result;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scope&amp;nbsp;=&amp;nbsp;scope&amp;nbsp;||&amp;nbsp;window;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;arr.length;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result.push(callback.call(scope,&amp;nbsp;arr[i],&amp;nbsp;i,&amp;nbsp;arr));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;result;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;3、filter&lt;br/&gt;&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;filter(function(item,index){})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;功能:对数组的每一项进行筛选,每一项都要执行回调函数,通过函数筛选成功的值,返回到新数组中.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;返回一个新数组,数组的长度可能比原数组要小.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.myFilter&amp;nbsp;=&amp;nbsp;function&amp;nbsp;(callback,&amp;nbsp;scope)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(typeof&amp;nbsp;callback&amp;nbsp;!==&amp;nbsp;&amp;#39;function&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;Error(&amp;#39;参数1必须是一个函数&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;arr.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;result&amp;nbsp;=&amp;nbsp;[];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(len&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return&amp;nbsp;result;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scope&amp;nbsp;=&amp;nbsp;scope&amp;nbsp;||&amp;nbsp;window;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;len;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(callback.call(scope,&amp;nbsp;arr[i],&amp;nbsp;i,&amp;nbsp;arr))&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result.push(arr[i]);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;result;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;4、every&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;every(function(item,index){})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;功能:每一项都要执行回调函数,通过了函数的条件,每一项都为true,才返回&amp;nbsp;true,如果有一项为假,则返回false
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;返回值:布尔值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.myEvery&amp;nbsp;=&amp;nbsp;function&amp;nbsp;(callback,&amp;nbsp;scope)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(typeof&amp;nbsp;callback&amp;nbsp;!==&amp;nbsp;&amp;#39;function&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;Error(&amp;#39;参数1必须是一个函数&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;arr.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(len&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return&amp;nbsp;true;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scope&amp;nbsp;=&amp;nbsp;scope&amp;nbsp;||&amp;nbsp;window;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;len;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果有一个不满足，返回false
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(!callback.call(scope,&amp;nbsp;arr[i],&amp;nbsp;i,&amp;nbsp;arr))&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;true;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;5、some&lt;br/&gt;&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;some(function(item,index){})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;功能:数组的某一项通过了函数的条件判断,则返回true,如果都没有通过,才返回false
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;返回值:布尔值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.mySome&amp;nbsp;=&amp;nbsp;function&amp;nbsp;(callback,&amp;nbsp;scope)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(typeof&amp;nbsp;callback&amp;nbsp;!==&amp;nbsp;&amp;#39;function&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;Error(&amp;#39;参数1必须是一个函数&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;arr.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(len&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return&amp;nbsp;false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scope&amp;nbsp;=&amp;nbsp;scope&amp;nbsp;||&amp;nbsp;window;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;len;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果有一个满足，返回true
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(callback.call(scope,&amp;nbsp;arr[i],&amp;nbsp;i,&amp;nbsp;arr))&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;true;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;6、reduce&lt;br/&gt;&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;reduce(function(sum,i){},0)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;功能:累计
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.myReduce&amp;nbsp;=&amp;nbsp;function&amp;nbsp;(callback,&amp;nbsp;init)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(typeof&amp;nbsp;callback&amp;nbsp;!==&amp;nbsp;&amp;#39;function&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;Error(&amp;#39;参数1必须是一个函数&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;arr.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果长度为0，又没有设置初始值，报错
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(len&amp;nbsp;==&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;init&amp;nbsp;===&amp;nbsp;undefined)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;Error(&amp;#39;数组为空时必须设置初始值&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果长度为0，返回初始值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(len&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return&amp;nbsp;init;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;总的值默认为初始值，没有初始值，默认为0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;total&amp;nbsp;=&amp;nbsp;init&amp;nbsp;||&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;没有设置初始值的时候，total默认为第一个数组的值，选项从第二个开始遍历。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(init&amp;nbsp;===&amp;nbsp;undefined)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;total&amp;nbsp;=&amp;nbsp;arr[0];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;1;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;len;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;total&amp;nbsp;=&amp;nbsp;callback(total,&amp;nbsp;arr[i],&amp;nbsp;i,&amp;nbsp;arr)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;设置了初始值，则从第一个项开始遍历
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;len;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;total&amp;nbsp;=&amp;nbsp;callback(total,&amp;nbsp;arr[i],&amp;nbsp;i,&amp;nbsp;arr)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;total;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;p&gt;还有includes、find、findIndex等等新增的方法就不写了，差别不大，好吧，其实是我想偷懒了，累觉不爱……&lt;/p&gt;&lt;p&gt; © Copyright Birdol.Com 2006-2014.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/339.html&quot; target=&quot;_blank&quot;&gt;继续阅读《用原型重写数组迭代方法(下)》的全文内容...&lt;/a&gt;&lt;/p&gt;&lt;p&gt;分类: JavaScript教程 | Tags: &lt;a href=&quot;http://mrszhao.com/tags-208.html&quot;&gt;数组&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-291.html&quot;&gt;原型&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-311.html&quot;&gt;迭代&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-312.html&quot;&gt;方法&lt;/a&gt;， | &lt;a href=&quot;http://mrszhao.com/post/339.html#comment&quot; target=&quot;_blank&quot;&gt;添加评论&lt;/a&gt;(0)&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/339.html#comment&quot; target=&quot;_blank&quot;&gt;还没有评论，您来说两句？&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;相关文章:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/338.html&quot;&gt;用原型重写数组基础方法(上)&lt;/a&gt; (2023-07-13)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/330.html&quot;&gt;面向对象(构造函数、原型、实例、原型链的关系)&lt;/a&gt; (2021-12-03)  &lt;/li&gt;&lt;/ul&gt;&lt;a target=&quot;_blank&quot; title=&quot;阿里云优惠&quot; href=&quot;http://www.birdol.com/redirect/?s=6&quot;&gt;&lt;img alt=&quot;Z-Blog&quot; src=&quot;http://www.birdol.com/aliyun/qingdao950x90.jpg&quot;&gt;&lt;/a&gt;</description><pubDate>Sat, 15 Jul 2023 16:12:59 +0800</pubDate></item><item><title>用原型重写数组基础方法(上)</title><link>http://mrszhao.com/post/338.html</link><description>&lt;p&gt;通过用原型的方式重写数组的方法，加深对数组和原型的掌握。&lt;/p&gt;&lt;p&gt;先从最简单的开始：&lt;br/&gt;&lt;/p&gt;&lt;h3&gt;1、push&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;nbsp;push(val1,val2,...)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;1、数组的方法，只能数组对象调用
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;2、功能是在数组的尾部添加数据
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;3、可以添加多个数据，逗号隔开
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;4、返回的是数组的length值，是数字类型
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;5、改变了原始数组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.myPush&amp;nbsp;=&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;保存长度，减少对数组长度的反复查找，节约性能
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;arr.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;arguments.length;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr[len++]&amp;nbsp;=&amp;nbsp;arguments[i];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;len;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;2、pop&lt;br/&gt;&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;pop()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;1、功能是：删除数组尾部的一个值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;2、返回被删除的数据
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;3、改变的是原数组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.myPop&amp;nbsp;=&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;arr.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;必须要判断数组的长度，如果为0，直接返回undefined
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(len&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;lastItem&amp;nbsp;=&amp;nbsp;arr[len&amp;nbsp;-&amp;nbsp;1];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;数组的长度少一个1，就会直接删除最后一个值。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr.length--;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;lastItem;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;3、unshift&lt;br/&gt;&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;unshift(val,val,...)&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;shift()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;在数组的头部添加数据和删除数据,是先后先出的模式。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.myUnshift&amp;nbsp;=&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;arr.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;argL&amp;nbsp;=&amp;nbsp;arguments.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;加入参数长度为0，返回数组的长度，不用操作后面
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(argL&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return&amp;nbsp;len;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;先把原始数组的值往右移动参数的个数
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;len;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr[argL&amp;nbsp;+&amp;nbsp;i]&amp;nbsp;=&amp;nbsp;arr[i];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;再把参数的值一一对应到数组中
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;argL;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr[i]&amp;nbsp;=&amp;nbsp;arguments[i];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;len++;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;len;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;4、shift&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;shift
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.myShift&amp;nbsp;=&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;arr.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//如果数组长度为0，则不执行，返回undefined。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(len&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;nbsp;取出第一个值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;firstItem&amp;nbsp;=&amp;nbsp;arr[0];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;nbsp;遍历后面所有值，往前移动一个位置。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;1;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;len;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr[i&amp;nbsp;-&amp;nbsp;1]&amp;nbsp;=&amp;nbsp;arr[i];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;nbsp;数组长度减1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr.length--;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;nbsp;返回第一个值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;firstItem;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;5、join&lt;br/&gt;&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;join(分隔符)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;功能是：把数组的值转成字符串，用分隔符拼接。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;参数是可以缺省，默认是逗号隔开。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果是空字符串，直接把数组拼接成字符串
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;返回的是字符串
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.myJoin&amp;nbsp;=&amp;nbsp;function&amp;nbsp;(sep)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(sep&amp;nbsp;||&amp;nbsp;sep&amp;nbsp;===&amp;nbsp;&amp;#39;&amp;#39;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sep&amp;nbsp;=&amp;nbsp;sep;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sep&amp;nbsp;=&amp;nbsp;&amp;#39;,&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;arr.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;str&amp;nbsp;=&amp;nbsp;&amp;#39;&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(len&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return&amp;nbsp;str;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;len;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(i&amp;nbsp;&amp;lt;&amp;nbsp;len&amp;nbsp;-&amp;nbsp;1)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;str&amp;nbsp;+=&amp;nbsp;arr[i]&amp;nbsp;+&amp;nbsp;sep;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;str&amp;nbsp;+=&amp;nbsp;arr[i];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;str;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;6、concat&lt;br/&gt;&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;concat(val,val,...)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;功能是：把多个值合并在新数组中返回
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;参数：任意数据类型的值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;返回值：一个新数组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;不改变原数组，返回新数组,但是是浅拷贝
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;能够拆开第一层数组。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.myConcat&amp;nbsp;=&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;arr.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;argsL&amp;nbsp;=&amp;nbsp;arguments.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;newArr&amp;nbsp;=&amp;nbsp;[];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;先把原数组遍历出来，把值赋值给新数组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;len;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newArr[i]&amp;nbsp;=&amp;nbsp;arr[i];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果参数长度为0，返回新数组。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(argsL&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return&amp;nbsp;newArr;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;遍历参数
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;argsL;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果参数中有数组，则解开第一层数组的值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(arguments[i]&amp;nbsp;instanceof&amp;nbsp;Array)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;j&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;j&amp;nbsp;&amp;lt;&amp;nbsp;arguments[i].length;&amp;nbsp;j++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newArr[len++]&amp;nbsp;=&amp;nbsp;arguments[i][j];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newArr[len++]&amp;nbsp;=&amp;nbsp;arguments[i];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;newArr;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;7、slice&lt;br/&gt;&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;slice(start,end)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;功能：截取数组的一段值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;参数：start表示开始的索引值，end表示结束的索引值，不包括结束的索引值。[start,end)，可以为负值。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;返回值：返回一个截取出来的新数组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;参数缺省，表示把所有的值都截取出来，返回到一个新数组，可以用来对数组进行浅拷贝。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;没有修改原数组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;slice
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.mySlice&amp;nbsp;=&amp;nbsp;function&amp;nbsp;(start,&amp;nbsp;end)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;arr.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;argsL&amp;nbsp;=&amp;nbsp;arguments.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;newArr&amp;nbsp;=&amp;nbsp;[];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果数值长度为0，返回新的空数组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(len&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return&amp;nbsp;newArr;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果第一个参数缺省，默认值为0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;start&amp;nbsp;=&amp;nbsp;arguments[0]&amp;nbsp;||&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果第二个参数缺省，默认值为数组的长度
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&amp;nbsp;=&amp;nbsp;arguments[1]&amp;nbsp;||&amp;nbsp;len;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果第一个参数小于0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(arguments[0]&amp;nbsp;&amp;lt;&amp;nbsp;0)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;start&amp;nbsp;=&amp;nbsp;len&amp;nbsp;+&amp;nbsp;arguments[0];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果第二个参数小于0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(arguments[1]&amp;nbsp;&amp;lt;&amp;nbsp;0)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&amp;nbsp;=&amp;nbsp;len&amp;nbsp;+&amp;nbsp;arguments[1];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果第一个参数大于等于第二个参数，返回新的空数组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(start&amp;nbsp;&amp;gt;=&amp;nbsp;end)&amp;nbsp;return&amp;nbsp;newArr;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;遍历start到end之间的值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;start;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;end;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newArr.push(arr[i]);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;newArr;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;8、splice&lt;br/&gt;&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;splice(index,howmany,val,val,....)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;功能:对数组任意位置进行增加,删除,修改值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;修改原数组，返回被删除的值构成的新数组，如果没有删除值，返回空数组。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;可以添加或者替换数组的一部分
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.mySplice&amp;nbsp;=&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;arr.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;argsL&amp;nbsp;=&amp;nbsp;arguments.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;newArr&amp;nbsp;=&amp;nbsp;[];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果没有参数，返回空数组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(argsL&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return&amp;nbsp;newArr;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;第一个参数作为起始位置
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;start&amp;nbsp;=&amp;nbsp;arguments[0];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果第一个参数小于0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(start&amp;nbsp;&amp;lt;&amp;nbsp;0)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;start&amp;nbsp;=&amp;nbsp;start&amp;nbsp;+&amp;nbsp;len;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果第一个参数不是数字，或者是NaN，默认0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(typeof&amp;nbsp;start&amp;nbsp;!==&amp;nbsp;&amp;#39;number&amp;#39;&amp;nbsp;||&amp;nbsp;start&amp;nbsp;!==&amp;nbsp;start&amp;nbsp;||&amp;nbsp;start&amp;nbsp;&amp;lt;&amp;nbsp;0)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;start&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果第一个参数大于数组的最大下标值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(start&amp;nbsp;&amp;gt;&amp;nbsp;len&amp;nbsp;-&amp;nbsp;1)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;start&amp;nbsp;=&amp;nbsp;len;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;第二个参数作为删除的个数。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;let&amp;nbsp;howmany&amp;nbsp;=&amp;nbsp;(arguments[1]&amp;nbsp;!==&amp;nbsp;undefined)&amp;nbsp;?&amp;nbsp;arguments[1]&amp;nbsp;:&amp;nbsp;len&amp;nbsp;-&amp;nbsp;start;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;howmany&amp;nbsp;=&amp;nbsp;arguments[1];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果没有传参第二个参数，默认为删除起始位置后面的所有值。如果为0，不删除。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;这里不要用短路||运算符，否则参数为0的时候，也会返回后面len&amp;nbsp;-&amp;nbsp;start的值。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(arguments[1]&amp;nbsp;===&amp;nbsp;undefined)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;howmany&amp;nbsp;=&amp;nbsp;len&amp;nbsp;-&amp;nbsp;start;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果第二个参数不是数字或者是NaN，默认为0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(typeof&amp;nbsp;howmany&amp;nbsp;!==&amp;nbsp;&amp;#39;number&amp;#39;&amp;nbsp;||&amp;nbsp;howmany&amp;nbsp;!==&amp;nbsp;howmany)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;howmany&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果被删除的个数大于了可以删除的个数，则只能截取到末尾。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(howmany&amp;nbsp;&amp;gt;&amp;nbsp;len&amp;nbsp;-&amp;nbsp;start)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;howmany&amp;nbsp;=&amp;nbsp;len&amp;nbsp;-&amp;nbsp;start;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;把要删除的值添加到新数组中
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;start;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;start&amp;nbsp;+&amp;nbsp;howmany;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newArr.push(arr[i]);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;获取第三个以后的参数
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;addArgs&amp;nbsp;=&amp;nbsp;Array.prototype.slice.call(arguments,&amp;nbsp;2);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;要添加的参数的长度
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;addArgsL&amp;nbsp;=&amp;nbsp;addArgs.length;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果有参数，则根据howmany来看，是添加还是替换。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果是插入或替换，只需用替换元素长度减去删除的个数即可得出向后移动的位置数，把插入替换的元素在移动出空缺的位置上对号入座；

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(addArgsL&amp;nbsp;&amp;gt;&amp;nbsp;0)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;添加的个数和删除的个数的差值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;num&amp;nbsp;=&amp;nbsp;addArgsL&amp;nbsp;-&amp;nbsp;howmany;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果添加的个数大于删除的个数，则是从后面扩展数组。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(num&amp;nbsp;&amp;gt;&amp;nbsp;0)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;必须是从后面往前面遍历，否则前面的数会把后面的数覆盖
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;len&amp;nbsp;-&amp;nbsp;1;&amp;nbsp;i&amp;nbsp;&amp;gt;=&amp;nbsp;start;&amp;nbsp;i--)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr[i&amp;nbsp;+&amp;nbsp;num]&amp;nbsp;=&amp;nbsp;arr[i];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果添加的个数少于要删除的个数，则从起始位置加上删除个数的位置开始往前移动
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;start&amp;nbsp;+&amp;nbsp;howmany;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;len;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr[i&amp;nbsp;+&amp;nbsp;num]&amp;nbsp;=&amp;nbsp;arr[i];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;改变数组的长度，如果添加的参数少于删除的个数，数组要把后面多余的数删除。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;数组原始的长度加上添加和删除的差值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr.length&amp;nbsp;=&amp;nbsp;len&amp;nbsp;+&amp;nbsp;num;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(addArgsL,&amp;nbsp;howmany,&amp;nbsp;arr.length,&amp;nbsp;start);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;再把要添加的数对应到相应的位置上。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;j&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;j&amp;nbsp;&amp;lt;&amp;nbsp;addArgsL;&amp;nbsp;j++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr[start++]&amp;nbsp;=&amp;nbsp;addArgs[j]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;没有要添加的参数，值直接删除。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;start;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;len;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr[i]&amp;nbsp;=&amp;nbsp;arr[i&amp;nbsp;+&amp;nbsp;howmany];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr.length&amp;nbsp;=&amp;nbsp;arr.length&amp;nbsp;-&amp;nbsp;howmany;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;newArr;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;9、reverse&lt;br/&gt;&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;reverse()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;功能:翻转数组的值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;没有参数
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;返回原数组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.myReverse&amp;nbsp;=&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;arr.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(len&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return&amp;nbsp;arr;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;centerpos&amp;nbsp;=&amp;nbsp;Math.floor(len&amp;nbsp;/&amp;nbsp;2);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;temp&amp;nbsp;=&amp;nbsp;&amp;#39;&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;centerpos;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;temp&amp;nbsp;=&amp;nbsp;arr[i];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr[i]&amp;nbsp;=&amp;nbsp;arr[len&amp;nbsp;-&amp;nbsp;1&amp;nbsp;-&amp;nbsp;i];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr[len&amp;nbsp;-&amp;nbsp;1&amp;nbsp;-&amp;nbsp;i]&amp;nbsp;=&amp;nbsp;temp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;arr;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;10、sort&lt;br/&gt;&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;sort
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;v8的sort源代码使用的是数组小于10，插入排序，大于10，快速排序，大于1000，插入和快排混合。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;https://zhuanlan.zhihu.com/p/33626637
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;https://zhuanlan.zhihu.com/p/24050357
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;这里使用的是冒泡排序
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.mySort&amp;nbsp;=&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果没有传参数
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;默认字符串排序
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(!arguments[0])&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;arr.length&amp;nbsp;-&amp;nbsp;1;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;j&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;j&amp;nbsp;&amp;lt;&amp;nbsp;arr.length&amp;nbsp;-&amp;nbsp;1&amp;nbsp;-&amp;nbsp;i;&amp;nbsp;j++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果是默认排序，则转成字符串，升序排列
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(String(arr[j])&amp;nbsp;&amp;gt;&amp;nbsp;String(arr[j&amp;nbsp;+&amp;nbsp;1]))&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;temp&amp;nbsp;=&amp;nbsp;arr[j&amp;nbsp;+&amp;nbsp;1];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr[j&amp;nbsp;+&amp;nbsp;1]&amp;nbsp;=&amp;nbsp;arr[j];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr[j]&amp;nbsp;=&amp;nbsp;temp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;arr;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;fn&amp;nbsp;=&amp;nbsp;arguments[0];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;arr.length&amp;nbsp;-&amp;nbsp;1;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;j&amp;nbsp;=&amp;nbsp;0;&amp;nbsp;j&amp;nbsp;&amp;lt;&amp;nbsp;arr.length&amp;nbsp;-&amp;nbsp;1&amp;nbsp;-&amp;nbsp;i;&amp;nbsp;j++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;调用比较函数，计算相邻两个数的差值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;result&amp;nbsp;=&amp;nbsp;fn(arr[j],&amp;nbsp;arr[j&amp;nbsp;+&amp;nbsp;1]);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果差值大于0，则交换两个数的位置
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(result&amp;nbsp;&amp;gt;&amp;nbsp;0)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;temp&amp;nbsp;=&amp;nbsp;arr[j&amp;nbsp;+&amp;nbsp;1];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr[j&amp;nbsp;+&amp;nbsp;1]&amp;nbsp;=&amp;nbsp;arr[j];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arr[j]&amp;nbsp;=&amp;nbsp;temp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;arr;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;11、indexOf&lt;br/&gt;&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;indexOf(item,start)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;功能:查找数组里面是否有item这个项.可以指定从哪个索引位置开始查找,start缺省,表示0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;返回值:如果找到了,返回这个item项的索引值,没找到,返回-1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;这个方法不能判断数组里面是否有NaN,因为NaN&amp;nbsp;===&amp;nbsp;NaN,返回false
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.myIndexOf&amp;nbsp;=&amp;nbsp;function&amp;nbsp;(ele,&amp;nbsp;start)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(arr.length&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return&amp;nbsp;-1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;start&amp;nbsp;=&amp;nbsp;start&amp;nbsp;||&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;result&amp;nbsp;=&amp;nbsp;-1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;start;&amp;nbsp;i&amp;nbsp;&amp;lt;&amp;nbsp;arr.length;&amp;nbsp;i++)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果元素相等，返回第一个相等的元素的下标值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(ele&amp;nbsp;===&amp;nbsp;arr[i])&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result&amp;nbsp;=&amp;nbsp;i;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;result;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;h3&gt;12、lastIndexOf&lt;br/&gt;&lt;/h3&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;lastIndexOf(item,start)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;功能和indexOf()类似,只不过是从数组的右边往左边查找
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;数组的元素的索引值是不变的,只是从右边往左边查找,返回的依然是值固定的索引值.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Array.prototype.myLastIndexOf&amp;nbsp;=&amp;nbsp;function&amp;nbsp;(ele,&amp;nbsp;start)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;arr.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(len&amp;nbsp;==&amp;nbsp;0)&amp;nbsp;return&amp;nbsp;-1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;start&amp;nbsp;=&amp;nbsp;start&amp;nbsp;||&amp;nbsp;len&amp;nbsp;-&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;result&amp;nbsp;=&amp;nbsp;-1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(let&amp;nbsp;i&amp;nbsp;=&amp;nbsp;start;&amp;nbsp;i&amp;nbsp;&amp;gt;=&amp;nbsp;0;&amp;nbsp;i--)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如果元素相等，返回第一个相等的元素的下标值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(ele&amp;nbsp;===&amp;nbsp;arr[i])&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result&amp;nbsp;=&amp;nbsp;i;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;result;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;p&gt;写了好久终于把常规的数组方法写完了，还有后面迭代的方法没有……&lt;/p&gt;&lt;p&gt; © Copyright Birdol.Com 2006-2014.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/338.html&quot; target=&quot;_blank&quot;&gt;继续阅读《用原型重写数组基础方法(上)》的全文内容...&lt;/a&gt;&lt;/p&gt;&lt;p&gt;分类: JavaScript教程 | Tags: &lt;a href=&quot;http://mrszhao.com/tags-208.html&quot;&gt;数组&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-291.html&quot;&gt;原型&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-207.html&quot;&gt;数组方法&lt;/a&gt;， | &lt;a href=&quot;http://mrszhao.com/post/338.html#comment&quot; target=&quot;_blank&quot;&gt;添加评论&lt;/a&gt;(0)&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/338.html#comment&quot; target=&quot;_blank&quot;&gt;还没有评论，您来说两句？&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;相关文章:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/236.html&quot;&gt;JavaScript基础6:数组Arrays和常用属性与方法&lt;/a&gt; (2019-07-23)  &lt;/li&gt;&lt;/ul&gt;&lt;a target=&quot;_blank&quot; title=&quot;阿里云优惠&quot; href=&quot;http://www.birdol.com/redirect/?s=6&quot;&gt;&lt;img alt=&quot;Z-Blog&quot; src=&quot;http://www.birdol.com/aliyun/qingdao950x90.jpg&quot;&gt;&lt;/a&gt;</description><pubDate>Thu, 13 Jul 2023 15:46:32 +0800</pubDate></item><item><title>H5 Audio API+jQuery+ajax实现一个迷你播放器！</title><link>http://mrszhao.com/post/334.html</link><description>&lt;p&gt;今天翻资料，发现一个还算完整的播放器案例，主要是练习H5提供的Audio API，结合jQuery+Ajax完成。&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/zb_users/upload/2023/09/player/player.html&quot; target=&quot;_blank&quot; title=&quot;播放器audio API练习&quot;&gt;&lt;img src=&quot;http://mrszhao.com/zb_users/upload/2023/09/202309041693833117456761.jpg&quot; title=&quot;1.jpg&quot; alt=&quot;1.jpg&quot;/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;点击图片看效果。&lt;/p&gt;&lt;p&gt;功能：&lt;/p&gt;&lt;p&gt;1、默认不播放，点击播放按钮，播放音乐。&lt;/p&gt;&lt;p&gt;2、点击暂停按钮，暂停播放。&lt;/p&gt;&lt;p&gt;3、点击上一首，下一首播放音乐。&lt;/p&gt;&lt;p&gt;4、点击停止，进度条归零，停止播放音乐。&lt;/p&gt;&lt;p&gt;5、可以拖拉播放进度条。&lt;/p&gt;&lt;p&gt;6、点击列表可以切换音乐并播放。&lt;/p&gt;&lt;p&gt;7、播放完后自动播放下一首。&lt;/p&gt;&lt;p&gt;核心代码：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;ajax获取本地json数据
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$.get(&amp;#39;data/music.json&amp;#39;,&amp;nbsp;function&amp;nbsp;(data)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;musicList&amp;nbsp;=&amp;nbsp;data.music;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;1、初始化界面
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;num&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;初始化音乐和图片
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;.playerImg&amp;#39;).html(`
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;img&amp;nbsp;src=&amp;quot;${musicList[num].coverSrc}&amp;quot;&amp;nbsp;alt=&amp;quot;&amp;quot;&amp;nbsp;width=&amp;quot;150&amp;quot;&amp;nbsp;height=&amp;quot;150&amp;quot;&amp;nbsp;id=&amp;quot;cover&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;audio&amp;nbsp;id=&amp;quot;audio&amp;quot;&amp;nbsp;src=&amp;quot;${musicList[num].videoSrc}&amp;quot;&amp;gt;&amp;lt;/audio&amp;gt;`);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;初始化音乐列表
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;str&amp;nbsp;=&amp;nbsp;&amp;#39;&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;musicList.forEach(function&amp;nbsp;(item,&amp;nbsp;index)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;str&amp;nbsp;+=&amp;nbsp;`&amp;nbsp;&amp;lt;li&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;span&amp;nbsp;class=&amp;quot;mr10&amp;quot;&amp;gt;${index&amp;nbsp;+&amp;nbsp;1}&amp;lt;/span&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;span&amp;gt;${item.title}&amp;lt;/span&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;span&amp;gt;-&amp;lt;/span&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;span&amp;gt;${item.author}&amp;lt;/span&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/li&amp;gt;`
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#musicList&amp;#39;).html(str);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;初始化高亮&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;len&amp;nbsp;=&amp;nbsp;musicList.length;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#musicList&amp;nbsp;&amp;gt;&amp;nbsp;li&amp;#39;).removeClass(&amp;#39;active&amp;#39;).eq(num).addClass(&amp;#39;active&amp;#39;);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;2、点击播放按钮，让音乐播放，点击切换成暂停，点击暂停
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;获取对象或者值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;totalWidth&amp;nbsp;=&amp;nbsp;$(&amp;#39;#progrees&amp;#39;).width();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;oAudio&amp;nbsp;=&amp;nbsp;document.querySelector(&amp;#39;#audio&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;默认没有播放
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;isOn&amp;nbsp;=&amp;nbsp;false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;播放和暂停功能
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#play&amp;#39;).on(&amp;#39;click&amp;#39;,&amp;nbsp;playAndPause);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;停止播放
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;.stop&amp;#39;).on(&amp;#39;click&amp;#39;,&amp;nbsp;stop);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;timeupdate&amp;nbsp;事件在音频/视频（audio/video）的播放位置发生改变时触发。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oAudio.addEventListener(&amp;#39;timeupdate&amp;#39;,&amp;nbsp;setProgress);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;3、点击下一首播放
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;.next&amp;#39;).on(&amp;#39;click&amp;#39;,&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;autoPlay();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;3、点击上一首播放
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;.prev&amp;#39;).on(&amp;#39;click&amp;#39;,&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;isOn&amp;nbsp;=&amp;nbsp;false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;num--;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(num&amp;nbsp;&amp;lt;=&amp;nbsp;-1)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;num&amp;nbsp;=&amp;nbsp;len&amp;nbsp;-&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;init(num);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;playAndPause();

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;4、点击切换歌曲
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#musicList&amp;nbsp;&amp;gt;&amp;nbsp;li&amp;#39;).on(&amp;#39;click&amp;#39;,&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;num&amp;nbsp;=&amp;nbsp;$(this).index();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;isOn&amp;nbsp;=&amp;nbsp;false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;init(num);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;playAndPause();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;5、点击进度条改变播放的位置
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#progrees&amp;#39;).on(&amp;#39;click&amp;#39;,&amp;nbsp;function&amp;nbsp;(e)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;获取被点击的偏移值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;offsetX&amp;nbsp;=&amp;nbsp;e.offsetX;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;获取被点击的位置和整个进度条长度的比例
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;radio&amp;nbsp;=&amp;nbsp;offsetX&amp;nbsp;/&amp;nbsp;totalWidth;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;totalTime&amp;nbsp;=&amp;nbsp;oAudio.duration;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;通过比例乘以总的时间，得到当前时间，赋值给audio对象。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oAudio.currentTime&amp;nbsp;=&amp;nbsp;totalTime&amp;nbsp;*&amp;nbsp;radio;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;currentTime变化之后，会自动触发timeupdate事件，会去执行setProgress函数
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;setProgress函数会设置进度条的宽度样式等。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;6、自动播放下一首
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oAudio.addEventListener(&amp;#39;ended&amp;#39;,&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;autoPlay();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;autoPlay&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;num++;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(num&amp;nbsp;&amp;gt;=&amp;nbsp;len)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;num&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;isOn&amp;nbsp;=&amp;nbsp;false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;init(num);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;playAndPause();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;播放或者暂停的切换函数
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;playAndPause()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;isOn&amp;nbsp;=&amp;nbsp;!isOn;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;播放和暂停按钮的切换
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(isOn)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oAudio.play();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#play&amp;#39;).removeClass(&amp;#39;play1&amp;#39;).addClass(&amp;#39;play2&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#play&amp;#39;).attr(&amp;#39;title&amp;#39;,&amp;nbsp;&amp;#39;暂停&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oAudio.pause();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#play&amp;#39;).removeClass(&amp;#39;play2&amp;#39;).addClass(&amp;#39;play1&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#play&amp;#39;).attr(&amp;#39;title&amp;#39;,&amp;nbsp;&amp;#39;播放&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;停止播放功能
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;点击停止按钮，停止播放，进度条归零
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;stop()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oAudio.pause();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;状态归为初始状态
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;isOn&amp;nbsp;=&amp;nbsp;false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;当前的时间归0,同时触发timeupdate事件。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oAudio.currentTime&amp;nbsp;=&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#play&amp;#39;).removeClass(&amp;#39;play2&amp;#39;).addClass(&amp;#39;play1&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#play&amp;#39;).attr(&amp;#39;title&amp;#39;,&amp;nbsp;&amp;#39;播放&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;进度条和时间的更新,当currentTime更新的时候，会触发timeupdate这个事件
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;这个事件触发的时候，不断更新进度条的宽度和当前的播放时间
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;setProgress()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;currentTime&amp;nbsp;=&amp;nbsp;this.currentTime;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;totaltime&amp;nbsp;=&amp;nbsp;this.duration;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;radio&amp;nbsp;=&amp;nbsp;currentTime&amp;nbsp;/&amp;nbsp;totaltime;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;currentWidth&amp;nbsp;=&amp;nbsp;totalWidth&amp;nbsp;*&amp;nbsp;radio;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#curProgrees&amp;#39;).css(&amp;#39;width&amp;#39;,&amp;nbsp;currentWidth);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#totalTime&amp;#39;).html(formate(totaltime));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;console.log(currentTime&amp;nbsp;,&amp;nbsp;totaltime)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#presentTime&amp;#39;).html(formate(currentTime));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;初始化界面和当前音乐的总时间
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;init(num)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;隐藏时间，避免看到NaN
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#playTime&amp;#39;).hide();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;出现音乐加载loading
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;.loading&amp;#39;).show();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oAudio.src&amp;nbsp;=&amp;nbsp;musicList[num].videoSrc;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#cover&amp;#39;).attr(&amp;#39;src&amp;#39;,&amp;nbsp;musicList[num].coverSrc);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#musicList&amp;nbsp;&amp;gt;&amp;nbsp;li&amp;#39;).removeClass(&amp;#39;active&amp;#39;).eq(num).addClass(&amp;#39;active&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;当音乐加载完毕，才获取总的时间，去掉loading
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;oAudio.addEventListener(&amp;#39;loadedmetadata&amp;#39;,&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;隐藏loading
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;.loading&amp;#39;).hide();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;totaltime&amp;nbsp;=&amp;nbsp;this.duration;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;显示时间
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#playTime&amp;#39;).show();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&amp;#39;#totalTime&amp;#39;).html(formate(totaltime));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&amp;nbsp;&amp;quot;json&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;格式化时间
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function&amp;nbsp;formate(time)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;min&amp;nbsp;=&amp;nbsp;Math.floor(time&amp;nbsp;/&amp;nbsp;60);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;sec&amp;nbsp;=&amp;nbsp;Math.floor(time&amp;nbsp;%&amp;nbsp;60);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;min&amp;nbsp;=&amp;nbsp;min&amp;nbsp;&amp;lt;&amp;nbsp;10&amp;nbsp;?&amp;nbsp;&amp;#39;0&amp;#39;&amp;nbsp;+&amp;nbsp;min&amp;nbsp;:&amp;nbsp;min;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sec&amp;nbsp;=&amp;nbsp;sec&amp;nbsp;&amp;lt;&amp;nbsp;10&amp;nbsp;?&amp;nbsp;&amp;#39;0&amp;#39;&amp;nbsp;+&amp;nbsp;sec&amp;nbsp;:&amp;nbsp;sec;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;`${min}:${sec}`;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt; © Copyright Birdol.Com 2006-2014.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/334.html&quot; target=&quot;_blank&quot;&gt;继续阅读《H5 Audio API+jQuery+ajax实现一个迷你播放器！》的全文内容...&lt;/a&gt;&lt;/p&gt;&lt;p&gt;分类: JavaScript案例集 | Tags: &lt;a href=&quot;http://mrszhao.com/tags-300.html&quot;&gt;audio&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-301.html&quot;&gt;HTML5&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-269.html&quot;&gt;jQuery&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-299.html&quot;&gt;ajax&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-302.html&quot;&gt;播放器&lt;/a&gt;， | &lt;a href=&quot;http://mrszhao.com/post/334.html#comment&quot; target=&quot;_blank&quot;&gt;添加评论&lt;/a&gt;(0)&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/334.html#comment&quot; target=&quot;_blank&quot;&gt;还没有评论，您来说两句？&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;相关文章:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/345.html&quot;&gt;Vue版本的todos本地任务清单！&lt;/a&gt; (2023-07-28)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/182.html&quot;&gt;利用transform打造走动的2D时钟&lt;/a&gt; (2018-05-15)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/312.html&quot;&gt;HTML5拖拽API实现本地拖拽或点击选择多张图片显示缩略图&lt;/a&gt; (2023-07-05)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/332.html&quot;&gt;jQuery+Ajax实现表单的关联下拉菜单选择&lt;/a&gt; (2021-12-18)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/204.html&quot;&gt;JavaScript案例5：QQ好友列表的展开和隐藏&lt;/a&gt; (2018-08-28)  &lt;/li&gt;&lt;/ul&gt;&lt;a target=&quot;_blank&quot; title=&quot;阿里云优惠&quot; href=&quot;http://www.birdol.com/redirect/?s=6&quot;&gt;&lt;img alt=&quot;Z-Blog&quot; src=&quot;http://www.birdol.com/aliyun/qingdao950x90.jpg&quot;&gt;&lt;/a&gt;</description><pubDate>Wed, 12 Jul 2023 19:34:59 +0800</pubDate></item><item><title>函数中的this对象的四种绑定规则和优先级！</title><link>http://mrszhao.com/post/337.html</link><description>&lt;p&gt;函数中的this是一个刚开始接触比较头疼的概念，总感觉它变来变去，害怕一不留神它就不是原来的它了。&lt;/p&gt;&lt;p&gt;ES6用了箭头函数干脆把this固定住，不允许它变，但是在更复杂的场景中，我们恰恰需要this的多变性，所以，还是必须把this的绑定规则搞定。&lt;/p&gt;&lt;h2&gt;1、this对象&lt;/h2&gt;&lt;p&gt;this是JavaScript中一个很特别的关键字，被自动定义在所有函数的作用域中。在函数被调用的时候，this才具有指向性。this引用的是函数执行时的环境对象，也就是函数执行时的作用域对象。不是函数声明时的作用域对象。&lt;/p&gt;&lt;h3&gt;1.1、调用位置&lt;/h3&gt;&lt;p cid=&quot;n292&quot; mdtype=&quot;paragraph&quot;&gt;this的绑定和函数声明的位置没有任何关系，只取决于函数的调用方式。&lt;/p&gt;&lt;p cid=&quot;n294&quot; mdtype=&quot;paragraph&quot;&gt;在理解this的绑定过程之前，首先要理解调用位置：调用位置就是函数在代码中被调用的位置（而不是声明的位置）。&lt;/p&gt;&lt;p cid=&quot;n296&quot; mdtype=&quot;paragraph&quot;&gt;最重要的是要分析调用栈，就是为了到达当前执行位置所调用的所有函数，我们关心的调用位置就在当前正在执行的函数的前一个调用中。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;调用栈就是当前正在执行的函数
//&amp;nbsp;调用位置就在当前正在执行的函数的前一个调用中。
function&amp;nbsp;baz(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//当前调用栈是：baz
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;因此，当前调用位置是全局作用域
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;baz&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bar();&amp;nbsp;//bar的调用位置
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;baz&amp;#39;);
}
function&amp;nbsp;bar(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;当前调用栈是baz-&amp;gt;bar
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;因此，当前调用位置在baz中。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;bar&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foo();//foo的调用位置
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;bar&amp;#39;);
}
function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//调试命令，可以让程序停留在这里
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;debugger;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;当前调用栈是baz-&amp;gt;bar-&amp;gt;foo
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;因此，当前调用位置在bar中。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;foo&amp;#39;);
}

baz();&amp;nbsp;//baz的调用位置&lt;/pre&gt;&lt;h3&gt;1.2、绑定规则&lt;/h3&gt;&lt;h4&gt;1.2.1、默认绑定&lt;/h4&gt;&lt;p&gt;最常用的函数调用类型：独立函数调用。可以把这条规则看作是无法应用其它规则时的默认规则。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a);
}
//声明在全局作用域中的变量就是全局对象的一个属性。
var&amp;nbsp;a&amp;nbsp;=&amp;nbsp;2;
//&amp;nbsp;函数被调用时应用了this的默认绑定，this指向全局对象window
foo();&amp;nbsp;//&amp;nbsp;2&lt;/pre&gt;&lt;h4&gt;1.2.2、隐式绑定&lt;/h4&gt;&lt;p&gt;另一条需要考虑的规则是调用位置是否有上下文对象，或者说是否被某个对象拥有或者包含。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a);
}
var&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foo:foo
}
obj.foo();&amp;nbsp;//&amp;nbsp;2&lt;/pre&gt;&lt;p cid=&quot;n308&quot; mdtype=&quot;paragraph&quot;&gt;函数foo()被当做引用属性添加到obj中，但是无论是直接在obj中定义还是先定义再添加为引用属性，这个函数严格来说都不属于obj对象。&lt;/p&gt;&lt;p cid=&quot;n310&quot; mdtype=&quot;paragraph&quot;&gt;然而，调用位置会使用obj上下文来引用函数，因为可以说函数被调用时obj对象“拥有”或者包含”它。&lt;/p&gt;&lt;p cid=&quot;n312&quot; mdtype=&quot;paragraph&quot;&gt;当foo()被调用时，它的前面加上了对obj的引用。当函数引用有上下文对象时，隐式绑定规则会把函数调用时的this绑定到这个上下文对象。&lt;/p&gt;&lt;p cid=&quot;n314&quot; mdtype=&quot;paragraph&quot;&gt;对象属性引用链中只有上一层或者说最后一层在调用位置中起作用。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a);
}
var&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foo:foo
}
var&amp;nbsp;obj1&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:3,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;obj2:obj,
}
obj1.obj2.foo();//2&lt;/pre&gt;&lt;h4&gt;1.2.3、隐式丢失&lt;/h4&gt;&lt;p&gt;一个最常见的this绑定问题就是被隐式绑定的函数会丢失绑定对象，也就是说它会应用默认绑定，从而把this绑定到全局对象或者undefined中。取决于是否是严格模式。（非严格模式绑定到全局对象，严格模式绑定到undefined中）&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a);
}
var&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foo:foo,
}
//bar是obj.foo的一个引用，但是实际上，它引用的是函数foo本身。函数引用的上下文丢失
var&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;obj.foo;&amp;nbsp;//&amp;nbsp;函数别名！
var&amp;nbsp;a&amp;nbsp;=&amp;nbsp;&amp;#39;全局属性的值&amp;#39;;
//此时bar()其实是一个不带任何修饰的函数调用，因此应用了默认绑定。
bar();&amp;nbsp;//&amp;nbsp;全局属性的值&lt;/pre&gt;&lt;p&gt;一种更常见的情况发生在传入回调函数时：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a);
}
//传入回调函数
function&amp;nbsp;doFoo(fn){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//fn其实引用的是foo
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn();&amp;nbsp;//foo的调用位置
}
var&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foo:foo
}
var&amp;nbsp;a&amp;nbsp;=&amp;nbsp;&amp;#39;全局属性的值&amp;#39;;
//传递参数其实也是一种隐式赋值，传入函数时也会被隐式赋值。
//&amp;nbsp;fn&amp;nbsp;=&amp;nbsp;obj.foo&amp;nbsp;函数别名
doFoo(obj.foo);//全局属性的值&lt;/pre&gt;&lt;p&gt;把函数传入语言内置的函数，情况也是一样的。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a);
}
var&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a&amp;nbsp;:&amp;nbsp;2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foo&amp;nbsp;:&amp;nbsp;foo
}
var&amp;nbsp;a&amp;nbsp;=&amp;nbsp;&amp;quot;全局属性的值&amp;quot;;
setTimeout(obj.foo,1000);&amp;nbsp;//全局属性的值

//和下面的代码原理相似：
//fn&amp;nbsp;=&amp;nbsp;obj.foo&amp;nbsp;函数别名
function&amp;nbsp;setTimeout(fn,delay){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//等待delay毫秒
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn();&amp;nbsp;//调用位置

}&lt;/pre&gt;&lt;p&gt;回调函数丢失this绑定是非常常见的。那么如何固定this呢？&lt;/p&gt;&lt;h4&gt;1.2.4、显式绑定&lt;/h4&gt;&lt;p cid=&quot;n330&quot; mdtype=&quot;paragraph&quot;&gt;隐式绑定时，我们必须在一个对象内部包含一个指向函数的属性，并通过这个属性间接引用函数，从而把this间接绑定到这个对象上。&lt;/p&gt;&lt;p cid=&quot;n332&quot; mdtype=&quot;paragraph&quot;&gt;如果不想在对象内部包含函数引用，只想在某个对象上强制调用函数，该怎么做呢？&lt;/p&gt;&lt;p cid=&quot;n334&quot; mdtype=&quot;paragraph&quot;&gt;函数作为对象，也拥有自己的方法，call()和apply()方法，JavaScript提供的函数和自己创建的所有函数都可以使用call()和apply()方法。&lt;/p&gt;&lt;p cid=&quot;n336&quot; mdtype=&quot;paragraph&quot;&gt;方法的第一个参数是一个对象，是给this准备的，在调用函数时将其绑定到this。因为可以直接指定this的绑定对象，这种方法称之为显式绑定。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a);
}
var&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2
}

foo.call(obj);&amp;nbsp;//&amp;nbsp;2&lt;/pre&gt;&lt;p cid=&quot;n339&quot; mdtype=&quot;paragraph&quot;&gt;通过foo.call()，可以在调用foo()函数时强制把foo里面的this绑定到obj上。&lt;/p&gt;&lt;p cid=&quot;n341&quot; mdtype=&quot;paragraph&quot;&gt;如果传入了一个原始值（字符串类型、布尔值类型、数字类型）来当作this的绑定对象，这个原始值会被转换成它的对象形式（new String()、new Boolean()、new Number()），这通常被称为“装箱”。&lt;/p&gt;&lt;p cid=&quot;n341&quot; mdtype=&quot;paragraph&quot;&gt;&lt;strong&gt;1、硬绑定&lt;/strong&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a);
}
var&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:&amp;nbsp;2
}
//显式的强制绑定叫做硬绑定
var&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;function&amp;nbsp;()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foo.call(obj);
}
bar();&amp;nbsp;//&amp;nbsp;2&amp;nbsp;
setTimeout(bar,&amp;nbsp;100);&amp;nbsp;//&amp;nbsp;2
var&amp;nbsp;a&amp;nbsp;=&amp;nbsp;&amp;#39;全局&amp;#39;;
//硬绑定的bar不可能再修改它的this
bar.call(window);&amp;nbsp;//&amp;nbsp;2&lt;/pre&gt;&lt;p cid=&quot;n341&quot; mdtype=&quot;paragraph&quot;&gt;硬绑定的典型应用场景就是创建一个包裹函数，负责接收参数并返回值：&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(something){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a,something);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this.a&amp;nbsp;+&amp;nbsp;something;
}
var&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2
}
var&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;function(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//把bar的arguments参数传递给foo，apply支持传递arguments参数。
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;foo.apply(obj,arguments);
}
var&amp;nbsp;b&amp;nbsp;=&amp;nbsp;bar(3);&amp;nbsp;//&amp;nbsp;2&amp;nbsp;3
console.log(b);&amp;nbsp;//&amp;nbsp;5&lt;/pre&gt;&lt;p&gt;另一种方法是创建一个可以重复使用的辅助函数：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(something){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a,something);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this.a&amp;nbsp;+&amp;nbsp;something;
}

//简单的辅助绑定函数
function&amp;nbsp;bind(fn,obj){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//返回一个新函数，形成闭包
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;function(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;fn.apply(obj,arguments);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
var&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2
}
var&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;bind(foo,obj);
var&amp;nbsp;b&amp;nbsp;=&amp;nbsp;bar(3);&amp;nbsp;//&amp;nbsp;2&amp;nbsp;3&amp;nbsp;
console.log(b);&amp;nbsp;//&amp;nbsp;5&lt;/pre&gt;&lt;p&gt;由于硬绑定是一种非常常见的模式，所以ES5提供了内置的方法Function.prototype.bind，它的用法如下：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(something){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a,something);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this.a&amp;nbsp;+&amp;nbsp;something;
}

var&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2
}
//利用JavaScript提供的bind函数直接硬绑定
var&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;foo.bind(obj);
var&amp;nbsp;b&amp;nbsp;=&amp;nbsp;bar(3);&amp;nbsp;//&amp;nbsp;2&amp;nbsp;3
console.log(b);//5
console.log(bar&amp;nbsp;===&amp;nbsp;foo);&amp;nbsp;//&amp;nbsp;false&lt;/pre&gt;&lt;p&gt;bind()会返回一个新函数，它会把你指定的参数设置为this的上下文并调用原始函数。&lt;/p&gt;&lt;p cid=&quot;n357&quot; mdtype=&quot;paragraph&quot;&gt;&lt;strong&gt;2、API调用的“上下文”&lt;/strong&gt;&lt;/p&gt;&lt;p cid=&quot;n359&quot; mdtype=&quot;paragraph&quot;&gt;第三方库的许多函数，以及JavaScript语言和宿主环境中许多新的内置函数，都提供了一个可选的参数，通常被称为“上下文（context）”，其作用和bind()一样，确保你的回调函数使用指定的this。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(el){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(el,this.id);
}
var&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;id:&amp;#39;myid&amp;#39;
}
var&amp;nbsp;id&amp;nbsp;=&amp;nbsp;&amp;#39;全局&amp;#39;;
//调用foo时把this绑定到obj
[1,2,3].forEach(foo,obj);&lt;/pre&gt;&lt;p&gt;这些函数实际上就是通过call()等实现了显示绑定，可以少写一些代码实现this的绑定。&lt;/p&gt;&lt;h4&gt;&lt;strong&gt;1.2.5、new绑定&lt;/strong&gt;&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;p cid=&quot;n365&quot; mdtype=&quot;paragraph&quot;&gt;这是最后一条this的绑定规则。&lt;/p&gt;&lt;p cid=&quot;n367&quot; mdtype=&quot;paragraph&quot;&gt;使用new来调用函数，或者说发生构造函数调用时，会自动执行下面的操作：&lt;/p&gt;&lt;p cid=&quot;n369&quot; mdtype=&quot;paragraph&quot;&gt;1、创建一个全新的对象。&lt;/p&gt;&lt;p cid=&quot;n371&quot; mdtype=&quot;paragraph&quot;&gt;2、这个新对象会被执行[[prototype]]连接。&lt;/p&gt;&lt;p cid=&quot;n373&quot; mdtype=&quot;paragraph&quot;&gt;3、这个新对象会绑定到函数调用的this。&lt;/p&gt;&lt;p cid=&quot;n375&quot; mdtype=&quot;paragraph&quot;&gt;4、如果函数没有返回其它对象，那么new表达式中的函数调用会自动返回这个新对象。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;Foo(a){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.a&amp;nbsp;=&amp;nbsp;a&amp;nbsp;;
}
//使用new调用foo函数，会构造出一个新对象，并把这个新对象绑定到foo函数调用中的this上。
var&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Foo(2);
console.log(bar.a);&amp;nbsp;//&amp;nbsp;2&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p cid=&quot;n378&quot; mdtype=&quot;paragraph&quot;&gt;在JavaScript中，构造函数只是一些使用new操作符时被调用的函数，它们并不是一种特殊的函数类型，它们只是被new操作符调用的普通函数而已。&lt;/p&gt;&lt;p cid=&quot;n380&quot; mdtype=&quot;paragraph&quot;&gt;所以，所有函数都可以用new来调用，这种函数调用被称为构造函数调用，实际上并不存在所谓的“构造函数”，只有对于函数的“构造调用”。&lt;/p&gt;&lt;h3&gt;1.3、优先级&lt;/h3&gt;&lt;p cid=&quot;n383&quot; mdtype=&quot;paragraph&quot;&gt;默认绑定的优先级是四条规则中最低的。&lt;/p&gt;&lt;p cid=&quot;n385&quot; mdtype=&quot;paragraph&quot;&gt;显示绑定的优先级高于隐式绑定。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a);
}
var&amp;nbsp;obj1&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foo:foo&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
}
var&amp;nbsp;obj2&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:3,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foo:foo&amp;nbsp;
}
obj1.foo();&amp;nbsp;//&amp;nbsp;2
obj2.foo();&amp;nbsp;//&amp;nbsp;3
obj1.foo.call(obj2);&amp;nbsp;//&amp;nbsp;3
obj2.foo.call(obj1);&amp;nbsp;//&amp;nbsp;2&lt;/pre&gt;&lt;p&gt;new绑定比隐式绑定优先级高&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(something){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.a&amp;nbsp;=&amp;nbsp;something;
}

var&amp;nbsp;obj1&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foo:foo
}
var&amp;nbsp;obj2&amp;nbsp;=&amp;nbsp;{};
obj1.foo(2);
console.log(obj1.a);&amp;nbsp;//&amp;nbsp;2
//显示绑定比隐式绑定优先级高
obj1.foo.call(obj2,3);
console.log(obj2.a);//3
//new绑定比隐式绑定的优先级高
var&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;new&amp;nbsp;obj1.foo(4);
console.log(bar.a);&amp;nbsp;//&amp;nbsp;4

console.log(obj1.a);//2&lt;/pre&gt;&lt;p&gt;new绑定的优先级高于显示绑定&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(something){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.a&amp;nbsp;=&amp;nbsp;something;
}

var&amp;nbsp;obj1=&amp;nbsp;{};
var&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;foo.bind(obj1);
bar(2);
console.log(obj1.a);&amp;nbsp;//&amp;nbsp;2
var&amp;nbsp;baz&amp;nbsp;=&amp;nbsp;new&amp;nbsp;bar(3);
console.log(obj1.a);&amp;nbsp;//&amp;nbsp;2
console.log(baz.a);&amp;nbsp;//&amp;nbsp;3&lt;/pre&gt;&lt;p cid=&quot;n394&quot; mdtype=&quot;paragraph&quot;&gt;现在可以根据优先级来判断函数在某个调用位置应用的是哪条规则。&lt;/p&gt;&lt;p cid=&quot;n396&quot; mdtype=&quot;paragraph&quot;&gt;可以按照下面的顺序进行判断：&lt;/p&gt;&lt;p&gt;1、函数是否在new中调用（new绑定）？如果是的话this绑定的是新创建的对象。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Foo()&lt;/pre&gt;&lt;p&gt;2、函数是否通过call、apply（显式绑定）或者硬绑定调用？如果是的话，this绑定的是指定的对象。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;foo.call(obj2)&lt;/pre&gt;&lt;p&gt;3、函数是否在某个上下文对象中调用（隐式绑定）？如果是的话，this绑定的是那个上下文对象。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;obj.foo()&lt;/pre&gt;&lt;p&gt;4、如果都不是的话，使用默认绑定。如果是在严格模式下，就绑定到undefined，否则绑定到全局对象。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;foo()&lt;/pre&gt;&lt;h3&gt;1.4、绑定例外&lt;/h3&gt;&lt;p&gt;如果把null或者undefined作为this的绑定对象传入call、apply或者bind，这些值在调用时会被忽略，实际应用的是默认绑定。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a);
}
var&amp;nbsp;a&amp;nbsp;=&amp;nbsp;2;
foo.call(null);&amp;nbsp;//&amp;nbsp;2&lt;/pre&gt;&lt;p cid=&quot;n414&quot; mdtype=&quot;paragraph&quot;&gt;什么情况下会传入null呢？&lt;/p&gt;&lt;p cid=&quot;n416&quot; mdtype=&quot;paragraph&quot;&gt;一种常用的做法是用apply()来展开一个数组，并当做参数传入一个函数。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(a,b){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(a&amp;nbsp;+&amp;nbsp;b);
}
//&amp;nbsp;把数组展开成参数
foo.apply(null,[2,3]);&amp;nbsp;//&amp;nbsp;5
//使用bind()进行柯里化
var&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;foo.bind(null,2);
bar(3);&amp;nbsp;//&amp;nbsp;5&lt;/pre&gt;&lt;p&gt;这两种方法都需要传入一个参数当做this的绑定对象，如果函数不关心this的话，仍然需要传入一个占位值，null非常方便。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;arr&amp;nbsp;=&amp;nbsp;[12,45,14,38];
let&amp;nbsp;max&amp;nbsp;=&amp;nbsp;Math.max.apply(null,arr);
console.log(max);&amp;nbsp;//&amp;nbsp;45&lt;/pre&gt;&lt;p&gt;然而，总是使用null来忽略this绑定可能产生一些副作用，如果某个函数确实使用了this（比如第三方库中的一个函数），那默认绑定会把this绑定到全局对象window上，这可能会导致不可预计的后果（比如修改全局对象）。所以，使用null会导致难以分析和追踪的bug。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;更安全的this&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;一种更安全的方法是传入一个特殊的对象，把this绑定到这个对象不会对程序产生任何副作用。&lt;/p&gt;&lt;p cid=&quot;n428&quot; mdtype=&quot;paragraph&quot;&gt;通过创建一个空对象，就不会对全局对象产生任何影响。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;//&amp;nbsp;创建一个空对象，这个空对象比{}更空，因为并不会创建Object.prototype对象。
var&amp;nbsp;φ&amp;nbsp;=&amp;nbsp;Object.create(null);
//&amp;nbsp;console.log(φ,{})
function&amp;nbsp;foo(a,b){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(a&amp;nbsp;+&amp;nbsp;b);
}
//&amp;nbsp;把数组展开成参数
foo.apply(φ,[2,3]);&amp;nbsp;//&amp;nbsp;5
//使用bind()进行柯里化
var&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;foo.bind(φ,2);
bar(3);&amp;nbsp;//&amp;nbsp;5&lt;/pre&gt;&lt;h2&gt;2、this词法&lt;/h2&gt;&lt;p cid=&quot;n432&quot; mdtype=&quot;paragraph&quot;&gt;在ES6中有一种无法使用上面四种规则的特殊函数类型：箭头函数。&lt;/p&gt;&lt;p cid=&quot;n434&quot; mdtype=&quot;paragraph&quot;&gt;箭头函数并不是使用function关键字定义的，而是使用被称为“胖箭头”的操作符=&amp;gt;定义的。箭头函数不使用this的四种标准规则，而是根据外层（函数或者全局）作用域来决定this。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//返回一个箭头函数
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;a&amp;nbsp;=&amp;gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//this继承自foo()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/*&amp;nbsp;return&amp;nbsp;function(a){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&amp;nbsp;*/
}
let&amp;nbsp;obj1&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2
};
let&amp;nbsp;obj2&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:3
};

let&amp;nbsp;bar&amp;nbsp;=&amp;nbsp;foo.call(obj1);
bar.call(obj2);//&amp;nbsp;2&lt;/pre&gt;&lt;p cid=&quot;n437&quot; mdtype=&quot;paragraph&quot;&gt;foo()内部创建的箭头函数会捕获调用时foo()的 this，由于foo()的this绑定到了obj1，bar(引用箭头函数)的this也会绑定到obj1，箭头函数的绑定无法被修改。（new也不行！）&lt;/p&gt;&lt;p cid=&quot;n439&quot; mdtype=&quot;paragraph&quot;&gt;箭头函数最常用于回调函数中，例如事件处理器或者定时器：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setTimeout(()=&amp;gt;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//这里的this在词法上继承自foo()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(this.a);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},1000)
}

let&amp;nbsp;obj1&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2
};
foo.call(obj1);&amp;nbsp;//&amp;nbsp;2&lt;/pre&gt;&lt;p cid=&quot;n442&quot; mdtype=&quot;paragraph&quot;&gt;箭头函数可以像bind()一样确保函数的this被绑定到指定对象上，此外，其重要性还体现在它用更常见的词法作用域取代了传统的this机制。&lt;/p&gt;&lt;p cid=&quot;n444&quot; mdtype=&quot;paragraph&quot;&gt;在ES6之前，有一种几乎和箭头函数完全一样的模式：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//把this对象保存在变量中
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;_this&amp;nbsp;=&amp;nbsp;this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setTimeout(function(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//通过_this变量来使用保存好的this对象
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(_this.a);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},1000)
}

let&amp;nbsp;obj1&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a:2
};
foo.call(obj1);&amp;nbsp;//&amp;nbsp;2&lt;/pre&gt;&lt;h2&gt;3、构造函数&lt;/h2&gt;&lt;p cid=&quot;n448&quot; mdtype=&quot;paragraph&quot;&gt;其实，在JavaScript中，构造函数并不是一种特殊的函数，只是受到Java等面向对象，拥有类概念的语言的影响。&lt;/p&gt;&lt;p cid=&quot;n450&quot; mdtype=&quot;paragraph&quot;&gt;构造函数首字母要大写这种规矩也是来源于对Java等语言的追随。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;Foo(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;this;
}
let&amp;nbsp;o&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Foo();

console.dir(Foo);//prototype是函数的一个属性，可以叫做原型对象。
//函数的prototype对象里面有一个constructor属性，又指向函数本身。
console.log(Foo.prototype.constructor&amp;nbsp;===&amp;nbsp;Foo);&amp;nbsp;//&amp;nbsp;true
//o是一个实例，它有一个原型链[[Prototype]]属性，指向new出自己的函数的原型对象。
console.log(o);
//通过__proto__可以访问实例的原型对象。
console.log(o.__proto__);
//o实例并没有constructor属性，但是通过对原型链的往上层访问，可以访问到原型对象里面的constructor属性。
console.log(o.constructor&amp;nbsp;===&amp;nbsp;Foo);//&amp;nbsp;true&lt;/pre&gt;&lt;p&gt;实际上，Foo函数与其他函数没有任何区别。函数本身不是构造函数，当在普通函数调用前面加上new关键字后，就会把这个函数调用变成一个“构造函数调用”。实际上，new会劫持所有普通函数并用构造对象的形式来调用它。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;function&amp;nbsp;nothingSpecial(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;我是一个普通函数&amp;#39;);
}

let&amp;nbsp;obj&amp;nbsp;=&amp;nbsp;new&amp;nbsp;nothingSpecial();
console.log(obj);&amp;nbsp;//&amp;nbsp;{}&lt;/pre&gt;&lt;p cid=&quot;n456&quot; mdtype=&quot;paragraph&quot;&gt;nothingSpecial()只是一个普通函数，使用new调用的时候，就会产生一个对象并赋值给obj，使用new调用一个函数无论如何都会返回一个对象。这个new的调用是一个构造函数的调用，但是nothingSpecial()却不是一个 构造函数。&lt;/p&gt;&lt;p cid=&quot;n458&quot; mdtype=&quot;paragraph&quot;&gt;可以理解为在JavaScript中，对于“构造函数”最准确的解释是：所有带new的函数调用。&lt;/p&gt;&lt;p cid=&quot;n460&quot; mdtype=&quot;paragraph&quot;&gt;函数不是构造函数，但是当且仅当使用new时，函数调用会变成“构造函数调用”。&lt;/p&gt;&lt;p cid=&quot;n460&quot; mdtype=&quot;paragraph&quot;&gt;&lt;strong&gt;当函数作为构造函数调用的时候，函数内部的this指向new返回出来的对象。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt; © Copyright Birdol.Com 2006-2014.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/337.html&quot; target=&quot;_blank&quot;&gt;继续阅读《函数中的this对象的四种绑定规则和优先级！》的全文内容...&lt;/a&gt;&lt;/p&gt;&lt;p&gt;分类: JavaScript教程 | Tags: &lt;a href=&quot;http://mrszhao.com/tags-305.html&quot;&gt;函数&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-309.html&quot;&gt;this&lt;/a&gt;，&lt;a href=&quot;http://mrszhao.com/tags-310.html&quot;&gt;箭头函数&lt;/a&gt;， | &lt;a href=&quot;http://mrszhao.com/post/337.html#comment&quot; target=&quot;_blank&quot;&gt;添加评论&lt;/a&gt;(0)&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://mrszhao.com/post/337.html#comment&quot; target=&quot;_blank&quot;&gt;还没有评论，您来说两句？&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;相关文章:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/236.html&quot;&gt;JavaScript基础6:数组Arrays和常用属性与方法&lt;/a&gt; (2019-07-23)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/254.html&quot;&gt;DOM基础1：DOM对象初了解&lt;/a&gt; (2019-08-19)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/336.html&quot;&gt;函数作为对象的属性和方法(call、apply、bind)&lt;/a&gt; (2023-07-10)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/231.html&quot;&gt;JavaScript基础3:运算符和表达式&lt;/a&gt; (2019-07-08)  &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrszhao.com/post/340.html&quot;&gt;对象属性的访问、遍历、getter和setter等高级特性！&lt;/a&gt; (2023-07-16)  &lt;/li&gt;&lt;/ul&gt;&lt;a target=&quot;_blank&quot; title=&quot;阿里云优惠&quot; href=&quot;http://www.birdol.com/redirect/?s=6&quot;&gt;&lt;img alt=&quot;Z-Blog&quot; src=&quot;http://www.birdol.com/aliyun/qingdao950x90.jpg&quot;&gt;&lt;/a&gt;</description><pubDate>Wed, 12 Jul 2023 14:28:29 +0800</pubDate></item></channel></rss><!--498.63 ms , 23 query , 6752kb memory , 0 error-->