Skip to content

ES2015 WeakMap的学习和使用

2017年2月27日

ES2015(ES6)中新增了几种数据类型,包括Map WeakMap Set WeakSet等。其中Map可以与我们熟悉的对象Object进行对照,他们的功能都是提供一个键值对集合,主要的区别在于Object的key只能是字符串,而Map的key可以是任意类型。关于Map的大致用法可以参考MDN,我在前一篇文章《也谈JavaScript数组去重》中也有提及。

今天要讨论的主角是WeakMap。

按照MDN上的说明

WeakMap 对象是键/值对的集合,且其中的键是弱引用的。其键只能是对象,而值则可以是任意的。

从这段描述来看,我们可以大致推断出,WeakMap与Map的主要区别在于两点:

  1. WeakMap对key的引用是弱引用
  2. WeakMap的key只能是对象

这两点意味着什么呢?反正我第一眼看到的时候不是拉格良日懵就是三元二次懵的状态。于是围绕WeakMap去查阅了一些资料,渐渐地有了一些更深入的认识,记录成本文。

To A Dark Futuer

2017年2月24日

开年来真的有点忙,好不容易写起来的公众号又好久没拔草了。

最近忙的其中一件事是写一个slides,也就是传说中的PPT。(明明用的是keynote,你才PPT,你全家都PPT!)写的是web前端的一些普及性的介绍。

在写的过程中,发现越写越悲观,写到最后竟然隐隐觉得web要完。当然,这是一件政治极其不正确的事情,所以也不敢到处乱发,只能当成呓语在公众号写一写,给为数不多的朋友诉一诉这其中的一些想法。

标准的危机

曾经有几年,大家是非常热衷于web标准的。但是如果问一问现在来面试的朋友,估计应该没有多少人还在意web标准这件事情。大家会关注 Angular / React / Vue ,会关注 AR / VR ,但是真的没有人关注web标准。

那我们关注一下可好?

唉,算了。反正大概的感觉就是真正需要成为标准的东西一直拖拖拉拉,比如像 web components 至今没有定稿,导致至今没有一个像样的组件方案。最后靠框架来填补这块空白。而像 web bluetooth / web usb / web vr 这类的东西倒是层出不穷。

除了标准本身外,厂商的跟进也是个大问题。一方面厂商对标准越来越不上心,爱理不理,另一方面,又为了各自的利益,先做非标准实现,再回头去影响标准。

总而言之,标准现在就是一锅粥。

也谈JavaScript数组去重

2017年1月5日

JavaScript的数组去重是一个老生常谈的话题了。随便搜一搜就能找到非常多不同版本的解法。

昨天在微博上看到一篇文章,也写数组去重,主要推崇的方法是将利用数组元素当作对象key来去重。我在微博转发了“用对象key去重不是个好办法…”然后作者问什么才是推荐的方法。

细想一下,这样一个看似简单的需求,如果要做到完备,涉及的知识和需要注意的地方着实不少,于是诞生此文。

定义重复(相等)

要去重,首先得定义,什么叫作“重复”,即具体到代码而言,两个数据在什么情况下可以算是相等的。这并不是一个很容易的问题。

对于原始值而言,我们很容易想到11是相等的,'1''1'也是相等的。那么,1'1'是相等的么?

如果这个问题还好说,只要回答“是”或者“不是”即可。那么下面这些情况就没那么容易了。

小程序接入OAuth

2016年12月29日

如何使用web录制视频

2016年9月25日

cover

Node.js中低成本实现错误告警

2016年1月27日

相比其他语言(特指PHP)而言,Node.js应用更需要关注出错信息,因为一旦处理不慎,就会导致应用crash。

一种偷懒的方法是使用PM2之类的进程管理软件来启动Node.js进程,从而达到出错crash后自动重新启动应用的目的。

当然更好的办法则是手工捕获错误,然后进行适当的处理,防止应用产生未被接住的错误导致crash。

在捕获到Node.js产生的错误后,下一步自然是记录到错误日志中,以便日后可以进行分析,并针对性地排查修改。本文要说的,即是对错误日志的处理方式之一——告警。

告警是运维工作中非常重要的一个环节,它能让开发者(维护者)及时获知应用出错状态和详情,及早介入处理,将线上故障的影响降低到最低。而要实现告警功能,则需要从两方面入手,一方面是对错误信息进行集中处理(分类、分级、合并、限流等),另一方面需要将这些错误信息及时推送出去。

使用PM2 Deploy部署基于Git版本管理的网站应用

2014年11月19日

按照官方介绍,PM2是一款用于生产环境Node.js应用进程管理的工具。按照民间介绍,它主要有这样几个功能:保证Node.js应用永远在线(挂掉自动重启)、自动负载均衡、零中断重启应用等。

鉴于它是如此优秀,这里还是简要介绍一下前两个功能。

安装

首先,它是一个Node.js写的工具,使用npm即可安装使用:

npm install -g pm2

运行Node.js程序

如果不使用pm2,运行Node.js程序是这样:

node xxx.js

使用pm2,是这样:

pm2 start xxx.js

监视模式

如果你正在开发Node.js应用,需要在代码变更后自动重启应用,只需要在pm2的参数中加上--watch即可:

pm2 start xxx.js --watch

Retina屏下的CSS雪碧图

2014年3月19日

cover

学习ES6生成器(Generator)

2013年12月29日

