一、常见误区

1. 数组

和php不同,在js中array是[object]类型,既然是对象,那么在函数操作里面就是地址传递

  1. var arr = [];
  2. var run = function (a) {
  3. a.push(1);
  4. }
  5. run(arr);
  6. console.log(arr); // [1]

php数组不是对象,则函数操作是值传递,js数组是对象,则函数操作是地址传递

2. 字符串0和数字0

  1. // 字符串0 布尔值是true
  2. console.log(!!'0');
  3. // 数字0 布尔值是false
  4. console.log(!!0);

在写实际业务的时候,尽量使用 if (变量>0) 代替 if (可能为0的变量)

二、高阶函数

数组的高效率方法(map, filter, forEach, reduce)


1. Array.prototype.map

用法:[].map(function(value,index,arr) { return something; });
说明: 将闭包函数应用于数组的每一个元素上,获取新的数组
参数: 数组对象map方法接收第1个参数为闭包函数,map方法结束后会返回一个新的数组,闭包函数自动接收3个参数,value为遍历的每一个数组元素,index为元素索引,arr为数组本身,闭包函数要有返回值
场景: 常用于适配。服务器返回数据库轮播图列表,而layer.photos需要元素都是图片地址字符串的数组

  1. // 这里可能是从ajax请求服务器后得到的数据
  2. var svr_data = {
  3. att_list: [
  4. {
  5. id: 1,
  6. url: '/Public/1.jpg',
  7. },
  8. {
  9. id: 2,
  10. url: '/Public/2.jpg',
  11. }
  12. ]
  13. };
  14. // 构建Layer需要的数据
  15. var data = svr_data.att_list.map(function(att_item) {
  16. return {
  17. "alt": "皇家披萨", // 图片名
  18. "pid": att_item.id, //图片id
  19. "src": 'baidu.com' + att_item.url, //原图地址
  20. "thumb": "" //缩略图地址
  21. };
  22. });
  23. // 调用layer的方法
  24. layer.photos({
  25. photos: {
  26. title: '美食图片',
  27. data: data
  28. }
  29. });
  30. // 其他场景:快速生成dom元素 ...

2. Array.prototype.filter

用法:[].filter(function(value,index,arr) { return flag; });
说明: 将闭包函数应用于数组的每一个元素上,获取过滤后的新的数组
参数: 数组对象filter方法接收第1个参数为闭包函数,filter方法结束后会返回一个新的数组,闭包函数自动接收3个参数,value为遍历的每一个数组元素,index为元素索引,arr为数组本身,闭包函数需要返回一个布尔值
场景: 常用于过滤。去掉数组某字段为空的元素

  1. // 代码展示大概用法
  2. var odd = [1, 2, 3, 4].filter(function(n) {
  3. return n % 2;
  4. });
  5. console.log(odd); // [1, 3] 奇数数组

3. Array.prototype.forEach

用法:[].forEach(function(value,index,arr) { /* do something */ });
说明: 将闭包函数应用于数组的每一个元素上
参数: 数组对象forEach方法接收第1个参数为闭包函数,闭包函数自动接收3个参数,value为遍历的每一个数组元素,index为元素索引,arr为数组本身,闭包函数不需要返回值
场景: 简单遍历都可以替换,减少无用变量 i,j,k 等

  1. var goods_list = [
  2. {
  3. goods_id: 1,
  4. name: '1'
  5. },
  6. {
  7. goods_id: 2,
  8. name: '2'
  9. }
  10. ];
  11. goods_list.forEach(function(goods) {
  12. console.log(goods);
  13. });

4. Array.prototype.reduce

用法:[].reduce(function(p,v,i,a) { return something; }, initialValue);
说明: 将闭包函数应用于数组的每一个元素上
参数: 数组对象reduce方法接收第1个参数为闭包函数,reduce方法结束后会返回一个新的值,闭包函数自动接收4个参数,p为初始值或上一次返回值,v为元素本身,i为元素索引,a为数组本身,闭包函数需要对p进行操作后的返回值
场景: 常用于统计。如商品的价格

  1. var goods_list = [
  2. {
  3. goods_id: 1,
  4. price: 1,
  5. num: 1
  6. },
  7. {
  8. goods_id: 2,
  9. price: 2,
  10. num: 2
  11. }
  12. ];
  13. var payAmount = goods_list.reduce(function(amount, goods) {
  14. return amount + goods.price * goods.num;
  15. }, 0);
  16. console.log(payAmount); // 5

总结:map适配,filter过滤,forEach遍历,reduce统计
php 也有对应的方法 array_map, array_filter, array_reduce,用法基本相同

