美文网首页H5前端技术分享
重读《学习JavaScript数据结构与算法-第三版》-第2章

重读《学习JavaScript数据结构与算法-第三版》-第2章

作者: 胡哥有话说 | 来源:发表于2019-08-12 20:45 被阅读14次

    定场诗

    八月中秋白露,路上行人凄凉;

    小桥流水桂花香,日夜千思万想。

    心中不得宁静,清早览罢文章,

    十年寒苦在书房,方显才高志广。

    前言

    洛伊安妮·格罗纳女士所著的《学习JavaScript数据结构与算法》第三版于2019年的5月份再次刊印发行,新版内容契合当下,实为JavaScript开发人员的必备之佳作。有幸重读此版,与诸君分享共勉。

    内容提要

    此章节为第2章-ECMAScript与TypeScript概述,主要介绍了JS和TS的相关概念,以及在JS新版本中的新特性:let、解构、箭头函数等。

    2.1 ECMAScript还是JavaScript

    ECMA是一个将信息标准化的组织。ECMAScript是一个语言的标准,而JavaScript是该标准(最流行)的一个实现。

    或恰如:ECMAScript是JS身份证上的名字(标准),JavaScript是常用的称呼(常见、亲切)。

    JS的版本问题

    版本 简称 发布时间 备注
    ECMAScript5 ES5 2009年12月
    ECMAScript2015 ES6 2015年6月 ECMAScript规范委员会决定每年更新标准一次,js的标准称呼为:ECMAScript+年份
    ECMAScript2016 ES7 2016年6月 ECMAScript第7个版本
    ECMAScript2017 ES8 2017年6月 ECMAScript第8个版本
    ES.NEXT 泛指下一个版本的ECMAScript

    JS版本的兼容性问题

    一定要明白,即便ES2015到ES2017已经发布,但不是所有的浏览器都支持新特性。

    1. 使用最新版的浏览器进行体验

    2. 使用Babel.js对使用ECMAScript新语言特性的JavaScript代码转换成只使用广泛支持的ES5特性的等价代码

      Babel.js是一个JavaScript的转译器,具体使用文档:官网-传送门 Babel.js中文网

    2.2 ES6+的新功能

    let和const定义变量

    1. 不存在变量提升

      console.log(a) // ReferenceError: Cannot access 'a' before initialization
      let a = 10
      
    2. 不允许重复声明定义变量

      let a = 10
      let a = 20  // SyntaxError: Identifier 'a' has already been declared
      
    3. 变量作用域

      块状作用域 {}

      if (true) {
        const b = 10
      }
      console.log(b) // ReferenceError: b is not defined
      

    let和const到底选择谁?

    const与let的行为是一样的,唯一的区别在于,使用const定义的变量是只读的,也就是常量。

    const保证的其实并不是变量的值不能改动,而是变量指向的内存地址所保存的数据不得改动。

    扩展:基本类型值和引用类型值

    每一个变量都指向了一个内存地址。

    基本类型值:指向了一个内存地址,变量的值就存储在改内存内置中。

    引用类型值:指向了一个内存地址,该内存地址中存储的是一个指针,一个指向实际数据的指针。

    const保证的是这个指针是固定的,总是指向另一个固定地址;但实际上指针指向的数据结构是否可变,则不能控制。

    模板字面量

    模板字面量语法``提供了很大的帮助,支持JS书写时换行,可定义多行字符串;使用${}插入变量的值。

    let person = {
      name: '王二狗',
      age: 18
    }
    
    let str = `给你介绍个人:
    这个人的名字是${person.name}
    `
    console.log(str)
    

    箭头函数

    箭头函数 () => {} 简化了函数语法

    let f = () => {
      console.log('我是箭头函数....')
    }
    f()
    
    // 简化return关键字
    let sum = (a, b) => a+b
    sum(1, 2)
    
    

    函数参数默认值

    支持定义函数参数的默认值

    function sum (x = 1, y = 2, z = 3) {
      return x + y + z
    }
    

    声明展开与剩余参数

    展开运算符... 将对象或数组展开为一层,亦可当做剩余参数

    let p = {
      name: '人',
      age: 20,
      sex: '男'
    }
    let wangErGou = {
      ...p,
      name: '王二狗'
    }
    console.log(wangErGou)
    
    // 剩余参数
    function sum (x, y, ...a) {
      return x * y * a.length
    }
    sum(1, 2, 2, 'abc', true) // 6 等同于a是数组[2, 'abc', true]
    

    解构

    数组与对象解构

    let [x, y] = [10, 20]
    console.log(x, y) // 10, 20
    
    let {age, name} = {
      name: '李四',
      age: 20
    }
    console.log(name, age) // 李四, 20
    

    数组解构中许注意顺序,对象解构中无需注意顺序;解构中无对应的值,则改值为undefined

    解构应用

    1. 交换变量值
    let x = 10
    let y = 20
    [y, x] = [x, y]
    
    1. 属性简写
    let x = 10
    let y = 10
    let obj = {x, y} // 相当于 {x: x, y: y}
    

    简写方法名

    对象中的方法名可简写

    let obj = {
      name: '王二狗',
      print () {
        console.log(this.name)
      }
    } 
    

    使用类进行面向对象编程

    定义

    class Book {
      constructor (title, author, isbn) {
        this.title = title
        this.author = author
        this.isbn = isbn
      }
      printIsbn () {
        console.log(this.isbn)
      }
    }
    let book = new Book('郭德纲相声选', '郭德纲', '00111011')
    book.printIsbn()
    

    继承

    class ITBook extends Book {
      constructor (title, author, isbn, technology) {
        // 代表调用父类构造函数
        super(title, author, isbn)
        this.technology = technology
      }
      printTechnology () {
        console.log(this.technology)
      }
    }
    let jsBook = new ITBook('JS数据结构与算法', 'Groner', '123456789', 'JavaScript')
    jsBook.printIsbn()
    jsBook.printTechnology()
    

    乘方运算符

    let r = 2
    let area = Math.PI * r ** 2
    console.log(area)
    

    模块

    1. CommonJS规范是服务器端模块化开发规范,使用require方法加载;
    2. AMD(Asynchronous Module Definition) 异步模块定义,RequireJS是AMD最流行的实现,是浏览器端模块化开发规范;
    3. CMD(Common Module Definition) 通用模块定义,SeaJS是CMD的流行实现,是浏览器端模块化开发规范

    ES6模块化开发

    export 导出模块;import 导入模块

    // moduleA.js
    export const moduleA = 'moduleA'
    
    // html中引入,注意type="module"
    <script type="module">
      import { moduleA } from './moduleA.js'
      console.log(moduleA)
    </script>
    

    2.3 介绍TypeScript

    TypeScript是一个开源的、渐进式包含类型的JavaScript超集,由微软创建并维护。目的是让开发者增强JavaScript的能力并使应用的规模扩展变得更容易。

    TS在JavaScript中提供类型支持可以实现静态检查,从而更容易地重构代码和寻找BUG。最后,TypeScript为被编译为简单的JavaScript代码。

    编写时为.ts文件,使用TypeScript对其进行tsc编译,最终为js文件

    下载TypeScript

    npm i -g typescript
    

    创建.ts文件,写入内容

    // demo.ts
    let a = '初始化为字符串内容'
    a = 10
    console.log(a)
    

    编译ts文件

    tsc demo.ts
    

    此处回生成demo.js文件,同时控制台报警告信息:error TS2322: Type '10' is not assignable to type 'string'. 说明TS对变量类型进行了校验,但并未阻止编译器生成最终的js代码。

    TS类型推断

    // 定义变量,并约束变量类型
    let age: number = 20
    let flag: Boolean = true
    

    TS允许我们给变量设置一个类型,但是此种写法太麻烦。TS提供了便捷的类型推断机制,相当于在给变量赋初始值时就约束了变量的类型。

    // 上面的代码改造
    let age = 20 // 数值类型
    let flag = true // 布尔值类型
    

    那么,什么时候需要给变量设置类型呢?声明变量,但没有设置其初始值的时候!

    如果没有给变量设置类型,那么它的类型会被自动设置为any,意思为接受任何类型的值。

    接口

    在TS中,有两种接口概念:

    第一种:给变量设置类型,是对一个对象必须包含的属性和方法的描述

    interface Person {
      age: number,
      name: string
    }
    
    function printName (person: Person) {
      console.log(person.name)
    }
    
    const john = {
      name: 'john',
      age: 21
    }
    const mary = {
      name: 'mary',
      age: 20,
      phone: '123456'
    }
    
    printName(john)
    printName(mary)
    

    执行tsc编译,木有任何问题。但是小伙伴可能会比较奇怪,对象mary中属性多了个phone,但是并未影响代码的执行。

    鸭子类型概念:如果它看起来像鸭子,像鸭子一样游泳,像鸭子一样叫,那么它一定是一只鸭子!

    变量mary的行为与Person接口定义的一样,那么它就是一个Person。

    第二种:TS接口的概念和面向对象编程相关

    接口视为一份合约,在合约里可以定义这份合约的类或接口的行为

    interface Comparable {
      compareTo (b): number
    }
    
    class myObject implements Comparable {
      age: number
      compareTo(b): number {
        if (this.age === b.age) {
          return 0
        }
        return this.age > b.age ? 1 : -1
      }
    }
    
    let obj = new MyObject()
    obj.age = 10
    let res = obj.compareTo(20)
    console.log(res) // -1
    

    Comparable接口告诉MyObject类,它需要实现一个叫做compareTo的方法,并且该方法接收一个参数。

    泛型

    对数据结构和算法作用强大的TS特性是泛型这一概念

    interface Comparable<T> {
      compareTo (b: T): number
    }
    
    class MyObject implements Comparable<MyObject> {
      age: number
      compareTo(b: MyObject): number {
        if (this.age === b.age) {
          return 0
        }
        return this.age > b.age ? 1 : -1
      }
    }
    
    let obj = new MyObject()
    obj.age = 10
    let obj2 = new MyObject()
    obj2.age = 20
    let res = obj.compareTo(obj2)
    console.log(res) // -1
    

    后记

    以上就是胡哥今天给大家分享的内容,喜欢的小伙伴记得收藏转发、点击右下角按钮在看,推荐给更多小伙伴呦,欢迎多多留言交流...

    胡哥有话说,一个有技术,有情怀的胡哥!京东开放平台首席前端攻城狮。与你一起聊聊大前端,分享前端系统架构,框架实现原理,最新最高效的技术实践!

    长按扫码关注,更帅更漂亮呦!关注胡哥有话说公众号,可与胡哥继续深入交流呦!

    胡哥有话说

    相关文章

      网友评论

        本文标题:重读《学习JavaScript数据结构与算法-第三版》-第2章

        本文链接:https://www.haomeiwen.com/subject/rmnujctx.html