1. 现代 javascript 用法

Posted zonehoo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1. 现代 javascript 用法相关的知识,希望对你有一定的参考价值。

简介

  包含 ECMAScript 基本概念,babel 使用 ,eslint 使用 以及新语法的介绍 和使用经验

 

ECMAScript 概念

  ECMASctipt 是一种由 Ecma (前身为欧洲计算机执照协会)通过 ECMA-262 标准化的脚本程序设计语言。这种语言在 万维网 上应用广泛, 它往往被成为 javascript 或者 JScript, 但实际上后后两者是 ECMA-262 标准的实现和 拓展

 

ES6 、 ES2015 是什么

  ES6的第一个版本, 在2015年6月发布, 正式名称就是《ECMAScript 2015标准》(简称 ES2015)

  2016年6月, 小幅修订的《ECMAScript 2016标准》(简称 ES2016)发布, 这个版本可以看作是 ES6.1 版

  ES6 既是一个历史名词, 也是一个泛指, 含义是5.1版以后的JavaScript的下一代标准, 涵盖了ES2015、ES2016、ES2017等等

 

tc39 是 什么 (官网

介绍

任何人都可以向标准委员会(又称TC39委员会)提案, 要求修改语言标准.

一种新的语法从提案到变成正式标准, 需要经历五个阶段. 每个阶段的变动都需要由 TC39 委员会批准.

Stage 0 - Strawman(展示阶段)
Stage 1 - Proposal(征求意见阶段)
Stage 2 - Draft(草案阶段)
Stage 3 - Candidate(候选人阶段)
Stage 4 - Finished(定案阶段)

一个提案只要能进入 Stage 2, 就差不多肯定会包括在以后的正式标准里面.

 

babel 基本概念  (官网)

  babel 是什么?

  将语法转换为 ES5 老语法的 转译器 (transpiler)

  相关模块

    babel-core: babel的核心

    babel-cli: babel的命令行工具

    babel-plugin: 语法插件

    babel-preset: 语法插件的集合(语法的集合就是语言的版本)

  babel 安装

    npm i babel-cli -g

  基本使用

    npm i 

    babel es6.js

    #es6.js 文件内容

    const log = (...params) => console.log(...params)

    export default log

 

babel-preset-env (强烈推荐)  (资料)

  好处

    根据配置可以生成兼容不同版本浏览器或者node环境的代码

    可转译所有的新语法,也可以根据环境的兼容性,不转译某些语法

 

babel 配置文件

  babel 使用的 配置文件

    babel-cli 默认使用 当前目录下的.babelrc 文件作为配置文件,采用json格式

  babel 不使用 配置文件

    使用--no-babelrc选项可以让babel-cli不是用配置文件, 此时需要使用命令行参数配置babel-cli

  #案例

 "presets": [ [ "env",  "targets":  "browsers": ["last 2 versions", "ie >= 10"] , "debug": false ] ], "plugins": [ "transform-class-properties", "transform-decorators-legacy", [ "transform-react-jsx",  "pragma": "React.createElement" ], [ "transform-runtime",  "helpers": true, "polyfill": true, "regenerator": true, "moduleName": "babel-runtime" ] ]

  

babel 两个插件

  polyfill 和 transform-runtime

    babel-polyfill   (在 window 对象内加 一些 ES5 特性 然后进行转换)

  先于业务代码加载到浏览器中的一段脚本, 用ES5实现的版本, 补充浏览器中缺乏的全局对象/类型/函数等新特性

    babel-plugin-transform-runtime (按需加载 没有定义的语法)

   babel-polyfill很大.

  不想污染全局, 比如不想在window添加字段.

  在babel转译过程中, 在使用了新特性的代码文件头部添加require语句, 将ES5实现版本引用到业务代码中. 使用什么特性, 就引用什么, 并且不会污染全局.

 

常用新语法

  let 和 const

  为了规避 var 关键字的"变量作用域的提升"问题而产生的定义变量语法

    let obj =   # 可变的对象

    const obj =   # 不可变的对象

    什么是作用域提升?let定义的变量, 其作用域与用var定义的变量有什么区别?

    使用 var 定义在 function 内定义之后

      会先定义 var 然后 再 赋值

      eg:

      function fn()

        if(1) var a = 12345

        console.log( a ); #12345

      

      等价于

      function fn()

        var a ; 

        if(1) a = 12345

        console.log( a ); #12345

      

       故会提升变量的作用域 所以 const 或者 let 会报错 指明了作用域的范围

    闭包传递时, 与用var定义的变量有什么区别?

      闭包 传值时  使用 var 定义 的使用 引用传递

            使用 let 定义 的使用 值传递

      eg:

      //for(var i = 0; i < 10; i++)

      for(let i = 0; i < 10; i++)

        setTimeout(function()

          console.log( i ); # var : 10 10 10 ...    let: 0 1 2 3 ...

        );

      

    const到底指的是谁不能变?

      const obj = ;

      obj = 1;  # 直接 改变 obj 的指向 会报错

      obj.a = 1;    #  添加属性不会报错

 

  解构赋值  解决多个变量赋值的问题

    eg: const obj = a:1, b:2

      const a:x,b = obj;

      console.log(a,b);

    eg: const [a , b] = [1 , 2]

      console.log(a , b);

  

  模版字符串

    不要再用 "+" 号组合字符串

    eg:

      const foo = ‘3‘;

      // const bar = foo + 2 + 1   # 321

      const bar = `$(foo)$(2+1)`; # 33

      console.log(bar)

  正则表达式的s修饰符

    正则表达式中的 "." 不能匹配换行符 使用 s 修饰符之后 "." 可以匹配换行符

    eg: const str = "Hello

             world!";

      const reg1 = /Hello.+world!/

      const reg2 = /Hello.+world!/s

      console.log(reg1.test(str));

      console.log(reg2.test(str));

  isFinite 和 isNaN

    isFinite 判断是不是 有限数值

      eg: Number.isFinite(1); 

    isNaN 判断是不是 NaN (not a number)

      eg: Number.isNaN(1);

 

  isSafeInteger

    JavaScript 能够准确表示的整数范围在 -2^53 到 2^53 之间(不含两个断电), 超过 这个范围, 无法精确表示这个值 isSafeInteger

    Number.MIN_SAFE_INTEGER

    Number.MAX_SAFE_INTEGER

    eg: Number.isSafeInteger(1)   // true

 

  Object 专题

    属性简介表示

      老语法

        const foo = 1

        const bar = 2

        const obj = foo : foo, bar: bar

      新语法

        const foo = 1

        const bar = 2

        const obj = foo ,bar

 

    属性名表达式 (将对象的属性的值 做为 另外一个对象的 属性)

      老语法

        function fn(foo, bar)

          const ret =

          ret[foo] = ‘foo‘

          ret[bar] = ‘bar‘

        

      新语法

        function fn(foo, bar)

          return

            [foo]: ‘foo‘,

            [bar]: ‘bar‘

          

        

    函数的 name 属性

      function 对象的 name 属性 , 可以获得函数名

      应用于: 调试工具, 日志打印等

      eg:  查看函数什么时候调用

        function foobar()

          return

        

        function invoke(fn)

          console.log( fn.name );

          return fn();

        

        invoke(foobar)

    Object.is

      is 是一种新的相等算法的实现

      == 和 === 的缺点

        == 会自动转换类型  [1] 和 "1" 相等

        === 不认为 NaN 和 NaN 相等, +0 和 -0 相等

      要点: Same-value equality (同值相等)

    Object.assign

      assgin 可以用来浅复制 或者 浅合并对象

      要点: 什么是‘浅‘?, 什么是‘深‘?

        浅复制:只对对象第一层的属性进行遍历, 然后把值复制上去

        深复制:复制的对象内的属性为对象时,直接复制 原对象的指针

      面试题: 如何拷贝一个对象?

      const foo = a: 1, b: 2

      const fee = c: 3, d: z:2 

      const check =  c: 3, d: z:2 

 

      // 复制

      const bar = Object.assign(, foo)  // a: 1, b: 2

       // 合并

      const baz = Object.assign(, foo, fee)  // a: 1, b: 2, c: 3, d: z:2 

      console.log( fee.d === baz.d ) // true  表示指向同一个指针

      console.log( check.d === baz.d ) // false  表示不指向同一个指针

 

    __proto__

      __proto__ 是指向对象原型的指针,只有浏览器承诺支持,其他环境不一定,建议不要直接使用

      相关知识点:

        Object.setPrototypeOf() 和 Object.getPrototype()

      拓展

        原型链

技术图片

 

 

    keys , values, entries

      keys 用来找到找到对象自身可枚举的属性名 ( 不包含 用 Object.setPrototypeof(obj, a:a) 设置在原型上的属性);

      values 用来找到找到对象自身可枚举的属性值

      entries 把对象转化为 key-value 的 数组

      拓展

        各种循环遍历对象的方法

         //打印 可枚举属性  自身具有的属性

          const obj = a:1, b:2, c:3

          Object.setPrototypeOf(obj, x:‘x‘)

            Object.keys(obj).forEach((ky)=> console.log(ky); ) // a b c

          Object.values(val).forEach((val)=> console.log(val); ) // 1 2 3

          Object.entries(obj).forEach((obj)=> console.log(obj); ) // [a,1] [b,2]

    getOwnPropertyDescriptor

      对象的每个属性都有一个描述对象(Descriptor), 用来控制该属性的行为, Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象

      拓展  可枚举性

        对象字段的enumerable属性, 称为"可枚举性",如果该属性为false,就表示某些操作会忽略当前属性

        1 . for...in循环 :  只遍历对象自身和继承的可枚举的属性

        2 . Object.kes() : 返回对象自身的所有可枚举的属性的键名

        3. JSON.stringify : 只串行化对象自身的可枚举的属性

        4. Object.assign() : 忽略不可枚举的属性, 只拷贝对象自身可枚举的属性

      eg:   定义为  不可枚举 不遍历出  不限时追加的自定义的属性

        const a = [1 ,2 ,3];

        // 获取 a 的 enumerable 的 值  Object.getOwnPropertyDescriptor(a, sum);

        Object.defineProperty(a, ‘sum‘,

          value: function() return 6 ,

          enumerable: false

        )

        for(let key in a)

          console.log(key);

        

    展开运算符

      使用 ... 符号, 可以将对象"展开"

        eg:

        1 . foo = a: 1, b: 2

          bar = ...foo, c: 3

          console.log(bar)  //a: 1, b: 2, c:3

          // 其中  ...foo  等价于  Object.keys(foo).forEach((key)=>bar[key] = foo[key])

        

 

以上是关于1. 现代 javascript 用法的主要内容,如果未能解决你的问题,请参考以下文章

现代化 JavaScript 框架 Mithril 的简单介绍及用法

js基础

一文道尽JavaScript 20年的发展史

javasc面向对象编程

15分钟学会Webpack

Themeleaf用法——Themeleaf简介