经典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的综合能力,很可惜到目前为止的将近两年中,几乎没有人能够完全答对,并非多 ...
随机推荐
- Android开发中无处不在的设计模式——动态代理模式
继续更新设计模式系列.写这个模式的主要原因是近期看到了动态代理的代码. 先来回想一下前5个模式: - Android开发中无处不在的设计模式--单例模式 - Android开发中无处不在的设计模式-- ...
- python TCP编程
1.socket 服务端和客户端通过socket套接字进行通信 2.服务端 import socket import threading def tcp_handler(connect_sock, a ...
- iOS正则表达式的使用案例-富文本
富文本(正则表达式) 一.新建工程导入图片 二 实现方式一(缺点是只能解决一个图片的替换) _myLabel.font = [UIFont systemFontOfSize:15]; //@" ...
- 网易云信消息抄送服务的第三方接口示例(Java)
package com.netease.nim.route; import com.alibaba.fastjson.JSONObject; import com.netease.nim.route. ...
- webpack的代码分割/离
两种方法: 1.webpack的methods----require.ensure 2.ES 2015的Loader spec //require.ensure语法 require.ensure [] ...
- c与c++相互调用机制分析与实现
c++通常被称为Better c,多数是因为c++程序可以很简单的调用c函数,语法上基本实现兼容.最常用的调用方式就是c++模块调用c实现的dll导出函数,很简单的用法,使用extern " ...
- 关于一点pthread_cond_t条件锁的思考以及实验
转:http://blog.csdn.net/aniao/article/details/5802015 APUE上,关于条件锁.其中有这么几条总结: 1.使用条件锁前必须先锁住对应的互斥锁. 2.条 ...
- jsdoc注释规范工具(使用 JSDoc 3 自动生成 JavaScript API 文档)
安装和使用规范见:http://moodpo.com/archives/jsdoc3-tutorial.html 实例: /** * 模块调用方法 * * * @param {string} modu ...
- 九章面试题:Find first K frequency numbers 解题报告
Find first K frequency numbers /* * Input: int[] A = {1, 1, 2, 3, 4, 5, 2}; k = 3 * return the highe ...
- 在Mac系统下用STS搭建一个Spring MVC项目
[本文出自天外归云的博客园] 从STS的下载到空项目的搭建 1. 下载STS,下载解压缩后点击sts-bundle文件夹中的STS文件启动ide: 2. 创建Spring MVC项目:File-> ...