惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Project Zero
Project Zero
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Scott Helme
Scott Helme
Know Your Adversary
Know Your Adversary
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
WordPress大学
WordPress大学
AWS News Blog
AWS News Blog
小众软件
小众软件
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Jina AI
Jina AI
AI
AI
美团技术团队
人人都是产品经理
人人都是产品经理
S
Secure Thoughts
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
宝玉的分享
宝玉的分享
Security Latest
Security Latest
P
Privacy & Cybersecurity Law Blog
C
Cisco Blogs
大猫的无限游戏
大猫的无限游戏
Google Online Security Blog
Google Online Security Blog
L
LINUX DO - 最新话题
罗磊的独立博客
Recent Announcements
Recent Announcements
H
Hacker News: Front Page
博客园 - 【当耐特】
K
Kaspersky official blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
SecWiki News
SecWiki News
Schneier on Security
Schneier on Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Apple Machine Learning Research
Apple Machine Learning Research
F
Full Disclosure
Google DeepMind News
Google DeepMind News
V
V2EX
博客园 - 聂微东
量子位
云风的 BLOG
云风的 BLOG
C
Check Point Blog
J
Java Code Geeks
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
W
WeLiveSecurity
Engineering at Meta
Engineering at Meta
V2EX - 技术
V2EX - 技术
Vercel News
Vercel News
L
LINUX DO - 热门话题
T
The Exploit Database - CXSecurity.com
L
Lohrmann on Cybersecurity
The GitHub Blog
The GitHub Blog

博客园 - iQingHan

C#中二进制和流之间的各种相互转换 underscore-1.8.3-analysis.js 12 extremely useful hacks for JavaScript IIS字体文件添加MIME映射 js类型判断的方法 基于html5 canvas 的客户端异步上传图片的插件,支持客户端压缩图片尺寸 Google Chrome 默认非安全端口列表 js判断类型的方法 博客园样式排版自定义 easyloader.js源代码分析 JQuery操作cookies jQuery插件的开发 jQuery 1.9 移除了 $.browser 的替代方法 Pretty Gmail GreasemonkeyScript jQuery之移除链接小插件 ASP.NET中关于验证控件和自定义弹出确认窗口的冲突问题 JQuery获取浏览器窗口的可视区域高度和宽度,滚动条高度 jQuery的选择器 园子里使用的jQuery.json
经典JS
iQingHan · 2016-08-29 · via 博客园 - iQingHan

用apply把document当作this传入getId函数,帮助“修正”this;

document.getElementById = (function (func) {
    return function () {
        return func.apply(document, arguments);
    }
})(document.getElementById);

//调用
var getId = document.getElementById;
var div = getId('div2');

类型判断

var Type = {};

for (var i = 0, type; type = ['String', 'Array', 'Number'][i++];) {

    (function (type) {
        Type['is' + type] = function (obj) {
            return Object.prototype.toString.call(obj) === '[object ' + type + ']';
        }
    })(type);

};

自定义事件(一):

var Event = {
    _listeners: {},    
    // 添加
    addEvent: function(type, fn) {
        if (typeof this._listeners[type] === "undefined") {
            this._listeners[type] = [];
        }
        if (typeof fn === "function") {
            this._listeners[type].push(fn);
        }    
        return this;
    },
    // 触发
    fireEvent: function(type) {
        var arrayEvent = this._listeners[type];
        if (arrayEvent instanceof Array) {
            for (var i=0, length=arrayEvent.length; i<length; i+=1) {
                if (typeof arrayEvent[i] === "function") {
                    arrayEvent[i]({ type: type });    
                }
            }
        }    
        return this;
    },
    // 删除
    removeEvent: function(type, fn) {
        var arrayEvent = this._listeners[type];
        if (typeof type === "string" && arrayEvent instanceof Array) {
            if (typeof fn === "function") {
                // 清除当前type类型事件下对应fn方法
                for (var i=0, length=arrayEvent.length; i<length; i+=1){
                    if (arrayEvent[i] === fn){
                        this._listeners[type].splice(i, 1);
                        break;
                    }
                }
            } else {
                // 如果仅仅参数type, 或参数fn邪魔外道,则所有type类型事件清除
                delete this._listeners[type];
            }
        }
        return this;
    }
};

自定义事件(二):

//自定义事件

