Abruzzi's Wall

Front-End Web Developer

Ghost only can help me to here...


  1. JQuery Reduce Patch

    今天写Jquery插件的时候发现JQuery不支持Array.prototype.reduce的实现,我做了一个简单的patch: 有三点需要注意: 1.为了实现链式调用,例如$([...]).map(fn).reduce(fn),注册reduce函数到jQuery的原型上:$.fn.reduce = fn; 2.由于传给$.reduce的arr在这里是$.mapreturn后的jquery对象,所以在reduce前做一次arr = arr.toArray()的处理 3.对于不支持ES5 Array.prototype.reduce()的环境,通过$.each()进行模拟reduce过程,每次迭代prev(previous)和cur(current)交换。…


  2. Analytics代码延迟异步加载

    这两天研究了一些网站统计代码的相关技术,做了一些实验,得到一些有趣的结果。 通常情况下,我们在自己的网站引入统计js脚本时,官方会提供同步/异步两种代码。同步代码暂且不谈,官方提供的异步代码通常如下(google & baidu): 可以看到,多数分析网站的异步脚本都是由document.write写入一个<script>标签,同时依次添加<script>标签的type、src以及async属性。 Html5<script>标签的async与defer属性 这里的async属性是html5为<script>增加的新属性,标有这个属性的外部脚本,被浏览器解析时会立刻下载该外部脚本同时却不阻塞后续的document渲染、script加载等事件,从而实现外部脚本的异步加载。 此外html5还为<script>元素提供了一个defer属性,defer属性和async作用大体一致,并且都拥有一个附加onload事件,例如: <script src=…


  3. 直接与间接调用eval函数

    读《Effective Javascript》第17条,由于翻译原因,花了很长时间才搞明白eval的直接调用、间接调用的区别与好恶,为了避免遗忘,记录于此。 首先见代码: 在函数中直接调用执行eval标识符,称为直接调用eval函数,在这种情况下,eval函数所执行的程序将获得eval函数执行时所在作用域访问权限,在上面的代码中,'foo'能直接访问到IIFY中的局部作用域,因此结果输出2。 而与直接调用eval函数不同的间接调用如下: 可以看到eval函数通过bar变量间接调用,在这种情况下,eval函数所执行的程序将获得全局(顶级)作用域的访问权限,因此输出结果为1。 在这种间接调用eval函数、获取全局作用域访问权限的情况下,编译器对其优化是远远简单于直接调用eval获取局部作用域访问权限的。 因此在使用eval的过程中应该尽可能间接调用eval函数。 另一种更加间接的间接调用eval函数的方式如下: 结果输出1 这个表达式(0, eval)('foo')工作原理为: 先后对0、eval求值,但0被忽略,括号表示的序列表达式最终结果为eval函数,因此整个表达式被视为一种间接调用eval函数的方式。…


  4. JS闭包中的引用

    今天读《Effective Javascript》第14条感觉很有意思,以前并不知道这个情况,因此记录下来。 先上Bug代码 初看这段代码输出的值大概会想到是10,但实际输出undefined。 这是因为对于闭包函数,即上面代码中 function() {return a[i];}, 它所引用的变量i来自外部函数,而闭包函数的一大特点是:通过引用而非值来捕获外部变量,因此这里a[i]中的i仅仅是对外部函数i的一个引用。 因此wrapped[0]时,闭包函数外所驻留的变量i此时值为5,因此调用所有闭包函数都会return a[5],结果自然就是undefined了。 解决这个坑的方法是创建一个嵌套函数的局部作用域,将a[x]的x绑定为值: 可以看到在闭包外的局部作用域中j以值的形式添加给了数组a。 通过立即调用函数表达式(IIFE)可以建立局部作用域,但同时也有2个隐患: 1.立即调用函数表达式代码块中不能有break,continue; 2.如果代码块中引用了this或者特别的arguments变量,IIFE可能会改变他们的含义。…