用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;
}
}

经典JS的更多相关文章

  1. 大部分人都会做错的经典JS闭包面试题

    由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...

  2. 经典JS闭包面试题(来理解闭包)(转)

    转载地址:http://www.cnblogs.com/xxcanghai/p/4991870.html 先看代码: function fun(n,o) { console.log(o) return ...

  3. 一篇常做错的经典JS闭包面试题

    作者 | Jeskson 来源 | 达达前端小酒馆 1 究竟是怎么样的一道面试题,能让我拿出来说说呢?下面请看代码: function fun(a,b) { console.log(b) return ...

  4. 一道经典JS面试题

    超过80%的候选人对下面这道JS面试题的回答情况连及格都达不到.这究竟是怎样神奇的一道JS面试题?他考察了候选人的哪些能力?对正在读本文的你有什么启示? 不起眼的开始 招聘前端工程师,尤其是中高级前端 ...

  5. 经典JS 判断上传文件大小和JS即时同步电脑时间

    我也是新手,还是一个JS笨,有一些网站要实现的功能要自己写么? 答案是不会,去问同事大佬吧,闲简单.就在晚上看了一些其他大佬们写的JS效果, 代码很少.占用网站CPU也小的多.可以一用, 废话少扯.代 ...

  6. 一道经典JS题(关于this)

    项目中碰到的问题,以前也碰到过,没有重视,现记录如下. <input type='button' value='click me' id='btn' /> <script> v ...

  7. 经典JS的HTML转义与反转义字符

    //HTML转义 function HTMLEncode(html) { var temp = document.createElement ("div"); (temp.text ...

  8. 经典js框架

    http://requirejs.org/ http://durandaljs.com/ http://knockoutjs.com/index.html http://www.jeasyui.com ...

  9. 一道常被人轻视的前端JS面试题

    前言 年前刚刚离职了,分享下我曾经出过的一道面试题,此题是我出的一套前端面试题中的最后一题,用来考核面试者的JavaScript的综合能力,很可惜到目前为止的将近两年中,几乎没有人能够完全答对,并非多 ...

随机推荐

  1. haproxy 日志配置

    haproxy日志配置 haproxy在默认情况不会记录日志,除了在haproxy.conf中的global段指定日志的输出外,还需要配置系统日志的配置文件.下面以centos6.4为例,haprox ...

  2. css遮罩层

    父元素:position:fixed; 让子元素居中对齐:position:absolute;top:0;bottom:0;left:0;right:0;margin:auto; <style& ...

  3. virtualbox和vagrant卸载脚本在macbook

    virtualbox和vagrant在macbook版本的安装文件内,都有一个卸载脚本uninstall.tool vagrant2.1.5卸载脚本: #!/usr/bin/env bash #--- ...

  4. 含有按钮的ScrollView在iOS8中无法滚动的解决办法 | ScrollView with UIControl/UIButton subviews not scrollable under iOS 8

    转自:http://zcw.me/blogwp/%E5%90%AB%E6%9C%89%E6%8C%89%E9%92%AE%E7%9A%84scrollview%E5%9C%A8ios8%E4%B8%A ...

  5. FFmpeg(6)-通过av_find_best_stream()来获取音视流的索引

    也可以通过av_find_best_stream()函数来获取流的索引: 例: audioStream = av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO, -, ...

  6. Java虚拟机(JVM)概述

    JVM(Java虚拟机)是一个抽象的计算模型.就如同一台真实的机器,它有自己的指令集和执行引擎,可以在运行时操控内存区域.目的是为构建在其上运行的应用程序提供一个运行环境.JVM可以解读指令代码并与底 ...

  7. openssl生成SSL证书的流程

    SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道(Secure socketlayer(SSL),SSL安全协议主要用来提供对用户和服务器的认证:对传送的数据进行加密和隐藏:确保数 ...

  8. angular-resource版本差异问题

    在 AngularJS v1.3.0-beta.14 这个版本里,使用query方法,如果传递进来的数据不是数组,会报错. 在 AngularJS v1.2.18 这个版本里,使用query方法,如果 ...

  9. iOS按钮的基本使用代码优化

    将图片按钮进行连线, 声明方法同时连接六个按钮 -(void)move:(UIButton *)btn{ //    NSLog(@"看见一个美女"); //头尾式动画 //0.开 ...

  10. maven 使用记录之修改 maven默认jdk版本

    maven package执行的时候会遇到jdk版本不对的问题 :原因是 maven所指定的jdk版本与项目使用的jdk版本不一致 1.项目属性的 java compiler可以设置 2.直接修改 m ...