5. 其他函数灵活写法

  1. // 写法1
  2. function run1(a) {
  3. return 1;
  4. }
  5. // 写法2
  6. var run2 = function(b) {
  7. return 2;
  8. };
  9. var util = {
  10. run1: run1,
  11. run2: run2,
  12. run3: function(c) {
  13. // 匿名函数
  14. return 3;
  15. }
  16. };
  17. // 闭包函数
  18. var getRun4 = function(d) {
  19. return function(e) {
  20. return d + e;
  21. };
  22. };
  23. util.run4 = getRun4(4);
  24. // 立即执行函数
  25. util.run5 = (function(f) {
  26. return function(g) {
  27. return f - g;
  28. };
  29. })(5);

为什么要用立即执行函数:https://zhuanlan.zhihu.com/p/22465092

三、ES6基础

1. 箭头函数


为了解决this问题,用箭头函数可以让代码很短,也不需要定义that, _this, self等乱七八糟的变量

  1. // 函数缩写
  2. // ES5写法
  3. App({
  4. data: { url: 'www.baidu.com' },
  5. test: function() {
  6. console.log(this.data.url); // 正确: this 指向 app
  7. setTimeout(function() {
  8. console.log(this.data.url); // 错误: this 指向匿名函数
  9. }, 1000);
  10. }
  11. });
  12. // ES6写法
  13. App({
  14. data: { url: 'www.baidu.com' },
  15. test() {
  16. console.log(this.data.url); // 正确: this 指向 app
  17. setTimeout(() => { // 使用箭头
  18. console.log(this.data.url); // 正确: this 指向 app
  19. }, 1000);
  20. }
  21. });
  22. /*
  23. 需要注意 onShow 的位置,如果是下面这种写法就不是预期需要的
  24. var app = {
  25. data: { url: 'www.baidu.com' },
  26. onShow: () => {
  27. console.log(this.data.url); // 报错: this 指向 window
  28. setTimeout(() => {
  29. console.log(this.data.url); // 报错: this 指向 window
  30. });
  31. }
  32. }
  33. ...........
  34. 定义函数方法
  35. ...........
  36. ES5 无参数写法: function run () { return 1; }
  37. ES6 无参数写法1: const run = () => { return 1; }
  38. ES6 无参数写法2: const run = () => (1)
  39. ........
  40. ES5 一参数写法: function addOne (a) { return a + 1; }
  41. ES6 一参数写法1: const addOne = (a) => { return a + 1; }
  42. ES6 一参数写法2: const addOne = a => { return a + 1; }
  43. ES6 一参数写法3: const addOne = a => (a + 1)
  44. ES6 一参数写法4: const addOne = a => a + 1
  45. ........
  46. ES5 多参数写法: function add (a, b) { return a + b; }
  47. ES6 多参数写法1: const add = (a, b) => { return a + b; }
  48. ES6 多参数写法2: const add = (a, b) => (a + b)
  49. ES6 多参数写法3: const add = (a, b) => a + b
  50. */

函数的扩展:http://es6.ruanyifeng.com/#docs/function

2. let和const


const 用于定义常量或者不可以被覆盖的对象(数组,函数,其他类型对象)
let 用于定义变量,同一作用域不可以重复定义

let和const:http://es6.ruanyifeng.com/#docs/let

3. 解构赋值

  1. // ES5写法
  2. var value = e.detail.value;
  3. var id = e.currentTarget.dataset.id;
  4. var path = e.currentTarget.dataset.path;
  5. // ES6写法
  6. let {value} = e.detail
  7. let {id, path} = e.currentTarget.dataset

解构赋值:http://es6.ruanyifeng.com/#docs/destructuring

4. 模块化

  1. // ES5写法
  2. // utils.js
  3. module.exports = {a: a, b: b};
  4. // app.js
  5. var util = require('./util.js'); // 只能引入全部
  6. // ES6写法
  7. // util.js
  8. export default {a, b}
  9. // app.js
  10. import util from 'util' // 引入全部
  11. import {a} from 'util' // 按需引入

Module语法:http://es6.ruanyifeng.com/#docs/module

5. 扩展运算符(…)

  1. // 快速操作数组
  2. let arr = [1, 2, 3]
  3. let newArr = [0, ...arr, 4] // [0, 1, 2, 3, 4]
  4. // 小程序快速赋值
  5. // app.js
  6. App({
  7. globalData: {
  8. a: 1,
  9. b: 2,
  10. },
  11. getSvrData() {
  12. // ....
  13. }
  14. })
  15. // page.js
  16. const app = getApp();
  17. Page({
  18. data: {
  19. ...app.globalData,
  20. c: 3,
  21. },
  22. ...mapActions(['map', 'tel'])
  23. })

数组扩展运算符:http://es6.ruanyifeng.com/#docs/array
对象扩展运算符:http://es6.ruanyifeng.com/#docs/object

四、参考资料

  1. ES6入门: http://es6.ruanyifeng.com/
  2. ES6转ES5:https://www.babeljs.cn/repl/