Edit in JSFiddle

var qianduan7 = {};         // 定义发布者(前端公众号)
qianduan7.clientList = [];  // 缓存列表(小王和小李的回调函数)

// 添加订阅者
qianduan7.listen = function(key, fn) {
    if(!this.clientList[key]) {       // 若缓存列表没有该类型的消息,初始化消息
        this.clientList[key] = [];
    }
    this.clientList[key].push(fn);    // 订阅消息添加至缓存列表 
}

// 发布消息, 依次通知订阅者
qianduan7.trigger = function() {
    var key = Array.prototype.shift.call(arguments);    // 取出消息类型
    var fns = this.clientList[key];                     // 取出该消息对应的回调函数集合
    if(!fns || fns.length == 0) {                       // 若订阅列表没有该类型的回到函数,则返回
        return false;                                   
    }
    for(var i = 0; i< fns.length; i++) {
         fns[i].apply(this, arguments);                 // arguments是发布消息时附送的参数
    }
}

// 小王订阅的js
qianduan7.listen('js', function(data) {
    console.log('小王收到的内容:' + data);
});

// 小王儿子订阅的js
qianduan7.listen('js', function(data) {
    console.log('小王儿子收到的内容:' + data);
});

// 小李订阅的nodejs
qianduan7.listen('nodejs', function(data) {
    console.log('小李收到的内容:' + data);
});

// 公众号发布消息
qianduan7.trigger('js', 'js创始人是Brendan Eich.');
qianduan7.trigger('nodejs', 'nodejs作者是Ryan Dahl.');
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="博客 - 发布订阅模式2">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>

</body>
</html>