前端培训初级阶段13-类模块继承

10次阅读

共计 3950 个字符,预计需要花费 10 分钟才能阅读完成。

前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思想,我们开课啦(每周四)。

该文为前端培训 - 初级阶段(13、18)的补充内容 (介绍了 ECMAScript 历史,ES6 常用点)。

本文介绍ECMAScript 基础知识

  1. 前端培训 - 初级阶段(13)– ECMAScript(语法、变量、值、类型、运算符、语句)
  2. 前端培训 - 初级阶段(13)– ECMAScript(内置对象、函数)

基础内容知识我们会用到。默认已读。

我们要讲什么

  • js 中的类
  • js 中的模块
  • js 中的继承实现

在 JavaScript 中,类的实现是基于原型继承机制的。如果两个实例都从同一个原型对象上继承了属性,我们说它们是同一个类的实例。
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念。通过 class 关键字,可以定义类。
ES6 的 Class 可以看作是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。。

class Logger {constructor(wigName) {this.wigName = wigName;}

  warn(info) {return console.log(`${this.wigName}-${info}`)
  }
}
logger = new Logger('lilnong.top')
logger.warn('404')
//ES5 中怎么写
function Logger(wigName){this.wigName = wigName;}
Logger.prototype.warn = function(info){return console.log(`${this.wigName}-${info}`)
}
logger = new Logger('lilnong.top-ES5')
logger.warn('404')

如图 ES6 其实也还是在 prototype

ES6 的 Class 还有一些特殊的功能,比如必须通过 new 来实例化。那么我们的 ES5 怎么来实现这个功能?(话说 ES6 怎么在低版本实现可以去在线 babel)

  1. function fun(){console.log(new.target)};console.log(fun(),new fun())通过新加的 new.target来区分。
  2. function fun(){console.log(this instanceof fun)};console.log(fun(),new fun())这个方法就是通过 new 的特性是判断,面试题new 的时候系统做了几步操作

    1. 创建一个空对象
    2. 空对象绑在 this 上
    3. 然后调用

模块

历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的 require、Python 的 import,甚至就连 CSS 都有 @import,但是 JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。
在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。

// CommonJS 模块
let {stat, exists, readFile} = require('fs');

// ES6 模块
export {stat, exists, readFile};
import {stat, exists, readFile} from 'fs';

ES6 的模块功能主要由两个命令构成:exportimport。export 命令用于规定模块的对外接口,import 命令用于输入其他模块提供的功能。 当然现在浏览器还不支持

模块规范(CommonJSAMDCMDUMD)

  1. CommonJS(NodeJS)
    require 引入模块是同步的, 但 script 标签引入 JS 是异步的, 因此 CommonJS 在浏览器环境下无法正常加载(无法处理依赖问题)。

       // 模块定义 myModule.js
       var name = 'Byron';
       function printName(){console.log(name);
       }
       module.exports = {printName: printName,}
       // 加载模块
       var myModule = require('./myModule.js');
       myModule.printName();
  2. AMD(RequireJS)
    AMD: Asynchronous Module Definition(异步模块定义)。AMD 模块中所有的依赖都前置,require 指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。

       // 定义模块 myModule.js
       //define([依赖的模块],定义模块的代码)
       define(function(){
           var name = 'Byron';
           function printName(){console.log(name);
           }
           return {printName: printName};
       });
       
       // 加载模块
       //require([依赖的模块],callback(依赖名))
       
       require(['myModule.js'], function (myModule){myModule.printName();
       });
  3. CMD(SeaJS)
    CMD: Common Module Definition(通用模块定义), 推崇依赖就近原则(也就是懒加载), 模块内部的依赖在需要引入的时候再引入.

    // 定义模块  myModule.js
    define(function(require, exports, module) {var $ = require('jquery.js');
      var foo = require('foo');
      var out = foo.bar();
      $('div').addClass('active');
      module.exports = out;
    });
    
    // 加载模块
    seajs.use(['myModule.js'], function(myModule){});
  4. UMD
    UMD: 兼容 AMD、CMD 和 commonJS 规范的同时,还兼容全局引用的方式 例子:

       //moduleName.js
       ;(function (global) {function factory () {var moduleName = {};
               return moduleName;
           }
           //CommonJS
           if (typeof module !== 'undefined' && typeof exports === 'object') {module.exports = factory();
           } else if (typeof define === 'function' && (define.cmd || define.amd)) { //AMD || CMD
               define(factory);
           } else { //script 标签
               global.moduleName = factory();}
       })(typeof window !== 'undefined' ? window : global);
       UMD 模块在不同环境引入:
       
       // Node.js
       var myModule = require('moduleName');
       // SeaJs
       define(function (require, exports, module) {var myModule = require('moduleName');
       });
       // RequireJs
       define(['moduleName'], function (moduleName) {});
       // Browse global
       <script src="moduleName.js"></script>
  5. ES6 模块(import,export)
    可以取代 CommonJS 和 AMD 规范, 是浏览器和服务器通用的模块解决方案。

       // 模块定义 myModule.js
       var name = 'Byron';
       function printName(){console.log(name);
       }
       const myModule = {printName: printName,};
       export myModule;
       
       // 加载模块
       import myModule from './myModule.js';
       myModule.printName();

继承

js 中的继承依赖于 原型链继承

function Fun(){};// 声明一个方法
Fun.prototype.toAuthor = ()=>console.log('linong');// 在他的原型上绑定一个方法
var fun = new Fun();// 实例化一下
fun.toAuthor()// 调用方法,fun.toAuthor = ()=>console.log('lilnong.top');// 覆盖这个方法
fun.toAuthor();// 调用,这个时候在自己这里找到了,就不会去调用原型上的方法了

fun.__proto__ == Fun.prototype // 实例上是__proto__,构造函数上是 prototype

后记

主讲人文章 -2019.04.11

参考文献

  1. ECMAScript 6 入门
正文完
 0