zoukankan      html  css  js  c++  java
  • 入门到放弃:理清前端技术概念

    什么是JavaScript

    JavaScript是一种脚本语言,1995年时,由Netscape公司在网景导航者浏览器上实现。浏览器内置JavaScript引擎来解释执行,用来给网页增加动态功能。Netscape希望它看起来像Java,因此取名为JavaScript,实际上毫无共通之处。Java和JavaScript的关系,就好比“老婆”和“老婆饼”的关系。

    什么是ECMAScript

    由于微软等公司也推出浏览器上运行的脚本语言进行竞争,1996 年Netscape 公司决定将 JavaScript 提交给标准化组织 ECMA(“European Computer Manufacturers Association”,欧洲计算机制造商协会),希望这种语言能够成为国际标准。次年,ECMA 基于JavaScript发布ECMA-262标准文件第一版,即ECMAScript 1.0 。为体现开放性和中立性,并避免侵犯Sun公司的商标权,该标准被称为ECMAScript而非JavaScript。

    ECMAScript 和 JavaScript 的关系

    ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的实现之一。通常下这两个词是可以互换。

    ECMAScript 1.0 是 1997 年发布的,接下来的两年,连续发布了 ECMAScript 2.0(1998 年 6 月)和 ECMAScript 3.0(1999 年 12 月)。3.0 版在业界得到广泛支持,成为通行标准,奠定了 JavaScript 语言的基本语法并得到完全继承。今天学习 JavaScript,其实就是在学 3.0 版的语法。

    什么是ES5

    2009 年 12 月,ECMAScript 5.0 版(ES5)正式发布,2011 年 6 月,ECMAScript 5.1 版发布,并且成为 ISO 国际标准(ISO/IEC 16262:2011)。ES5 与 ES3 基本保持兼容。

    什么是ES6

    ES6即ECMAScript 6.0,是 2015 年 6 月正式发布JavaScript 语言标准,是继ES5之后的一次主要改进,增添了许多必要的特性,例如:模块和类,并且完全兼容以前的版本。目标是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

    参考: https://es6.ruanyifeng.com

    ES6 与 ECMAScript 2015 的关系

    ES6 和 ES2015 实际上是同一个东西。 由于技术委员会规定ECMAScript 必须做到每年做一次更新。由此,这个版本被更名为 ES 2015,此后新版本(从 2015 年起) ES 命名也都是是根据年份来算的: ES2015、 ES2016、 ES2017... 目前最新的草稿已经到了ES2021( https://tc39.es/ecma262/

    什么是Node.js

    最初JavaScript只能运行于客户端的浏览器,依赖于浏览器上的引擎。2009年5月,Ryan Dahl发布了Node.js平台,对谷歌的Chrome V8引擎进行了封装,从而使JavaScript可以脱离浏览器,独立运行于服务端。

    实质是:Node.js 是 JavaScript 的服务器运行环境(runtime),并且它对 ES6 的支持度很高。

    什么是模块化

    模块化是指把一个复杂的系统分解到一个一个的模块

    模块化开发的优点

    (1)代码复用,让我们更方便地进行代码管理、同时也便于后面代码的修改和维护。

    (2)一个单独的文件就是一个模块,是一个单独的作用域,只向外暴露特定的变量和函数。这样可以避免污染全局变量,减少变量命名冲突。

    早期的JavaScript缺乏对模块化的支持,后来发展出来的js模块化规范有:CommonJS、AMD、CMD、ES6的模块系统。

    参考来源:https://zhuanlan.zhihu.com/p/53125734

    什么是CommonJS模块化

    服务器端模块的规范,由Node.js推广使用。该规范的核心思想是:允许模块通过require方法来同步加载所要依赖的其他模块,然后通过 exports 或module.exports 来导出需要暴露的接口。

    实例:

    //math.js
    var num = 0;
    function add(a, b) {
    return a + b;
    }
    module.exports = {
    //需要向外暴露的变量、函数
    num: num,
    add: add
    }

    可以这样加载:

    //引入自定义的模块时,参数包含路径,可省略.js
    //引入核心模块时,不需要带路径,如var http = require("http");
    var math = require('./math');
    math.add(1, 2)//3

    实际上,从上面的例子就可以看出,math.add(1,2)必须要等待math.js加载完成,即require是同步的。

    什么是AMD模块化

    AMD:异步模块定义。上面已经介绍过,CommonJS是服务器端模块的规范,主要是为了JS在后端的表现制定的,不太适合前端。而AMD就是要为前端JS的表现制定规范。由于不是JavaScript原生支持,使用AMD规范进行页面开发需要用到对应的库函数,也就是require.js(还有个js库:curl.js)。实际上AMD 是 require.js在推广过程中对模块定义的规范化的产出。

    math.js定义一个模块:

    define('math', ['jquery'], function (jquery) {//引入jQuery模块
    return {
    add: function (x, y) {
    return x + y;
    }
    };
    });

    导入和使用:

    require(['math'], function (math) {
    math.add(1, 2)
    })

    math.add()与加载math模块不是同步的,不会阻塞浏览器的加载。

    什么是CMD模块化

    CMD:通用模块定义。

    国内的玉伯大佬写了sea.js,实际上CMD就是 sea.js在推广过程中对模块定义的规范化的产出。

    define(function (require, exports, module) {
    // 模块代码
    });

    说明:

    require:可以把其他模块导入进来的一个参数;

    exports:可以把模块内的一些属性和方法导出的;

    module: 是一个对象,上面存储了与当前模块相关联的一些属性和方法。

    上面示例中的代码改写成CMD形式:

    define(function (require, exports, module) {
    var add = function (a, b) {
    return a + b;
    }
    exports.add = add;
    })
    //导入和使用
    seajs.use(['math.js'], function (math) {
    var sum = math.add(1, 2);
    });

    CMD与AMD的不同的在于:

    (1)AMD推崇依赖前置;CMD推崇依赖就近,只有在用到某个模块的时候再去require:

    //AMD推崇的依赖关系前置:在定义模块时就要声明要依赖的模块
    define(['a', 'b', 'c', 'd'], function (a, b, c, d) { // 依赖必须一开始就写好
    a.doSomething()
    // 此处省略100行
    ...
    b.doSomething()
    ...
    })

    //CMD推崇依赖就近,按需加载,只有在用到某个模块时再去require
    define(function (require, exports, modules) {
    var a = require('a');
    a.doSomething();
    // 此处省略100行
    ...
    var b = require("b");//按需加载
    b.doSomething();
    ...
    })

    (2)AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。

    对于依赖的模块,AMD是提前执行,CMD是延迟执行。

    具体细节可点击 参考

    什么是ES5的模块化

    其实就是指CommonJS(服务器端)和AMD(浏览器端,require.js)

    CommonJS模块化和AMD模块化的区别

    CommonJS服务器端,AMD浏览器端。

    什么是ES6模块化

    在ES6标准出来之前,大家都是commonJS或者AMD规范来模块化。ES6在语言的层面上实现了模块化。浏览器厂商和 Node.js 都宣布要原生支持该规范。它将逐渐取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。

    在 ES6 中,使用export关键字来导出模块,使用import关键字引用模块。但是浏览器还没有完全兼容,需要使用babel转换成ES5。

    示例中的代码改写成ES6形式:

    //math.js
    var num = 0;
    var add = function (a, b) {
    return a + b;
    };
    export { num, add };
    //导入
    import { num, add } from './math';
    function test(ele) {
    ele.textContent = add(1 + num);
    }

    缺点

    浏览器还没有完全兼容,必须通过工具转换成标准的 ES5 后才能正常运行。

    为什么需要Babel和Webpack

    ES6引入了模块化后,不同功能的代码可以分开写成module的形式。

    但目前的浏览器环境,并不支持ES6 module写法, 所以我们需要借助webpack打包工具和babel转码器来生成可运行的代码。

    什么是Babel 转码器

    Babel 是 ES6 转码器或者说编译器,将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。

    这意味着,你可以用 ES6 的方式编写程序,又不用担心现有环境是否支持...吗?

    什么是Webpack

    WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。

    Webpack和Babel什么关系

    参考来源:https://www.jianshu.com/p/c8b27e40d433

    Webpack是打包工具,Bable是转码器,两者一起使用。我们只需要配置入口js文件,webpack会自动解析模块间的依赖关系,

    通过babal-loader调用babel去转译相应的模块,最后打包成一个目标js文件。

    有了Babel为什么还需要Webpack

    babel承担了“翻译”的角色,把es6的写法转换成es5的写法。

    但是有些人可能在一个项目中单独安装完babel,并成功生成了新的文件后,发现导入这个文件到浏览器中却报错了。其中很有可能被误导的是 import这个关键词。

    实际上babel转换后的代码是遵循commonJS规范的,而这个规范,浏览器并不能识别。因此导入到浏览器中会报错,而nodeJS是commonJS的实现者,所以在babel转换后的代码是可以在node中运行的。

    为了将babel生成的commonJS规范的es5写法能够在浏览器上直接运行,我们就借住了webpack这个打包工具来完成,因为webpack本身也是遵循commonJS这个规范的,从它的配置文件webpack.config.js中就可以看出来。

    //module.exports是commonJS的接口输出规范,es6的规范是export
    module.exports = {
    entry: path.join(__dirname, 'index.js'),
    output: {
    path: path.join(__dirname, 'outs'),
    filename: 'index.js'
    },
    };

    Webpack的工作方式

    参考来源:https://www.jianshu.com/p/42e11515c10f

    把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。

    Babel的局限性

    参考来源:21 分钟精通前端 Polyfill 方案

    即便使用了 Babel ,也做不到放心大胆的使用ES6,否则会被各种 undefined 的报错无情打脸。

    const foo = (a, b) => {
    return Object.assign(a, b);
    };

    上面这样的代码交给 babel 编译时,我们得到了:

    "use strict";
    var foo = function foo(a, b) {
    return Object.assign(a, b);
    };

    可以看到,Babel只能进行语法转换,arrow function 被编译成了普通的函数形式,完美。

    但是Object.assign作为 es2015 的新方法,没有可以被自动转换为的老函数。

    一句话概括, babel 的编译不会做 polyfill。那么 polyfill 是指什么呢?

    什么是Polyfill

    polyfill
     
    - n. 一种用于衣物、床具等的聚酯填充材料, 使这些物品更加温暖舒适。
    - Polyfill 是一块代码(通常是 Web 上的 JavaScript),用来为旧浏览器提供它没有原生支持的较新的功能。 

    比如说 polyfill 可以让 IE7 使用 Silverlight 插件来模拟 HTML Canvas 元素的功能,或模拟 CSS 实现 rem 单位的支持,或 text-shadow,或其他任何你想要的功能。

    Polyfill如何实现

    1,分别引入替换插件babel-plugin-transform-xxx,比如替换Object.assign的babel-plugin-transform-object-assign

    yarn add babel-plugin-transform-object-assign
    # in .babelrc
    {
    "presets": ["latest"],
    "plugins": ["transform-object-assign"]
    }

    2,babel 提供了 babel-plugin-transform-runtime,从一个统一的地方 core-js 自动引入对应的方法

    yarn add -D babel-plugin-transform-runtime
    yarn add babel-runtime
    # .babelrc
    {
    "presets": ["latest"],
    "plugins": ["transform-runtime"]
    }

    3,babel 直接提供了通过改变全局来兼容 es2015 所有方法的 babel-polyfill

    import 'babel-polyfill';
    export const foo = (a, b) => Object.assign(a, b);

    三种方式各有优缺点和适用场景,而且使用不当会造成很难以发现的问题。参考:21 分钟精通前端 Polyfill 方案

    4,babel-preset-env 支持针对指定目标环境选择需要的 polyfill 了,只需引入 babel-polyfill,并在 babelrc 中声明 useBuiltIns,babel 会将引入的 babel-polyfill 自动替换为所需的 polyfill。

    5,polyfill.io 服务器会判断浏览器 UA 返回不同的 polyfill 文件,你所要做的仅仅是在页面上引入这个文件,polyfill 这件事就自动以最优雅的方式解决了。更加让人喜悦的是,polyfill.io 不旦提供了 cdn 的服务,也开源了自己的实现方案 polyfill-service。简单配置一下,便可拥有自己的 polyfill service 了。

    上面两种方式也有缺陷,参考:21 分钟精通前端 Polyfill 方案 坑这么多,真替前端技术人员捂脸。

    什么是npm

    npm的出现,是为了解决前端开发中的代码复用问题,让全世界的前端开发人员可以互相分享并复用所有人的代码。

    参考来源:https://www.jianshu.com/p/c36666b306aa

    【node package management】,是nodejs内置的软件包管理器。毫无疑问,npm是用来管理软件包的。

    它是世界上最大的软件注册表,每星期大约有30亿次的下载量,包含超过600000个包(包)(即,代码模块)。来自各大洲的开源软件开发者使用NPM互相分享和借鉴.包的结构使您能够轻松跟踪依赖项和版本。
     
    npm由三大独立部分组成:
     
    - 网站:开发者查找包(package)、设置参数以及管理 npm 使用体验的主要途径,网址为:https://www.npmjs.com/
    - 注册表:是一个巨大的数据库,保存了每个包的基本信息。
    - 命令行工具:开发者与npm包打交道的工具。

    什么是yarn

    yarn的出现,是为了解决npm的问题

    参考来源:https://www.cnblogs.com/wendyw/p/11494036.html

    Yarn:Yet Another Resource Negotiator,是一个快速、可靠、安全的依赖管理工具,一款新的JavaScript包管理工具。可以替代npm。

    未完(写不下去了... 向勇于攀登的前端技术同学致敬)

  • 相关阅读:
    webLogic的安装与配置总结
    hibernate 中save()、update()、saveOrUpdate()的区别?
    struts2+spring+hibernate+oracle整合,实现增删改查操作。(一)
    配置struts时web.xml中<url-pattern>*.action</url-pattern>
    java中,返回1000-10000中 能被3整除,且个位数是6的个数
    kubernetes部署Fluentd+Elasticsearch+kibana 日志收集系统
    用Docker搭建WordPress
    51建设Android版一些技术整理
    微信内置浏览器隐藏功能左上角功能选项
    vs2013修改默认的开发环境
  • 原文地址:https://www.cnblogs.com/csliwei/p/13045395.html
Copyright © 2011-2022 走看看