整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          2017年最重要的HTML5開發手冊,傳播正能量

          天給大家推薦這個HTML5開發手冊,希望能幫助正在學習web前端的人,鄙人也是剛學習前端沒多久,借助于一點資訊平臺能夠結識更多前端大牛,這是我的HTML5進階學習一點資訊群:250777811,里面有很多大牛隨時解答學習問題,每天晚上休息的時候還有免費的企業項目解決,歡迎初學者和進階的伙計申請加入。

          1、HTML5中文手冊

          通過制定如何處理所以HTMl元素以及如何從錯誤中恢復的緊缺規則,HTML5改進了互操作性,并2減少了開發成本。HTML5中的新特性包括了嵌入音頻、視頻和圖形的功能,客戶端數據存儲,以及交互式文檔。

          2、 CSS完全參考手冊3.0下載

          3、JavaScript參考手冊

          JavaScript 本地對象和內置對象 Browser 對象(BOM)、 HTML DOM 對象 、JavaScript 對象參考手冊 本參考手冊描述每個對象的屬性和方法,并提供實例。

          4、jQuery 1.4參考手冊

          2010年1月22日,更新至JQuery 1.4版本,本版是參考shawphy的1.4在線版本制作,更新了好多以前的內容,以前沒仔細核對過,發現之前網上流行的chm版本基本都基于1.2的,1.3的內容很多都沒加進去,這次都補全了。用*標注了1.3版本新加的內容,@標注1.4新加的內容,方便大家查看。

          5、Ajax中文手冊

          AJAX是一種運用JavaScript和可擴展標記語言(XML),在網絡瀏覽器和服務器之間傳送或接受數據 的技術。AJAX可以用來和數據端進行數據的交互聯通。AJAX可以用來創建更多交互式的網絡應用程序。

          6、Bootstrap3參考手冊

          Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的,它簡潔靈活,使得 Web 開發更加快捷。它由Twitter的設計師Mark Otto和Jacob Thornton合作開發,是一個CSS/HTML框架。Bootstrap提供了優雅的HTML和CSS規范,它即是由動態CSS語言Less寫成。

          全部HTML5手冊內容都已經上傳群文件了250777811

          關注悟空頭條,每日收獲HTML5學習干貨,傳播正能量,吾有本頭條!


          推薦這個項目是因為使用手冊部署手冊非常完善,項目也有開發教程視頻對小白非常貼心,接私活可以直接拿去二開非常舒服

          開源說明

          • 系統100%開源
          • 模塊化開發模式,銘飛所開發的模塊都發布到了maven中央庫。可以通過pom.xml文件的方式拉取源代碼
          <dependency>
          	<groupId>net.mingsoft</groupId>
          	<artifactId>模塊</artifactId>
          	<version>版本號</version>
          	<classifier>sources</classifier>
          	<scope>provided</scope>
          </dependency>

          商用

          基于MIT開源協議,可直接商用無需授權,但請尊重開源精神不要去掉代碼中銘飛的注釋和版權信息

          特點

          • 免費完整開源:基于MIT協議,源代碼完全開源,無商業限制,MS開發團隊承諾將MCMS內容系統永久完整開源;關注Java項目分享
          • 標簽化建站:不需要專業的后臺開發技能,只要使用系統提供的標簽,就能輕松建設網站;
          • html靜態化:系統支持全站靜態化;
          • 跨終端:站點同時支持PC與移動端訪問,同時會自動根據訪問的終端切換到對應的界面,數據由系統統一管理;
          • 海量模版:銘飛通過MStore(MS商城)分享更多免費、精美的企業網站模版,降低建站成本;關注Java項目分享
          • 豐富插件:為了讓MCms適應更多的業務場景,在MStore用戶可以下載對應的插件,如:站群插件、微信插件、商城插件等;
          • 每月更新:銘飛團隊承諾每月28日為系統升級日,分享更多好用等模版與插件;
          • 文檔豐富:為了讓用戶更快速的使用MCms系統進行開發,銘飛團隊持續更新開發相關文檔,如標簽文檔、使用文檔、視頻教程等;

          面向對象

          • 企 業:幫助創立初期的公司或團隊快速搭建產品的技術平臺,加快公司項目開發進度;
          • 開發者:幫助開發者快速完成承接外包的項目,避免從零搭建系統;
          • 學習者:初學JAVA的同學可以下載源代碼來進行學習交流;

          開發環境

          建議開發者使用以下環境,這樣避免版本帶來的問題

          • Windows、Linux
          • Eclipse、Idea
          • Mysql≧5.7
          • JDK≧8
          • Tomcat≧8

          1. MCms內容插件手冊

          MCms內容插件提供最基本的菜單、權限、角色、欄目、內容、靜態化、等常用功能。
          視頻教程:內容插件視頻教程 配合代碼生成器使用快速提升開發效率:代碼生成器在線視頻教程、代碼生成器使用文檔

          1.1. Apache Maven依賴

          1.1.1. 當前版本

          <!-- ms-mcms 內容模塊插件 -->
          <dependency>
              <groupId>net.mingsoft</groupId>
              <artifactId>ms-mcms</artifactId>
              <version>當前版本</version>
          </dependency>
          <!-- ms-mcms 內容模塊源碼 -->
          <dependency>
              <groupId>net.mingsoft</groupId>
              <artifactId>ms-mcms</artifactId>
              <version>當前版本</version>
              <classifier>sources</classifier>
          </dependency>Copy

          1.2. 接口

          項目訪問路徑/swagger-ui.html#/


          系統部署手冊

          1. jar部署

          1.1. 打包方式1

          懶人做法,將所有的資源打成一個jar包,維護資源不方便,不推薦

          mvn clean package
          java -jar ms-mcms.jarCopy

          1.2. 打包方式2(推薦)

          打包指令增加參數 -f bin-xml ,執行完成會在target目錄會生成 “ 項目-bin ” 發布文件夾

          mvn clean package -f bin-xml
          Copy

          1.2.1. 目錄結構

          config:配置文件

          html:靜態化自動生成的目錄(自動生成)

          static:靜態資源文件

          templets:(必須)模版目錄,需要復制一份

          upload:(必須)上傳的文件夾

          WEB-INF:ftl視圖文件

          mcms.log:自動生成的日志文件

          *.sh:linux啟動、停止腳本

          *.bat:window啟動、停止腳本

          技術選型

          后端框架

          技術

          名稱

          官網

          Spring Framework

          容器

          http://projects.spring.io/spring-framework

          Spring Boot

          MVC框架

          https://spring.io/projects/spring-boot

          Apache Shiro

          安全框架

          http://shiro.apache.org

          Spring session

          分布式Session管理

          http://projects.spring.io/spring-session

          MyBatis

          ORM框架

          http://www.mybatis.org

          Freemarker

          視圖框架

          http://freemarker.foofun.cn

          PageHelper

          MyBatis分頁插件

          http://git.oschina.net/free/Mybatis_PageHelper

          Log4J

          日志組件

          http://logging.apache.org

          Maven

          項目構建

          http://maven.apache.org

          Elasticsearch

          分布式搜索引擎

          https://www.elastic.co

          Redis

          分布式緩存數據庫

          https://redis.io

          hutool

          工具類

          http://hutool.mydoc.io

          前端框架

          技術

          名稱

          官網

          vue

          函式庫

          https://cn.vuejs.org//

          element ui

          UI庫

          https://element.eleme.cn/2.0/#/zh-CN

          jQuery

          函式庫

          http://jquery.com/

          Bootstrap

          前端框架

          http://getbootstrap.com/

          Bootstrap-table

          Bootstrap數據表格

          http://bootstrap-table.wenzhixin.net.cn/

          BootstrapValidator

          表單驗證

          http://bootstrapvalidator.com/

          Font-awesome

          字體圖標

          http://fontawesome.io/

          Waves

          點擊效果插件

          https://github.com/fians/Waves/

          zTree

          樹插件

          http://www.treejs.cn/v3/

          Select2

          選擇框插件

          https://github.com/select2/select2

          Vue

          MVVM框架

          https://cn.vuejs.org/

          AmazeUI

          移動端UI

          http://amazeui.org/

          Plupload

          上傳控件

          http://www.plupload.com/

          freemarker

          模板引擎

          http://freemarker.foofun.cn/toc.html

          validator

          驗證庫

          https://github.com/chriso/validator.js

          animate

          動畫

          http://daneden.github.io/animate.css/

          icon

          矢量小圖標(待更新)

          http://ms.mingsoft.net/html/86//6048/index.html

          軟件截圖

          銘飛平臺

          做開源我們是業余的,寫代碼我們是認真的。研發產品的路上我們一直在探索、一直在學習、一直在用心投入,希望能給更多的企業與開發者提供一些更有價值的服務。

          項目管理

          代碼生成器

          源碼資料獲取方式:關注小編+轉發文章+私信【 666 】免費獲取
          八股文面試資料獲取方式:關注小編+轉發文章+私信【 13 】免費獲取
          重要的事情說三遍,轉發+轉發+轉發,一定要記得點贊轉發哦!!!

          面試官:Spring 和 Spring Boot 的區別是什么?

          概述

          對于 SpringSpringBoot到底有什么區別,我聽到了很多答案,剛開始邁入學習 SpringBoot的我當時也是一頭霧水,隨著經驗的積累、我慢慢理解了這兩個框架到底有什么區別,相信對于用了 SpringBoot很久的同學來說,還不是很理解 SpringBoot到底和 Spring有什么區別,看完文章中的比較,或許你有了不同的答案和看法!

          什么是Spring

          作為 Java開發人員,大家都 Spring都不陌生,簡而言之, Spring框架為開發 Java應用程序提供了全面的基礎架構支持。它包含一些很好的功能,如依賴注入和開箱即用的模塊,如:

          SpringJDBC、SpringMVC、SpringSecurity、SpringAOP、SpringORM、SpringTest,這些模塊縮短應用程序的開發時間,提高了應用開發的效率例如,在 JavaWeb開發的早期階段,我們需要編寫大量的代碼來將記錄插入到數據庫中。但是通過使用 SpringJDBC模塊的 JDBCTemplate,我們可以將操作簡化為幾行代碼。

          什么是Spring Boot

          SpringBoot基本上是 Spring框架的擴展,它消除了設置 Spring應用程序所需的 XML配置,為更快,更高效的開發生態系統鋪平了道路。

          SpringBoot中的一些特征:

          1、創建獨立的 Spring應用。
          2、嵌入式 TomcatJettyUndertow容器(無需部署war文件)。
          3、提供的 starters 簡化構建配置
          4、盡可能自動配置 spring應用。
          5、提供生產指標,例如指標、健壯檢查和外部化配置
          6、完全沒有代碼生成和 XML配置要求

          從配置分析

          Maven依賴

          首先,讓我們看一下使用Spring創建Web應用程序所需的最小依賴項

          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-web</artifactId>
              <version>5.1.0.RELEASE</version>
          </dependency>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-webmvc</artifactId>
              <version>5.1.0.RELEASE</version>
          </dependency>

          與Spring不同,Spring Boot只需要一個依賴項來啟動和運行Web應用程序:

          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-web</artifactId>
              <version>2.0.6.RELEASE</version>
          </dependency>

          在進行構建期間,所有其他依賴項將自動添加到項目中。

          另一個很好的例子就是測試庫。我們通常使用 SpringTestJUnitHamcrestMockito庫。在 Spring項目中,我們應該將所有這些庫添加為依賴項。但是在 SpringBoot中,我們只需要添加 spring-boot-starter-test依賴項來自動包含這些庫。

          Spring Boot為不同的Spring模塊提供了許多依賴項。一些最常用的是:

          spring-boot-starter-data-jpaspring-boot-starter-securityspring-boot-starter-testspring-boot-starter-webspring-boot-starter-thymeleaf

          有關 starter的完整列表,請查看Spring文檔。

          MVC配置

          讓我們來看一下 SpringSpringBoot創建 JSPWeb應用程序所需的配置。

          Spring需要定義調度程序 servlet,映射和其他支持配置。我們可以使用 web.xml 文件或 Initializer類來完成此操作:

          public class MyWebAppInitializer implements WebApplicationInitializer {
              @Override
              public void onStartup(ServletContext container) {
                  AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
                  context.setConfigLocation("com.pingfangushi");
                    container.addListener(new ContextLoaderListener(context));
                    ServletRegistration.Dynamic dispatcher = container
                    .addServlet("dispatcher", new DispatcherServlet(context));
                  dispatcher.setLoadOnStartup(1);
                  dispatcher.addMapping("/");
              }
          }

          還需要將 @EnableWebMvc注釋添加到 @Configuration類,并定義一個視圖解析器來解析從控制器返回的視圖:

          @EnableWebMvc
          @Configuration
          public class ClientWebConfig implements WebMvcConfigurer { 
             @Bean
             public ViewResolver viewResolver() {
                InternalResourceViewResolver bean
                  = new InternalResourceViewResolver();
                bean.setViewClass(JstlView.class);
                bean.setPrefix("/WEB-INF/view/");
                bean.setSuffix(".jsp");
                return bean;
             }
          }

          再來看 SpringBoot一旦我們添加了 Web啟動程序, SpringBoot只需要在 application配置文件中配置幾個屬性來完成如上操作:

          spring.mvc.view.prefix=/WEB-INF/jsp/
          spring.mvc.view.suffix=.jsp

          上面的所有Spring配置都是通過一個名為auto-configuration的過程添加 Bootweb starter來自動包含的。

          這意味著 SpringBoot將查看應用程序中存在的依賴項,屬性和 bean,并根據這些依賴項,對屬性和 bean進行配置。當然,如果我們想要添加自己的自定義配置,那么 SpringBoot自動配置將會退回。

          配置模板引擎

          現在我們來看下如何在Spring和Spring Boot中配置Thymeleaf模板引擎。

          Spring中,我們需要為視圖解析器添加 thymeleaf-spring5依賴項和一些配置:

          @Configuration
          @EnableWebMvc
          public class MvcWebConfig implements WebMvcConfigurer {
              @Autowired
              private ApplicationContext applicationContext;
              @Bean
              public SpringResourceTemplateResolver templateResolver() {
                  SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
                  templateResolver.setApplicationContext(applicationContext);
                  templateResolver.setPrefix("/WEB-INF/views/");
                  templateResolver.setSuffix(".html");
                  return templateResolver;
              }
              @Bean
              public SpringTemplateEngine templateEngine() {
                  SpringTemplateEngine templateEngine = new SpringTemplateEngine();
                  templateEngine.setTemplateResolver(templateResolver());
                  templateEngine.setEnableSpringELCompiler(true);
                  return templateEngine;
              }
              @Override
              public void configureViewResolvers(ViewResolverRegistry registry) {
                  ThymeleafViewResolver resolver = new ThymeleafViewResolver();
                  resolver.setTemplateEngine(templateEngine());
                  registry.viewResolver(resolver);
              }
          }

          SpringBoot1X只需要 spring-boot-starter-thymeleaf的依賴項來啟用 Web應用程序中的 Thymeleaf支持。 ??但是由于 Thymeleaf3.0中的新功能,我們必須將 thymeleaf-layout-dialect 添加為 SpringBoot2XWeb應用程序中的依賴項。配置好依賴,我們就可以將模板添加到 src/main/resources/templates文件夾中, SpringBoot將自動顯示它們。

          Spring Security 配置

          為簡單起見,我們使用框架默認的 HTTPBasic身份驗證。讓我們首先看一下使用 Spring啟用 Security所需的依賴關系和配置。

          Spring首先需要依賴 spring-security-webspring-security-config 模塊。接下來, 我們需要添加一個擴展 WebSecurityConfigurerAdapter的類,并使用 @EnableWebSecurity注解:

          @Configuration
          @EnableWebSecurity
          public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
              @Autowired
              public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
                  auth.inMemoryAuthentication()
                    .withUser("admin")
                      .password(passwordEncoder()
                      .encode("password"))
                    .authorities("ROLE_ADMIN");
              }
              @Override
              protected void configure(HttpSecurity http) throws Exception {
                  http.authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                    .httpBasic();
              }
              @Bean
              public PasswordEncoder passwordEncoder() {
                  return new BCryptPasswordEncoder();
              }
          }

          這里我們使用 inMemoryAuthentication來設置身份驗證。同樣, SpringBoot也需要這些依賴項才能使其工作。但是我們只需要定義 spring-boot-starter-security的依賴關系,因為這會自動將所有相關的依賴項添加到類路徑中。

          SpringBoot中的安全配置與上面的相同

          應用程序啟動引導配置

          SpringSpringBoot中應用程序引導的基本區別在于 servletSpring使用 web.xmlSpringServletContainerInitializer作為其引導入口點。SpringBoot僅使用 Servlet3功能來引導應用程序,下面讓我們詳細來了解下

          Spring 引導配置

          Spring支持傳統的 web.xml引導方式以及最新的 Servlet3+方法。

          配置 web.xml方法啟動的步驟

          Servlet容器(服務器)讀取 web.xml

          web.xml中定義的 DispatcherServlet由容器實例化

          DispatcherServlet通過讀取 WEB-INF/{servletName}-servlet.xml來創建 WebApplicationContext。最后, DispatcherServlet注冊在應用程序上下文中定義的 bean

          使用 Servlet3+方法的 Spring啟動步驟

          容器搜索實現 ServletContainerInitializer的類并執行 SpringServletContainerInitializer找到實現所有類 WebApplicationInitializer``WebApplicationInitializer創建具有XML或上下文 @ConfigurationWebApplicationInitializer創建 DispatcherServlet與先前創建的上下文。

          SpringBoot 引導配置

          Spring Boot應用程序的入口點是使用@SpringBootApplication注釋的類

          @SpringBootApplication
          public class Application {
              public static void main(String[] args) {
                  SpringApplication.run(Application.class, args);
              }
          }

          默認情況下, SpringBoot使用嵌入式容器來運行應用程序。在這種情況下, SpringBoot使用 publicstaticvoidmain入口點來啟動嵌入式 Web服務器。此外,它還負責將 ServletFilterServletContextInitializerbean從應用程序上下文綁定到嵌入式 servlet容器。SpringBoot的另一個特性是它會自動掃描同一個包中的所有類或 Main類的子包中的組件。

          SpringBoot提供了將其部署到外部容器的方式。我們只需要擴展 SpringBootServletInitializer即可:

          /**
           * War部署
           *
           * @author SanLi
           * Created by 2689170096@qq.com on 2018/4/15
           */
          public class ServletInitializer extends SpringBootServletInitializer {
              @Override
              protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
                  return application.sources(Application.class);
              }
              @Override
              public void onStartup(ServletContext servletContext) throws ServletException {
                  super.onStartup(servletContext);
                  servletContext.addListener(new HttpSessionEventPublisher());
              }
          }

          這里外部 servlet容器查找在war包下的 META-INF文件夾下MANIFEST.MF文件中定義的 Main-classSpringBootServletInitializer將負責綁定 ServletFilterServletContextInitializer

          打包和部署

          最后,讓我們看看如何打包和部署應用程序。這兩個框架都支持 MavenGradle等通用包管理技術。但是在部署方面,這些框架差異很大。例如,Spring Boot Maven插件在 Maven中提供 SpringBoot支持。它還允許打包可執行 jarwar包并 就地運行應用程序。

          在部署環境中 SpringBoot 對比 Spring的一些優點包括:

          1、提供嵌入式容器支持
          2、使用命令
          java -jar獨立運行jar
          3、在外部容器中部署時,可以選擇排除依賴關系以避免潛在的jar沖突
          4、部署時靈活指定配置文件的選項
          5、用于集成測試的隨機端口生成

          結論

          簡而言之,我們可以說 SpringBoot只是 Spring本身的擴展,使開發,測試和部署更加方便。



          1. 這里的 "ES6" 泛指 ES5 之后的新語法
          2. 這里的 "完全" 是指本文會不斷更新
          3. 這里的 "使用" 是指本文會展示很多 ES6 的使用場景
          4. 這里的 "手冊" 是指你可以參照本文將項目更多的重構為 ES6 語法

          此外還要注意這里不一定就是正式進入規范的語法。

          1. let 和 const

          在我們開發的時候,可能認為應該默認使用 let 而不是 var,這種情況下,對于需要寫保護的變量要使用 const。

          然而另一種做法日益普及:默認使用 const,只有當確實需要改變變量的值的時候才使用 let。這是因為大部分的變量的值在初始化后不應再改變,而預料之外的變量的修改是很多 bug 的源頭。

          // 例子 1-1
          
          // bad
          var foo = 'bar';
          
          // good
          let foo = 'bar';
          
          // better
          const foo = 'bar';
          復制代碼

          2. 模板字符串

          1. 模板字符串

          需要拼接字符串的時候盡量改成使用模板字符串:

          // 例子 2-1
          
          // bad
          const foo = 'this is a' + example;
          
          // good
          const foo = `this is a ${example}`;
          復制代碼

          2. 標簽模板

          可以借助標簽模板優化書寫方式:

          // 例子 2-2
          
          let url = oneLine `
              www.taobao.com/example/index.html
              ?foo=${foo}
              &bar=${bar}
          `;
          
          console.log(url); 
          復制代碼

          oneLine 的源碼可以參考 《ES6 系列之模板字符串》

          https://github.com/mqyqingfeng/Blog/issues/109

          3. 箭頭函數

          優先使用箭頭函數,不過以下幾種情況避免使用:

          1. 使用箭頭函數定義對象的方法

          // 例子 3-1
          
          // bad
          let foo = {
            value: 1,
            getValue: () => console.log(this.value)
          }
          
          foo.getValue();  // undefined
          復制代碼

          2. 定義原型方法

          // 例子 3-2
          
          // bad
          function Foo() {
            this.value = 1
          }
          
          Foo.prototype.getValue = () => console.log(this.value)
          
          let foo = new Foo()
          foo.getValue();  // undefined
          復制代碼

          3. 作為事件的回調函數

          // 例子 3-3
          
          // bad
          const button = document.getElementById('myButton');
          button.addEventListener('click', () => {
              console.log(this === window); // => true
              this.innerHTML = 'Clicked button';
          });
          復制代碼

          4. Symbol

          1. 唯一值

          // 例子 4-1
          
          
          // bad
          // 1. 創建的屬性會被 for-in 或 Object.keys() 枚舉出來
          // 2. 一些庫可能在將來會使用同樣的方式,這會與你的代碼發生沖突
          if (element.isMoving) {
            smoothAnimations(element);
          }
          element.isMoving = true;
          
          // good
          if (element.__$jorendorff_animation_library$PLEASE_DO_NOT_USE_THIS_PROPERTY$isMoving__) {
            smoothAnimations(element);
          }
          element.__$jorendorff_animation_library$PLEASE_DO_NOT_USE_THIS_PROPERTY$isMoving__ = true;
          
          // better
          var isMoving = Symbol("isMoving");
          
          ...
          
          if (element[isMoving]) {
            smoothAnimations(element);
          }
          element[isMoving] = true;
          復制代碼

          2. 魔術字符串

          魔術字符串指的是在代碼之中多次出現、與代碼形成強耦合的某一個具體的字符串或者數值。

          魔術字符串不利于修改和維護,風格良好的代碼,應該盡量消除魔術字符串,改由含義清晰的變量代替。

          // 例子 4-1
          
          // bad
          const TYPE_AUDIO = 'AUDIO'
          const TYPE_VIDEO = 'VIDEO'
          const TYPE_IMAGE = 'IMAGE'
          
          // good
          const TYPE_AUDIO = Symbol()
          const TYPE_VIDEO = Symbol()
          const TYPE_IMAGE = Symbol()
          
          function handleFileResource(resource) {
            switch(resource.type) {
              case TYPE_AUDIO:
                playAudio(resource)
                break
              case TYPE_VIDEO:
                playVideo(resource)
                break
              case TYPE_IMAGE:
                previewImage(resource)
                break
              default:
                throw new Error('Unknown type of resource')
            }
          }
          復制代碼

          3. 私有變量

          Symbol 也可以用于私有變量的實現。

          // 例子 4-3
          
          const Example = (function() {
              var _private = Symbol('private');
          
              class Example {
                  constructor() {
                    this[_private] = 'private';
                  }
                  getName() {
                    return this[_private];
                  }
              }
          
              return Example;
          })();
          
          var ex = new Example();
          
          console.log(ex.getName()); // private
          console.log(ex.name); // undefined
          復制代碼

          5. Set 和 Map

          1. 數組去重

          // 例子 5-1
          
          [...new Set(array)]
          復制代碼

          2. 條件語句的優化

          // 例子 5-2
          // 根據顏色找出對應的水果
          
          // bad
          function test(color) {
            switch (color) {
              case 'red':
                return ['apple', 'strawberry'];
              case 'yellow':
                return ['banana', 'pineapple'];
              case 'purple':
                return ['grape', 'plum'];
              default:
                return [];
            }
          }
          
          test('yellow'); // ['banana', 'pineapple']
          復制代碼
          // good
          const fruitColor = {
            red: ['apple', 'strawberry'],
            yellow: ['banana', 'pineapple'],
            purple: ['grape', 'plum']
          };
          
          function test(color) {
            return fruitColor[color] || [];
          }
          復制代碼
          // better
          const fruitColor = new Map()
            .set('red', ['apple', 'strawberry'])
            .set('yellow', ['banana', 'pineapple'])
            .set('purple', ['grape', 'plum']);
          
          function test(color) {
            return fruitColor.get(color) || [];
          }
          復制代碼

          6. for of

          1. 遍歷范圍

          for...of 循環可以使用的范圍包括:

          1. 數組
          2. Set
          3. Map
          4. 類數組對象,如 arguments 對象、DOM NodeList 對象
          5. Generator 對象
          6. 字符串

          2. 優勢

          ES2015 引入了 for..of 循環,它結合了 forEach 的簡潔性和中斷循環的能力:

          // 例子 6-1
          
          for (const v of ['a', 'b', 'c']) {
            console.log(v);
          }
          // a b c
          
          for (const [i, v] of ['a', 'b', 'c'].entries()) {
            console.log(i, v);
          }
          // 0 "a"
          // 1 "b"
          // 2 "c"
          復制代碼

          3. 遍歷 Map

          // 例子 6-2
          
          let map = new Map(arr);
          
          // 遍歷 key 值
          for (let key of map.keys()) {
            console.log(key);
          }
          
          // 遍歷 value 值
          for (let value of map.values()) {
            console.log(value);
          }
          
          // 遍歷 key 和 value 值(一)
          for (let item of map.entries()) {
            console.log(item[0], item[1]);
          }
          
          // 遍歷 key 和 value 值(二)
          for (let [key, value] of data) {
            console.log(key)
          }
          復制代碼

          7. Promise

          1. 基本示例

          // 例子 7-1
          
          // bad
          request(url, function(err, res, body) {
              if (err) handleError(err);
              fs.writeFile('1.txt', body, function(err) {
                  request(url2, function(err, res, body) {
                      if (err) handleError(err)
                  })
              })
          });
          
          // good
          request(url)
          .then(function(result) {
              return writeFileAsynv('1.txt', result)
          })
          .then(function(result) {
              return request(url2)
          })
          .catch(function(e){
              handleError(e)
          });
          復制代碼

          2. finally

          // 例子 7-2
          
          fetch('file.json')
          .then(data => data.json())
          .catch(error => console.error(error))
          .finally(() => console.log('finished'));
          復制代碼

          8. Async

          1. 代碼更加簡潔

          // 例子 8-1
          
          // good
          function fetch() {
            return (
              fetchData()
              .then(() => {
                return "done"
              });
            )
          }
          
          // better
          async function fetch() {
            await fetchData()
            return "done"
          };
          復制代碼
          // 例子 8-2
          
          // good
          function fetch() {
            return fetchData()
            .then(data => {
              if (data.moreData) {
                  return fetchAnotherData(data)
                  .then(moreData => {
                    return moreData
                  })
              } else {
                return data
              }
            });
          }
          
          // better
          async function fetch() {
            const data = await fetchData()
            if (data.moreData) {
              const moreData = await fetchAnotherData(data);
              return moreData
            } else {
              return data
            }
          };
          復制代碼
          // 例子 8-3
          
          // good
          function fetch() {
            return (
              fetchData()
              .then(value1 => {
                return fetchMoreData(value1)
              })
              .then(value2 => {
                return fetchMoreData2(value2)
              })
            )
          }
          
          // better
          async function fetch() {
            const value1 = await fetchData()
            const value2 = await fetchMoreData(value1)
            return fetchMoreData2(value2)
          };
          復制代碼

          2. 錯誤處理

          // 例子 8-4
          
          // good
          function fetch() {
            try {
              fetchData()
                .then(result => {
                  const data = JSON.parse(result)
                })
                .catch((err) => {
                  console.log(err)
                })
            } catch (err) {
              console.log(err)
            }
          }
          
          // better
          async function fetch() {
            try {
              const data = JSON.parse(await fetchData())
            } catch (err) {
              console.log(err)
            }
          };
          復制代碼

          3. "async 地獄"

          // 例子 8-5
          
          // bad
          (async () => {
            const getList = await getList();
            const getAnotherList = await getAnotherList();
          })();
          
          // good
          (async () => {
            const listPromise = getList();
            const anotherListPromise = getAnotherList();
            await listPromise;
            await anotherListPromise;
          })();
          
          // good
          (async () => {
            Promise.all([getList(), getAnotherList()]).then(...);
          })();
          復制代碼

          9. Class

          構造函數盡可能使用 Class 的形式

          // 例子 9-1
          
          class Foo {
            static bar () {
              this.baz();
            }
            static baz () {
              console.log('hello');
            }
            baz () {
              console.log('world');
            }
          }
          
          Foo.bar(); // hello
          復制代碼
          // 例子 9-2
          
          class Shape {
            constructor(width, height) {
              this._width = width;
              this._height = height;
            }
            get area() {
              return this._width * this._height;
            }
          }
          
          const square = new Shape(10, 10);
          console.log(square.area);    // 100
          console.log(square._width);  // 10
          復制代碼

          10.Decorator

          1. log

          // 例子 10-1
          
          class Math {
            @log
            add(a, b) {
              return a + b;
            }
          }
          復制代碼

          log 的實現可以參考 《ES6 系列之我們來聊聊裝飾器》

          2. autobind

          // 例子 10-2
          
          class Toggle extends React.Component {
          
            @autobind
            handleClick() {
              console.log(this)
            }
          
            render() {
              return (
                <button onClick={this.handleClick}>
                  button
                </button>
              );
            }
          }
          復制代碼

          autobind 的實現可以參考 《ES6 系列之我們來聊聊裝飾器》

          3. debounce

          // 例子 10-3
          
          class Toggle extends React.Component {
          
            @debounce(500, true)
            handleClick() {
              console.log('toggle')
            }
          
            render() {
              return (
                <button onClick={this.handleClick}>
                  button
                </button>
              );
            }
          }
          復制代碼

          debounce 的實現可以參考 《ES6 系列之我們來聊聊裝飾器》

          4. React 與 Redux

          // 例子 10-4
          
          // good
          class MyReactComponent extends React.Component {}
          
          export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);
          
          // better
          @connect(mapStateToProps, mapDispatchToProps)
          export default class MyReactComponent extends React.Component {};
          復制代碼

          11. 函數

          1. 默認值

          // 例子 11-1
          
          // bad
          function test(quantity) {
            const q = quantity || 1;
          }
          
          // good
          function test(quantity = 1) {
            ...
          }
          
          復制代碼
          // 例子 11-2
          
          doSomething({ foo: 'Hello', bar: 'Hey!', baz: 42 });
          
          // bad
          function doSomething(config) {
            const foo = config.foo !== undefined ? config.foo : 'Hi';
            const bar = config.bar !== undefined ? config.bar : 'Yo!';
            const baz = config.baz !== undefined ? config.baz : 13;
          }
          
          // good
          function doSomething({ foo = 'Hi', bar = 'Yo!', baz = 13 }) {
            ...
          }
          
          // better
          function doSomething({ foo = 'Hi', bar = 'Yo!', baz = 13 } = {}) {
            ...
          }
          復制代碼
          // 例子 11-3
          
          // bad
          const Button = ({className}) => {
          	const classname = className || 'default-size';
          	return <span className={classname}></span>
          };
          
          // good
          const Button = ({className = 'default-size'}) => (
          	<span className={classname}></span>
          );
          
          // better
          const Button = ({className}) =>
          	<span className={className}></span>
          }
          
          Button.defaultProps = {
          	className: 'default-size'
          }
          復制代碼
          // 例子 11-4
          
          const required = () => {throw new Error('Missing parameter')};
          
          const add = (a = required(), b = required()) => a + b;
          
          add(1, 2) // 3
          add(1); // Error: Missing parameter.
          復制代碼

          12. 拓展運算符

          1. arguments 轉數組

          // 例子 12-1
          
          // bad
          function sortNumbers() {
            return Array.prototype.slice.call(arguments).sort();
          }
          
          // good
          const sortNumbers = (...numbers) => numbers.sort();
          復制代碼

          2. 調用參數

          // 例子 12-2
          
          // bad
          Math.max.apply(null, [14, 3, 77])
          
          // good
          Math.max(...[14, 3, 77])
          // 等同于
          Math.max(14, 3, 77);
          復制代碼

          3. 構建對象

          剔除部分屬性,將剩下的屬性構建一個新的對象

          // 例子 12-3
          let [a, b, ...arr] = [1, 2, 3, 4, 5];
          
          const { a, b, ...others } = { a: 1, b: 2, c: 3, d: 4, e: 5 };
          復制代碼

          有條件的構建對象

          // 例子 12-4
          
          // bad
          function pick(data) {
            const { id, name, age} = data
          
            const res = { guid: id }
          
            if (name) {
              res.name = name
            }
            else if (age) {
              res.age = age
            }
          
            return res
          }
          
          // good
          function pick({id, name, age}) {
            return {
              guid: id,
              ...(name && {name}),
              ...(age && {age})
            }
          }
          復制代碼

          合并對象

          // 例子 12-5
          
          let obj1 = { a: 1, b: 2,c: 3 }
          let obj2 = { b: 4, c: 5, d: 6}
          let merged = {...obj1, ...obj2};
          復制代碼

          4. React

          將對象全部傳入組件

          // 例子 12-6
          
          const parmas =  {value1: 1, value2: 2, value3: 3}
          
          <Test {...parmas} />
          復制代碼

          13. 雙冒號運算符

          // 例子 13-1
          
          foo::bar;
          // 等同于
          bar.bind(foo);
          
          foo::bar(...arguments);
          // 等同于
          bar.apply(foo, arguments);
          復制代碼

          如果雙冒號左邊為空,右邊是一個對象的方法,則等于將該方法綁定在該對象上面。

          // 例子 13-2
          
          var method = obj::obj.foo;
          // 等同于
          var method = ::obj.foo;
          
          let log = ::console.log;
          // 等同于
          var log = console.log.bind(console);
          復制代碼

          14. 解構賦值

          1. 對象的基本解構

          // 例子 14-1
          
          componentWillReceiveProps(newProps) {
          	this.setState({
          		active: newProps.active
          	})
          }
          
          componentWillReceiveProps({active}) {
          	this.setState({active})
          }
          復制代碼
          // 例子 14-2
          
          // bad
          handleEvent = () => {
            this.setState({
              data: this.state.data.set("key", "value")
            })
          };
          
          // good
          handleEvent = () => {
            this.setState(({data}) => ({
              data: data.set("key", "value")
            }))
          };
          復制代碼
          // 例子 14-3
          
          Promise.all([Promise.resolve(1), Promise.resolve(2)])
          .then(([x, y]) => {
              console.log(x, y);
          });
          復制代碼

          2. 對象深度解構

          // 例子 14-4
          
          // bad
          function test(fruit) {
            if (fruit && fruit.name)  {
              console.log (fruit.name);
            } else {
              console.log('unknown');
            }
          }
          
          // good
          function test({name} = {}) {
            console.log (name || 'unknown');
          }
          復制代碼
          // 例子 14-5
          
          let obj = {
              a: {
                b: {
                  c: 1
                }
              }
          };
          
          const {a: {b: {c = ''} = ''} = ''} = obj;
          復制代碼

          3. 數組解構

          // 例子 14-6
          
          // bad
          const spliteLocale = locale.splite("-");
          const language = spliteLocale[0];
          const country = spliteLocale[1];
          
          // good
          const [language, country] = locale.splite('-');
          復制代碼

          4. 變量重命名

          // 例子 14-8
          
          let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
          console.log(baz); // "aaa"
          復制代碼

          5. 僅獲取部分屬性

          // 例子 14-9
          
          function test(input) {
            return [left, right, top, bottom];
          }
          const [left, __, top] = test(input);
          
          function test(input) {
            return { left, right, top, bottom };
          }
          const { left, right } = test(input);
          復制代碼

          15. 增強的對象字面量

          // 例子 15-1
          
          // bad
          const something = 'y'
          const x = {
            something: something
          }
          
          // good
          const something = 'y'
          const x = {
            something
          };
          復制代碼

          動態屬性

          // 例子 15-2
          
          const x = {
            ['a' + '_' + 'b']: 'z'
          }
          
          console.log(x.a_b); // z
          復制代碼

          16. 數組的拓展方法

          1. keys

          // 例子 16-1
          
          var arr = ["a", , "c"];
          
          var sparseKeys = Object.keys(arr);
          console.log(sparseKeys); // ['0', '2']
          
          var denseKeys = [...arr.keys()];
          console.log(denseKeys);  // [0, 1, 2]
          復制代碼

          2. entries

          // 例子 16-2
          
          var arr = ["a", "b", "c"];
          var iterator = arr.entries();
          
          for (let e of iterator) {
              console.log(e);
          }
          復制代碼

          3. values

          // 例子 16-3
          
          let arr = ['w', 'y', 'k', 'o', 'p'];
          let eArr = arr.values();
          
          for (let letter of eArr) {
            console.log(letter);
          }
          復制代碼

          4. includes

          // 例子 16-4
          
          // bad
          function test(fruit) {
            if (fruit == 'apple' || fruit == 'strawberry') {
              console.log('red');
            }
          }
          
          // good
          function test(fruit) {
            const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
            if (redFruits.includes(fruit)) {
              console.log('red');
            }
          }
          復制代碼

          5. find

          // 例子 16-5
          
          var inventory = [
              {name: 'apples', quantity: 2},
              {name: 'bananas', quantity: 0},
              {name: 'cherries', quantity: 5}
          ];
          
          function findCherries(fruit) {
              return fruit.name === 'cherries';
          }
          
          console.log(inventory.find(findCherries)); // { name: 'cherries', quantity: 5 }
          復制代碼

          6. findIndex

          // 例子 16-6
          
          function isPrime(element, index, array) {
            var start = 2;
            while (start <= Math.sqrt(element)) {
              if (element % start++ < 1) {
                return false;
              }
            }
            return element > 1;
          }
          
          console.log([4, 6, 8, 12].findIndex(isPrime)); // -1, not found
          console.log([4, 6, 7, 12].findIndex(isPrime)); // 2
          復制代碼

          更多的就不列舉了。

          17. optional-chaining

          舉個例子:

          // 例子 17-1
          
          const obj = {
            foo: {
              bar: {
                baz: 42,
              },
            },
          };
          
          const baz = obj?.foo?.bar?.baz; // 42
          復制代碼

          同樣支持函數:

          // 例子 17-2
          
          function test() {
            return 42;
          }
          test?.(); // 42
          
          exists?.(); // undefined
          復制代碼

          需要添加 @babel/plugin-proposal-optional-chaining 插件支持

          18. logical-assignment-operators

          // 例子 18-1
          
          a ||= b;
          
          obj.a.b ||= c;
          
          a &&= b;
          
          obj.a.b &&= c;
          復制代碼

          Babel 編譯為:

          var _obj$a, _obj$a2;
          
          a || (a = b);
          
          (_obj$a = obj.a).b || (_obj$a.b = c);
          
          a && (a = b);
          
          (_obj$a2 = obj.a).b && (_obj$a2.b = c);
          復制代碼

          出現的原因:

          // 例子 18-2
          
          function example(a = b) {
            // a 必須是 undefined
            if (!a) {
              a = b;
            }
          }
          
          function numeric(a = b) {
            // a 必須是 null 或者 undefined
            if (a == null) {
              a = b;
            }
          }
          
          // a 可以是任何 falsy 的值
          function example(a = b) {
            // 可以,但是一定會觸發 setter
            a = a || b;
          
            // 不會觸發 setter,但可能會導致 lint error
            a || (a = b);
          
            // 就有人提出了這種寫法:
            a ||= b;
          }
          復制代碼

          需要 @babel/plugin-proposal-logical-assignment-operators 插件支持

          19. nullish-coalescing-operator

          a ?? b
          
          // 相當于
          
          (a !== null && a !== void 0) ? a : b
          復制代碼

          舉個例子:

          var foo = object.foo ?? "default";
          
          // 相當于
          
          var foo = (object.foo != null) ? object.foo : "default";
          復制代碼

          需要 @babel/plugin-proposal-nullish-coalescing-operator 插件支持

          20. pipeline-operator

          const double = (n) => n * 2;
          const increment = (n) => n + 1;
          
          // 沒有用管道操作符
          double(increment(double(5))); // 22
          
          // 用上管道操作符之后
          5 |> double |> increment |> double; // 22
          復制代碼

          其他

          新開了 知乎專欄,大家可以在更多的平臺上看到我的文章,歡迎關注哦~

          參考

          1. ES6 實踐規范
          2. babel 7 簡單升級指南
          3. 不得不知的 ES6 小技巧
          4. 深入解析 ES6:Symbol
          5. 什么時候你不能使用箭頭函數?
          6. 一些使 JavaScript 更加簡潔的小技巧
          7. 幾分鐘內提升技能的 8 個 JavaScript 方法
          8. [譯] 如何使用 JavaScript ES6 有條件地構造對象
          9. 5 個技巧讓你更好的編寫 JavaScript(ES6) 中條件語句
          10. ES6 帶來的重大特性 – JavaScript 完全手冊(2018版)

          ES6 系列

          ES6 系列目錄地址:https://github.com/mqyqingfeng/Blog

          ES6 系列預計寫二十篇左右,旨在加深 ES6 部分知識點的理解,重點講解塊級作用域、標簽模板、箭頭函數、Symbol、Set、Map 以及 Promise 的模擬實現、模塊加載方案、異步處理等內容。

          如果有錯誤或者不嚴謹的地方,請務必給予指正,十分感謝。如果喜歡或者有所啟發,歡迎 star,對作者也是一種鼓勵。


          原鏈接:https://juejin.im/post/5bfe05505188252098022400


          主站蜘蛛池模板: 丝袜美腿一区二区三区| 无码日韩人妻av一区免费| 99久久精品午夜一区二区| 国产一区二区三区在线| 亚拍精品一区二区三区| 丰满人妻一区二区三区视频53 | 肥臀熟女一区二区三区 | a级午夜毛片免费一区二区| 国产在线精品一区二区中文| 中文字幕精品一区二区日本| 成人欧美一区二区三区在线视频| 国产一区二区在线|播放| 国产在线不卡一区二区三区| 亚洲乱码一区av春药高潮| 免费萌白酱国产一区二区| 国产一区二区在线视频| AV天堂午夜精品一区二区三区| 人成精品视频三区二区一区 | 无码国产精品一区二区免费式影视 | 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 毛片一区二区三区| 中文字幕乱码人妻一区二区三区| 日本免费一区二区三区四区五六区| 日本一区二区三区高清| 亚洲永久无码3D动漫一区| 亚洲成AV人片一区二区| 日韩精品无码免费一区二区三区| 亚洲日本乱码一区二区在线二产线| 久久一区二区明星换脸| 精品国产一区二区三区四区| 国产乱码一区二区三区| 亚洲国产欧美日韩精品一区二区三区 | 精品一区二区三区AV天堂| 福利视频一区二区牛牛| 国产av天堂一区二区三区| 国产免费一区二区视频| 骚片AV蜜桃精品一区| 中文字幕精品一区二区| 香蕉久久AⅤ一区二区三区| 日本一区二区三区在线观看| 亚洲国产成人精品无码一区二区 |