经典JS
用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的更多相关文章
- 大部分人都会做错的经典JS闭包面试题
由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...
- 经典JS闭包面试题(来理解闭包)(转)
转载地址:http://www.cnblogs.com/xxcanghai/p/4991870.html 先看代码: function fun(n,o) { console.log(o) return ...
- 一篇常做错的经典JS闭包面试题
作者 | Jeskson 来源 | 达达前端小酒馆 1 究竟是怎么样的一道面试题,能让我拿出来说说呢?下面请看代码: function fun(a,b) { console.log(b) return ...
- 一道经典JS面试题
超过80%的候选人对下面这道JS面试题的回答情况连及格都达不到.这究竟是怎样神奇的一道JS面试题?他考察了候选人的哪些能力?对正在读本文的你有什么启示? 不起眼的开始 招聘前端工程师,尤其是中高级前端 ...
- 经典JS 判断上传文件大小和JS即时同步电脑时间
我也是新手,还是一个JS笨,有一些网站要实现的功能要自己写么? 答案是不会,去问同事大佬吧,闲简单.就在晚上看了一些其他大佬们写的JS效果, 代码很少.占用网站CPU也小的多.可以一用, 废话少扯.代 ...
- 一道经典JS题(关于this)
项目中碰到的问题,以前也碰到过,没有重视,现记录如下. <input type='button' value='click me' id='btn' /> <script> v ...
- 经典JS的HTML转义与反转义字符
//HTML转义 function HTMLEncode(html) { var temp = document.createElement ("div"); (temp.text ...
- 经典js框架
http://requirejs.org/ http://durandaljs.com/ http://knockoutjs.com/index.html http://www.jeasyui.com ...
- 一道常被人轻视的前端JS面试题
前言 年前刚刚离职了,分享下我曾经出过的一道面试题,此题是我出的一套前端面试题中的最后一题,用来考核面试者的JavaScript的综合能力,很可惜到目前为止的将近两年中,几乎没有人能够完全答对,并非多 ...
随机推荐
- 读取JPG图片的Exif属性(一) - Exif信息简介
https://blog.csdn.net/fioletfly/article/details/53605959 https://blog.csdn.net/a_big_pig/article/det ...
- 服务器有无中木马前期诊断 注意:wget最好是从服务器上卸载掉,因为多数情况是wget下载木马到服务器的
# rpm -qf /usr/bin/wget wget-.el6_6..x86_64 rpm -e --nodeps wget 有无下列文件: cat /etc/rc.d/init.d/selinu ...
- Fluent UDF【5】:第一个UDF
这里以一个简单的初始化案例来描述UDF的使用过程. 0 Fluent中的Patch Fluent中提供了全域初始化以及局部Patch功能.对于整体区域的全局初始化可以采用starndard及hybri ...
- Spring开启方法异步执行
@EnableAsync @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(Async ...
- 深入云存储系统Swift核心组件:Ring实现原理剖析
http://www.cnblogs.com/yuxc/archive/2012/06/22/2558312.html 简介 OpenStack是一个美国国家航空航天局和Rackspace合作研发的开 ...
- XShell 技巧
说明: 很长时间了,一直用XShell,但是总是用鼠标操作,后来想用其他方式代替鼠标,一想肯定有快捷方式等,这里就先记下一遍有用的博文,转自: http://sundful.iteye.com/blo ...
- python(44):array和matrix的运算
在NumPy中,array用于表示通用的N维数组,matrix则特定用于线性代数计算.array和matrix都可以用来表示矩阵,二者在进行乘法操作时,有一些不同之处. 使用array时,运算符 * ...
- mac book air 与 virtual box 网络互访 安装centos7 mini
Host-only Adapter 主机模式 虚拟机之间可以访问...主机可以访问虚拟机 NAT 网络地址转换模式(Network A ...
- JAVA Zero Copy的相关知识【转】
转自:https://my.oschina.net/cloudcoder/blog/299944 摘要: java 的zero copy多在网络应用程序中使用.Java的libaries在linux和 ...
- js判断网页是真静态还是伪静态的方法
现在很多网站都是使用以“.html“为扩展名的网页,这样做的好处是有利于搜索引擎收录和排名,或者是其他目的,如可以缩短网址使人容易记住.不过有意思的是并不是所有的以“.html”扩展名的网页都是静态的 ...