这几天,TJ大神的koa框架突然在国内火起来了,随之而来的,则是其使用的ES6生成器(Generator)引起了广大码农的强烈兴趣,各种文章也如雨后春笋般拔地而起,比如这篇这篇、还有这篇。这个神奇的生成器被视为解决JS“回调恶魔金字塔”的利器。在动手实践之后,发现介绍ES6生成器的文章仍然有些疏漏,因此有了这篇文章,权当是对各位大大们的补充好了。

背景

在JS的使用场景中,异步操作的处理是一个不可回避的问题,如果不做任何抽象、组织,只是“跟着感觉走”,那么面对“按顺序发起3个ajax请求”的需求,很容易就能写出如下代码(假设已引入jQuery):

javascript
// 第1个ajax请求
$.ajax({
  url:'http://echo.113.im',
  dateType:'json',
  type:'get',
  data:{
    data:JSON.stringify({status:1,data:'hello world'}),
    type:'json',
    timeout:1000
  },
  success:function(data){
    if(data.status === 1){
      // 第2个ajax请求
      $.ajax({
        ......此处省略500字
        success:function(data){
          if(data.status === 1){
            // 第3个ajax请求
            $.ajax({
              ......此处省略500字
              success:function(data){
                if(data.status === 1){

                }
              }
            });
          }
        }
      });
    }
  }
});
// 第1个ajax请求
$.ajax({
  url:'http://echo.113.im',
  dateType:'json',
  type:'get',
  data:{
    data:JSON.stringify({status:1,data:'hello world'}),
    type:'json',
    timeout:1000
  },
  success:function(data){
    if(data.status === 1){
      // 第2个ajax请求
      $.ajax({
        ......此处省略500字
        success:function(data){
          if(data.status === 1){
            // 第3个ajax请求
            $.ajax({
              ......此处省略500字
              success:function(data){
                if(data.status === 1){

                }
              }
            });
          }
        }
      });
    }
  }
});

当顺序执行的异步操作越来越多的时候,回调层级也就越多,这也就是传说中的“回调恶魔金字塔”。

如何设计一个前端模板引擎

2013年8月25日

前端模板引擎现在已经被广泛应用于前端开发了,几乎每个项目都会使用。微博上甚至出现了“不写个模板引擎就没办法在前端界混了”的言论。当然,这是玩笑话,却也能在一定程度上反映前端模板的普及程度。如果你还没有了解过前端模板引擎,赶紧去补补课吧。

本文其实算不上是一篇讲模板引擎设计的文章,写这篇文章的动力来自于自己使用过一些模板引擎(jQuery Tmpl、jade、ejs、artTemplate以及ThinkPHP自带后端模板引擎)之后的心得,所以可能不会涉及到模板引擎设计的方方面面,更多地是讲模板引擎之间的一些有差异的细节以及我的思考和取舍。

来历

javascript
var tempHtml = '<table>' +
    '     <tr>' +
    '       <th>Hello</th>' +
    '       <th>World</th>' +
    '       <th>!</th>' +
    '     </tr>' +
    '     <tr>' +
    '       <td>' + myData.col1 + '</td>' +
    '       <td>' + myData.col2 +'</td>' +
    '       <td>' + (myData.col3 === 'yes'?'!':'?') + '</td>' +
    '     </tr>' +
    '   </table>';

document.querySelector('#myDiv').innerHTML = tempHtml;
var tempHtml = '<table>' +
    '     <tr>' +
    '       <th>Hello</th>' +
    '       <th>World</th>' +
    '       <th>!</th>' +
    '     </tr>' +
    '     <tr>' +
    '       <td>' + myData.col1 + '</td>' +
    '       <td>' + myData.col2 +'</td>' +
    '       <td>' + (myData.col3 === 'yes'?'!':'?') + '</td>' +
    '     </tr>' +
    '   </table>';

document.querySelector('#myDiv').innerHTML = tempHtml;

相信上面的代码对哪怕做过一点点涉及界面开发的都应该很熟悉吧。当我们想把一段结构和一段数据组合起来,再放到页面上时,就会常常面临这样一段复杂的代码。

这段代码相信不用我说你也会觉得它实在有点复杂:要处理结构中字符串本身的拼接,还要注意结构与数据的拼接,处理数据拼接时还要注意运算优先级(尤其在使用?:三元运算符时),还要为了可读性考虑纠结的缩进……

当然,最麻烦的还不是这里,当我们想要对一个数据循环遍历并输出时,居然还要自己去写循环,再一圈一圈地把这些结构拼起来,最后再拼上首尾的结构。而当数据为空时,又要自己去写一个“暂无数据”之类的占位符……

为什么浏览器不内建更多选择器

2012年9月6日

来自知乎问题JavaScript 为什么不内建选择器?

首先,与这个问题有关的浏览器中的技术概念其实大致有这些:

  1. BOM,即浏览器对象模型,简单说就是浏览器提供的环境,包括各种对象及其方法,比如window
  2. DOM,即文档对象模型,它是由HTML经解析后生成的一个模型,我们对页面可视部分进行操作实际上就是在操作DOM
  3. JavaScript,浏览器提供了BOM,也解析了DOM,那么,开发者如何去操作它们呢?这时候就轮到JavaScript出场了,所以JavaScript(在这个例子中)是用来操作DOM和BOM的

那么所谓的选择器,getElement(s)ByXXXX实际上是由DOM提供的,而且对DOM的level实现的程度不一样,这些方法也不一样,比如DOM level 0中主要的方法(确切说是属性)就是document.imagesdocument.links之类。而DOM level 3中则提供了querySelector(All)之类更为方便的API。

[译]什么是Shadow Dom?

2012年6月7日

cover