ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] ## 1.4 JavaScript脚本 小程序的主要开发语言是 JavaScript ,开发者使用 JavaScript 来开发业务逻辑以及调用小程序的 API 来完成业务需求、处理用户的操作。 ### 1.4.1 ECMAScript 在大部分开发者看来,ECMAScript和JavaScript表达的是同一种含义,但是严格的说,两者的意义是不同的。 ECMAScript是一种由Ecma国际通过ECMA-262标准化的脚本程序设计语言, JavaScript 是 ECMAScript 的一种实现。理解 JavaScript 是 ECMAScript 一种实现后,可以帮助开发者理解小程序中的 JavaScript同浏览器中的 JavaScript 以及 NodeJS 中的 JavaScript 是不相同的。 ECMA-262 规定了 ECMAScript 语言的几个重要组成部分: 1. 语法 2. 类型 3. 语句 4. 关键字 5. 操作符 6. 对象 :-: ![浏览器中的 JavaScript](https://box.kancloud.cn/7ae6ea9f09084dad7c0b3a6e83226daa_501x241.png) :-: 图2-15 浏览器中的 JavaScript 浏览器中的JavaScript 是由 ECMAScript 和 BOM(浏览器对象模型)以及 DOM(文档对象模型)组成的,Web前端开发者会很熟悉这两个对象模型,它使得开发者可以去操作浏览器的一些表现,比如修改URL、修改页面呈现、记录数据等等。 :-: ![NodeJS中的 JavaScript](https://box.kancloud.cn/a2db9c689a03e96ada743884710e52ed_503x244.png) :-: 图2-16 NodeJS中的 JavaScript NodeJS中的JavaScript 是由 ECMAScript 和 NPM以及Native模块组成,NodeJS的开发者会非常熟悉 NPM 的包管理系统,通过各种拓展包来快速的实现一些功能,同时通过使用一些原生的模块例如 FS、HTTP、OS等等来拥有一些语言本身所不具有的能力。 :-: ![小程序中的 JavaScript](https://box.kancloud.cn/50c585dfe7d8cc1faee191d652f387d9_503x242.png) :-: 图2-17 小程序中的 JavaScript 小程序中的 JavaScript 是由ECMAScript 以及小程序框架和小程序 API 来实现的。同浏览器中的JavaScript 相比没有 BOM 以及 DOM 对象,所以类似 JQuery、Zepto这种浏览器类库是无法在小程序中运行起来的,同样的缺少 Native 模块和NPM包管理的机制,小程序中无法加载原生库,也无法直接使用大部分的 NPM 包。 ### 1.4.2 小程序的执行环境 小程序目前可以运行在三大平台: 1. iOS平台,包括iOS9、iOS10、iOS11 2. Android平台 3. 小程序IDE 区别主要是体现三大平台实现的 ECMAScript 的标准有所不同。截止到当前一共有七个版本的ECMAScript 标准,目前开发者大部分使用的是 ECMAScript 5 和 ECMAScript 6 的标准,但是在小程序中, iOS9和iOS10 所使用的运行环境并没有完全的兼容到 ECMAScript 6 标准,一些 ECMAScript 6 中规定的语法和关键字是没有的或者同标准是有所不同的,例如: - 箭头函数 - let const - 模板字符串 所以一些开发者会发现有些代码在旧的手机操作系统上出现一些语法错误。为了帮助开发者解决这类问题,小程序IDE提供语法转码工具帮助开发者,将 ECMAScript 6代码转为 ECMAScript 5代码,从而在所有的环境都能得到很好的执行。 开发者需要在项目设置中,勾选 `ES6 转 ES5 `开启此功能。 ### 1.4.3 模块化 浏览器中,所有 JavaScript 是运行在同一个作用域下的,定义的参数或者方法可以被后续加载的脚本访问或者改写。 同浏览器不同,小程序中可以将任何一个JavaScript 文件作为一个模块,通过module.exports 或者 exports 对外暴露接口。 简单模块示例,B.js 引用模块A,并使用A暴露的multiplyBy2方法完成一个变量乘以 2 的操作。 代码清单2-26 模块示例 ~~~ // moduleA.js module.exports = function( value ){ return value * 2; } ~~~ 代码清单2-27 引用模块A ~~~ // B.js // 在B.js中引用模块A var multiplyBy2 = require('./moduleA') var result = multiplyBy2(4) ~~~ 代码清单2-28 在需要使用这些模块的文件中,使用 `require(path)` 将公共代码引入 ~~~ var common = require('common.js') Page({ helloMINA: function() { common.sayHello('MINA') }, goodbyeMINA: function() { common.sayGoodbye('MINA') } }) ~~~ ### 1.4.4 脚本的执行顺序 浏览器中,脚本严格按照加载的顺序执行。 在小程序中的脚本执行顺序有所不同。小程序执行的入口文件是 `app.js` 。并且会根据其中 `require 的模块顺序`决定文件的运行顺序,当 app.js 执行结束后,小程序会按照开发者在 `app.json` 中定义的 `pages 的顺序`,逐一执行。 ### 1.4.5 作用域 同浏览器中运行的脚本文件有所不同,小程序的脚本的作用域同 NodeJS 更为相似。 在文件中声明的变量和函数只在该文件中有效,不同的文件中可以声明相同名字的变量和函数,不会互相影响。 当需要使用全局变量的时,通过使用全局函数 `getApp()` 获取全局的实例,并设置相关属性值,来达到设置全局变量的目的,如代码2-38、代码2-39所示。 代码清单2-38 在脚本 a.js 中设置全局变量 ~~~ // a.js // 获取全局变量 var global = getApp() global.globalValue = 'globalValue' ~~~ 代码清单2-39 在脚本 b.js 中访问 a.js 定义的全局变量 ~~~ // b.js // 访问全局变量 var global = getApp() console.log(global.globalValue) // 输出 globalValue ~~~ 需要注意的是,上述示例只有在 a.js 比 b.js 先执行才有效,当需要保证全局的数据可以在任何文件中安全的被使用到,那么可以在app.js的 `App()` 中进行设置,如代码2-40、代码2-41、代码2-42所示。 代码清单2-40 定义全局变量 ~~~ // app.js App({ globalData: 1 }) ~~~ 代码清单2-41 获取以及修改 global 变量的方法 ~~~ // a.js // 局部变量 var localValue = 'a' // 获取 global 变量 var app = getApp() // 修改 global 变量 app.globalData++ // 执行后 globalData 数值为 2 ~~~ 代码清单2-42 获取 global 变量 ~~~ // b.js // 定义另外的局部变量,并不会影响 a.js 中文件变量 var localValue = 'b' // 如果先执行了 a.js 这里的输出应该是 2 console.log(getApp().globalData) ~~~