博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
读Zepto源码之IOS3模块
阅读量:6227 次
发布时间:2019-06-21

本文共 2905 字,大约阅读时间需要 9 分钟。

IOS3 模块是针对 IOS 的兼容模块,实现了两个常用方法的兼容,这两个方法分别是 trimreduce

读 Zepto 源码系列文章已经放到了github上,欢迎star:

源码版本

本文阅读的源码为

GitBook

《》

trim

if (String.prototype.trim === undefined) // fix for iOS 3.2  String.prototype.trim = function(){ return this.replace(/^\s+|\s+$/g, '') }复制代码

看注释, trim 是为了兼容 ios3.2 的。

也是常规的做法,如果 Stringprototype 上没有 trim 方法,则自己实现一个。

实现的方式也简单,就是用正则将开头和结尾的空格去掉。^\s+ 这段是匹配开头的空格,\s+$ 是匹配结尾的空格。

reduce

// For iOS 3.x// from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduceif (Array.prototype.reduce === undefined)  Array.prototype.reduce = function(fun){    if(this === void 0 || this === null) throw new TypeError()    var t = Object(this), len = t.length >>> 0, k = 0, accumulator    if(typeof fun != 'function') throw new TypeError()    if(len == 0 && arguments.length == 1) throw new TypeError()    if(arguments.length >= 2)      accumulator = arguments[1]    else      do{        if(k in t){          accumulator = t[k++]          break        }        if(++k >= len) throw new TypeError()      } while (true)    while (k < len){      if(k in t) accumulator = fun.call(undefined, accumulator, t[k], k, t)      k++    }    return accumulator  }复制代码

用法与参数

要理解这段代码,先来看一下 reduce 的用法和参数:

用法

arr.reduce(callback[, initialValue])

参数

  • callback: 回调函数,有如下参数
    • accumulator: 上一个回调函数返回的值或者是初始值(initialValue
    • currentValue: 当前值
    • currentIndex: 当前值在数组中的索引
    • array: 调用 reduce 的数组
  • initialValue: 初始值,如果没有提供,则为数组的第一项。如果数组为空数组,而又没有提供初始值时,会报错

检测参数

if(this === void 0 || this === null) throw new TypeError()var t = Object(this), len = t.length >>> 0, k = 0, accumulatorif(typeof fun != 'function') throw new TypeError()if(len == 0 && arguments.length == 1) throw new TypeError()复制代码

首先检测是否为 undefined 或者 null ,如果是,则报类型错误。这里有一点值得注意的,判断是否为 undefined 时,用了 void 0 的返回值,因为 void 操作符返回的结果都为 undefined ,这是为了避免 undefined 被重新赋值,出现误判的情况。

接下来,将数组转换成对象,用变量 t 来保存,后面会看到,遍历用的是 for...in 来处理。为什么不直接用 for 来处理数组呢?因为 reduce 不会处理稀疏数组,所以转换要转换成对象来处理。

数组长度用 len 来保存,这里使用了无符号位右移操作符 >>> ,确保 len 为非负整数。

k 来保存当前索引,accumulator 为返回值。

接下来,检测回调函数 fun 是否为 function ,如果不是,抛出类型错误。

在数组为空,并且又没有提供初始值(即只有一个参数 fun)时,抛出类型错误。

accumulator初始值

if(arguments.length >= 2)  accumulator = arguments[1]else  do{    if(k in t){      accumulator = t[k++]      break    }    if(++k >= len) throw new TypeError()  } while (true)复制代码

如果参数至少有两项,则 accumulator 的初始值很简单,就是 arguments[1] ,即 initialValue

如果没有提供初始值,则迭代索引,直到找到在对象 t 中存在的索引。注意这里用了 do...while,所以最终结果,要么是报类型错误,要么 accumulator 能获取到值。

这段还巧妙地用了 ++kk++ 。如果 k 在对象 t 中存在时,则赋值给 accumulatork 再自增,否则用 k 自增后再和 len 比较,如果超出 len 的长度,则报错,因为不存在下一个可以赋给 accumulator 的值。

返回结果

while (k < len){  if(k in t) accumulator = fun.call(undefined, accumulator, t[k], k, t)  k++}return accumulator复制代码

要注意,如果没有提供初始值时,k 是自增后的值,即不再需要处理数组的第一个值。

到这里问题就比较简单了,就是 while 循环,用 accumulator 保存回调函数返回的值,在下一次循环时,再将 accumulator 作为参数传递给回调函数,直至数组耗尽,然后将结果返回。

系列文章

《》

系列文章

附文

参考

License

最后,所有文章都会同步发送到微信公众号上,欢迎关注,欢迎提意见:

作者:对角另一面

转载地址:http://linna.baihongyu.com/

你可能感兴趣的文章
数字电路建模 - jchdl
查看>>
( 转)UVM验证方法学之一验证平台
查看>>
编写每天定时切割Nginx日志的脚本
查看>>
我们一起来聊聊并发吧,one。
查看>>
每日英语:China Pipeline Explosions Kill 52
查看>>
paip.提升性能---jvm java 工具使用.
查看>>
java实现可有括号的android计算器
查看>>
8个免费且实用的C++ GUI库(转载)
查看>>
WGS84 2 GCJ-02
查看>>
RotateAnimation详解
查看>>
GNU make 指南
查看>>
每日英语:How to Save Detroit
查看>>
SQL中以count或sum为条件的查询方式
查看>>
[原]Windows Azure开发之Linux虚拟机
查看>>
[转]MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践
查看>>
SqlServer查询中使用事务
查看>>
ipv6相关
查看>>
粒子加到骨骼中
查看>>
VS2010几款超赞的扩展辅助工具总结
查看>>
Tomcat embed
查看>>