正在翻译Elixir的官方上手文档
Elxir官方上手文档
Sade Olutola

Product Placement

Kiana Khansmith

Kaledo Art
Claire Keane

❣ Chile in a Photography ❣
DEAR READER

Andulka
Cosimo Galluzzi

Discoholic 🪩

JBB: An Artblog!
cherry valley forever
ojovivo
I'd rather be in outer space 🛸
we're not kids anymore.
AnasAbdin
Cosmic Funnies
Lint Roller? I Barely Know Her
KIROKAZE
seen from Uzbekistan
seen from Romania
seen from United States
seen from Romania

seen from United Kingdom

seen from United States
seen from Spain

seen from France

seen from United Kingdom

seen from Malaysia

seen from Türkiye
seen from United States
seen from Malaysia
seen from Singapore

seen from Türkiye
seen from Türkiye

seen from Bulgaria
seen from United States

seen from United States
seen from Germany
@codejazz-blog
正在翻译Elixir的官方上手文档
Elxir官方上手文档

Anya is live and ready to show you everything. Watch her strip, dance, and perform exclusive shows just for you. Interact in real-time and make your fantasies come true.
Free to watch • No registration required • HD streaming
一行行读源码之Async.js(1)
处理async库内部变量与全局变量冲突问题
(function() { // Async.js 实现代码 )()
async的所有实现代码被一个立即执行函数所包围,所有的变量都是在该立即函数的范围内定义,没有泄露到全局作用域中
var async = {};
第一行定义的async空对象是Async.js的命名空间,对外的函数全部定义在该命名空间之中,这样就不会产生命名冲突
处理可能的async变量冲突问题
var root, previous_async; root = this; if (root != null) { previous_async = root.async; }
接下来定义的root以及previous_async变量:
通过把封装async的立即函数执行时的this赋值给了root,把root定义成了一个全局变量,在服务端(NodeJS)中是global对象,在浏览器中则是window对象。
而previous_async变量则保存了对root对象原有async变量的引用。
async.noConflict = function() { root.async = previous_async; return async; }
然后就是async库的第一个共有函数,async.noConflict,它负责处理async库的命名空间已经存在的情况,将前面保存的原有async引用重新赋值回root对象,然后返回async库的命名空间。将这个函数的返回值赋给新变量,并通过新的变量调用async库的功能,使得不与已有的async变量冲突。
function only_once(fn) { var called = false; return function() { if (called) throw new Error("Callback was already called."); called = true; fn.apply(root, arguments); } }
only_once函数接受一个函数作为参数,使得这个函数只能被调用一次,可以看做是一个函数装饰器模式,也是一个闭包。在函数里头定义了一个called变量,该变量用来标识传入的函数是否已调用,默认值false表示未调用。它返回另外一个函数,在返回的函数中,通过判断called变量的值来确定函数是否已调用。没有调用过的话在函数中变更called变量的值,called变量的值是通过闭包来保存的。然后调用传入的函数参数,这是函数的执行空间是root变量。
处理跨浏览器兼容性问题
接下来为了跨浏览器兼容性而定义了_each, _map, _reduce以及_keys这四个函数,这几个函数前面几行都是判断是否具备相应的原函数,有的话,就直接利用原函数实现功能,否则就自己去模拟。我们可以看看如果浏览器中没有这四种函数的话,要怎么样去模拟这四种函数。
_each函数
var _each = function (arr, iterator) { if (arr.forEach) { return arr.forEach(iterator); } for (var i = 0; i < arr.length; i += 1) { iterator(arr[i], i, arr); } };
_each函数的实现较为简单,首先判断传入的数组对象中是否存在forEach方法,如果有的话,就把iterator传给forEach方法,利用forEach方法来处理。我们知道forEach方法接收一个函数作为参数,这个函数有三个参数,分别是
当前处理的元素
当前处理元素的偏移
当前处理的整个数组对象
所以iterator函数也应该接收这三个参数,这一点我们可以在接下来async库自己模拟的forEach功能中看到。如果arr数组没有forEach方法,那么就用一个for循环来模拟,在for循环中调用iterator函数处理,这时传给iterator的三个参数就是前面说过的三个参数。
_map函数
var _map = function (arr, iterator) { if (arr.map) { return arr.map(iterator); } var results = []; _each(arr, function (x, i, a) { results.push(iterator(x, i, a)); }); return results;
_map函数中中,定义了一个results数组,用来存储即将返回的结果。我们可以看到,在数组中不存在原生map方法时,可以通过前面定义的_each方法来实现map的功能。
不过这时_each函数调用的函数中,把iterator函数调用后的返回值push到了前面定义的results数组中。在处理完了所有元素之后,把results数组返回了。这样就与原生map函数表现一致,接收一个数组作为参数,返回的结果是另外一个数组,这个数组中的元素依次对应iterator函数处理原有传入数组元素后的函数返回值。这里的iterator函数与前面_each函数的iterator定义一致,也是接收前面说过的三个参数。
_reduce函数
var _reduce = function (arr, iterator, memo) { if (arr.reduce) { return arr.reduce(iterator, memo); } _each(arr, function (x, i, a) { memo = iterator(memo, x, i, a); }); return memo; };
_reduce函数接收的参数与前面定义的两个略有不同,除了数组arr以及迭代处理函数iterator之外,还接收一个memo参数作为reduce操作的初始值。如果原生的数组reduce方法存在,该方法接收一个迭代处理函数以及一个初始值作为参数,在初始值参数不存在的情况下,以数组的第一个元素作为初始值。
在_reduce函数中,也是利用前面定义的_each函数来处理数组元素的。可以看到这时iterator函数接收的是四个参数,第一个是初始值,接下来才是前面说明过的三个参数,即
处理初始值memo
当前处理元素x
当前处理元素偏移i
当前处理的数组a
在_reduce函数中,memo参数不仅仅充当了初始值的角色,还扮演了一个累加器的角色,这里累加器不仅仅指得是加法,而是所有的二元操作。iterator函数调用时,接收前一次的memo值,跟当前处理的值x做某些操作后,返回值重新赋值回了memo变量,作为下一次迭代的参数,就这样依次处理arr数组中的元素,实现了reduce功能
_keys函数
var _keys = function (obj) { if (Object.keys) { return Object.keys(obj); } var keys = []; for (var k in obj) { if (obj.hasOwnProperty(k)) { keys.push(k); } } return keys; };
这个函数也很简单,将传入对象obj的key值集合以数组形式返回,从obj.hasOwnProperty(k)可以看出来,这里的key值集合,是obj对象自己的key值,而不会是obj对象从继承链上继承的key值。