var Event=(function () { 

    var global=this,
        Event,
        _default='default';

    Event=function () { 
        var _listen,
            _trigger,
            _remove,
            _slice=Array.prototype.slice,
            _shift=Array.prototype.shift,
            _unshift=Array.prototype.unshift,
            namespaceCache={},
            _create,
            find,
            each=function (ary,fn) { 
                var ret;
                for (var i = 0, l=ary.length; i < l; i++){
                    var n=ary[i];
                    ret=fn.call(n,i,n);
                }
                return ret;
             };
             //添加监听事件,并缓存
             _listen = function (key,fn,cache) { 
                 if(!cache[key]){
                     cache[key]=[];
                 }
                 cache[key].push(fn);
              };
              //移除监听
              _remove=function (key,cache,fn) { 
                  if(cache[key]){ //如果存在该监听事件
                      if(fn){ //如果存在回调函数
                          for (var i = cache[key].length; i >=0; i--){
                             if(cache[key][i]===fn){
                                 cache[key].splice(i,1); //移除此回调函数
                             }
                          }
                      }else{
                          cache[key]=[]; //清除此事件(为什么存在回调函数时不执行此步骤,奇怪)
                      }
                  }
               };

               //触发事件
               _trigger=function () { 
                   var cache = _shift.call(arguments), //第一个参数是cache
                       key = _shift.call(arguments),  //第二个参数是key
                       args = arguments,
                       _self = this,
                       ret,
                       stack= cache[key];

                    if(!stack || !stack.length){ //没有回调函数则直接返回
                        return;
                    }

                    return each(stack, function () { //执行所有的回调函数
                        return this.apply(_self,args);
                     });

                };
                //创建事件的实例
                _create=function (namespace) { 
                    var namespace = namespace || _default;
                    var cache ={},
                        offlineStack=[], //离线事件
                        ret={
                            listen:function (key,fn,last) { 
                                _listen(key,fn,cache);
                                if(offlineStack===null){
                                    return;
                                }
                                if(last==='last'){
                                    offlineStack.length && offlineStack.pop()(); //如果是最后一个离线事件,触发此离线事件并移除此事件
                                }else{
                                    each(offlineStack,function(){ //如果是多个离线事件,并遍历触发
                                        this();
                                    });
                                }

                                offlineStack = null; 清空离线事件
                             },
                             //执行一次监听事件
                             one:function (key,fn,last) { 
                                 _remove(key,cache); //此缓存中移除此事件
                                 this.listen(key,fn,last); //添加此事件
                              },
                              remove:function (key,fn) { 
                                  _remove(key,cache,fn);
                               },
                               trigger:function () { 
                                   var fn,
                                       args,
                                       _self=this;

                                    _unshift.call(arguments,cache); //将cache缓存添加到arguments参数集合中
                                    args=arguments;
                                    fn=function(){
                                        return _trigger.apply(_self,args);
                                    };

                                    if(offlineStack){
                                        return offlineStack.push(fn);
                                    }
                                    return fn(); //触发事件
                                }

                        };

                        return namespace ?
                            (namespaceCache[namespace] ? namespaceCache[namespace]:
                                namespaceCache[namespace]= ret ) 
                                    :ret;
                 };

                return {
                    create: _create,
                    one: function (key, fn, last) {
                        var event = this.create();
                        event.one(key, fn, last);
                    },
                    remove: function (key, fn) {
                        var event = this.create();
                        event.remove(key, fn);
                    },
                    listen: function (key, fn, last) {
                        var event = this.create();
                        event.listen(key, fn, last);
                    },
                    trigger: function () {
                        var event = this.create();
                        event.trigger.apply(this,arguments);
                    }
                };


     }();

     return Event;

 })();

方法绑定:

Function.prototype.bind = function () {
    var self = this,
    context  = [].shift.call(arguments),
    args     = [].slice.call(arguments);
    
    return function () {
        return self.apply( context, [].concat.call(args, [].slice.call(arguments)) )
    } 
}

AOP:

Function.prototype.before = function(beforefn) {
    var _self = this;
    return function() {
        beforefn.apply(this, arguments);
        return _self.apply(this, arguments);
    }
}

Function.prototype.after = function(afterfn) {
    var _self = this;
    return function() {
        var ret = _self.apply(this, arguments);
        afterfn.apply(this, arguments);
        return ret;
    }
}