如何在HTML中使用JavaScript? -- 传统、流行、未来

1. 在HTML页面中,通过<scritp>签加载JavaScript脚本, 有两种方式:内嵌外部引用

  • 内嵌 将脚本内容直接置于<scritp>签的内容中
  • 外部引用 通过<scritp>签的src属性引用一个脚本文件

推荐采用外部引用方式:

  • 便于维护
    采用内嵌的方式,会使JS脚本遍布各个页面中,而引用脚本文件的话,可以把JS脚本集中放到一个文件夹中,方便管理,程序员在不触碰 HTML页的情况下,集中精力开发JS脚本。
  • JS脚本可在多个页面中共享和缓存, 最终可以加快页面加载速度。

2. <scritp>签, 可置于页面的<head><body> 部分

  • 最早 <scritp><link>签一样, 统一放在 <head>部分
    但是,这样做有明显的缺点, 这会导致JS立即下载并顺序执行,很有可能阻塞页面渲染。
    HTML5规范,特意引入deferasync属性 实现 外部引用的脚本延迟执行,区别是 defer保证脚本按顺序执行,async并不保证。
  • 推荐放在 <body>的尾部 一定会在页面渲染完成后,下载并执行。

3. JavaScript模块化

JavaScript没有名字空间的概念,当加载多个 JS脚本时,特别是引入第三方脚本时, 很容易产生名字污染,所以一般不会直接在JS的全局域中直接定义函数和变量,而是定义一个模块对象,包含这些函数和变量。

//  common.js 传统写法,全局域中直接定义函数和变量 很容易造成名字污染 
var DATA_PATH =  '/data/source/';
var someInternalState = true;
function doSth() {
  //...
}
// 定义一个模块对象,包含这些导出的函数和变量
var  common = {
  DATA_PATH :   '/data/source/',
  someInternalState : true,
  doSth : function () {
    //...
  }
}
// 进一步改进, 采用`立即执行函数`的办法,只暴露接口,隐藏实现细节 ,比如实例中的someInternalState
var common = function () {
  var DATA_PATH =  '/data/source/';
  var someInternalState = true;
  function doSth() {
  ...
  }
  return {
       DATA_PATH :   DATA_PATH ,
       doSth : doSth
  }
}

4. 目前 最流行的方式 是通过RequrieJS来 异步加载JS脚本。

《如何在HTML中使用JavaScript? -- 传统、流行、未来》 RequireJS

传统方式加载JS脚本, 都是同步、顺序的执行,同步可能导致阻塞问题, 顺序执行需要当心 脚本间依赖关系, 不得不 手动指定<script>签顺序,依赖最少的排在最前面,而且当JS脚本越来越多时,<scritp>签会越来越多,页面也会显得臃肿、丑陋

是什么 ?

是一个JavaSript库,帮助我们完成脚本的模块化(符合AMD规范), 实现异步加载。

怎么用?

  1. 页面: 在<body>尾部添加一条<script>
<!-- src指定 RequireJS位置, data-main指定主模块位置  -->
 <script src='require.js'  data-main='main.js' > </script>

  1. 主模块 使用require函数 导入其他模块。主模块的作用类似main函数,是程序的入口点
 // 假设主模块main.js依赖于 requery.js 和 common.js,在默认情况下, RequireJS会从主模块目录查找依赖模块
 // require第一个参数是依赖的模块名列表, 模块名不能指定.js后缀; 第二个参数,是依赖模块全都加载完毕后的回调函数,传入依赖模块的导出结果。
require(['jquery', 'common'], function($, common) {
        // ....
 });

 // 当依赖模块和主模块不在一个目录下时,需要额外的配置 baseUrl 属性
// 特别注意的是,baseUrl支持相对和绝对路径,  示例以/开头,是一个本地的绝对路径;如果忽略开头的/,则是一个相对于主模块所在路径的相对路径
 require.config({
       baseUrl"/js/others"  
 });
 require(['jquery', 'common'], function($, common) {
        // ....
 });
 
 // 当依赖模块并不都在一个目录时,需要单独的配置paths属性(特别是需要引用外网的JS脚本时)
 require.config({
       baseUrl"/js/others"  
       paths: {
      "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"// 完整的Url
    }
 });
 require(['jquery', 'common'], function($, common) {
        // ....
 });
  1. 依赖模块 使用define函数 符合AMD规范
    // 没有额外依赖时 传入一个返回模块对象的匿名函数
    define(function() {
         // ... 最终返回导出对象
         return { functions, variables }; 
    });  
    
    // 有额外依赖时,第一个参数是依赖模块名的列表
    

define([‘base’], function(base) {
//… 最终返回导出对象
return { functions, variables };
} );


4. 当依赖模块不符合`AMD`规范时,直接改造或者在导入时配置 shim 属性
```javascript
// 依赖模块 common.js
function a() {
//...
}
function b() {
//...
}
//主模块 main.js 需要导入common.js的一个名字时,配置exports属性   
require.config({
      shim : {
           'common' : {
                 deps : ['jquery'] , // common依赖的模块名
                 exports :  ' a'  // 需要导出的函数或者变量名字
           }
      }
});
// 需要导入多个名字时,配置init属性  
require.config({
      shim : {
           'common' : {
                 deps : ['jquery'] ,   // common依赖的模块名
                 init:  function() {
                       return {
                             a:a, 
                             b:b
                       }
                 }
           }
      }
});

5. 值得期待的是 ,ES6标准 引入了classmodule概念,规范了脚本模块化和加载方式,但浏览器完全支持尚需时日。

本篇文章总结了在前端浏览器中如何使用JavaScript,有三种方式,传统的<script>签, 流行的 RequireJS插件,以及面向未来的 ES6。接下来,我要总结后台Node.js环境中,如何使用JavaScript脚本。

    原文作者:ufoac
    原文地址: https://www.jianshu.com/p/30cc3d24111a
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