经典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的综合能力,很可惜到目前为止的将近两年中,几乎没有人能够完全答对,并非多 ...
随机推荐
- Jenkins管理静态资源
这里我们的前端是使用webpack来管理静态资源的,把静态资源上传到svn上面来管理 这里我们把项目和静态资源剥离开来,然后静态资源接入CDN 我们的svn的结构是这样的 我们需要把这些目录都进行打包 ...
- php分享二十:mysql优化
1:垂直分割 示例一:在Users表中有一个字段是家庭地址,这个字段是可选字段,相比起,而且你在数据库操作的时候除了个人信息外,你并不需要经常读取或是改写这个字段.那么,为什么不把他放到另外一张表中呢 ...
- CentOS 7 安装中文环境
centos升级到7后,系统设置好多和6有了很大的区别,中文支持就有很大的变化. 1.安装中文语言包. yum install kde-l10n-Chinese 2.安装(已经安装的要重新安装)gli ...
- ios--网页js调用oc代码+传递参数+避免中文参数乱码的解决方案(实例)
此解决方案原理: 1.在ViewController.h中声明方法和成员变量,以及webView的委托: // // ViewController.h // JS_IOS_01 // // Cr ...
- nginx、Apache、Lighttpd启用HSTS
302跳转 通常情况下,我们将用户的 HTTP 请求 302 跳转到 HTTPS,这会存在两个问题: 不够安全,302 跳转会暴露用户访问站点,也容易被劫持 拖慢访问速度,302 跳转需要一个 RTT ...
- windows远程连接mac配置方法
1.开启mac共享服务,设置通过密码进行连接 [系统偏好设置]中选择[共享]打开[屏幕共享]服务,即可允许其他电脑的用户远程查看并控制此电脑.点击[电脑设置]配置访问密码 2. 下载TightVNC, ...
- Mybatis的mapper注册
既然 MyBatis 的行为已经由上述元素配置完了,我们现在就要定义 SQL 映射语句了.但是首先我们需要告诉 MyBatis 到哪里去找到这些语句. Java 在自动查找这方面没有提供一个很好的方法 ...
- 使用jquery提交FormData数据
https://blog.csdn.net/u011500781/article/details/54931716 http://yunzhu.iteye.com/blog/2177923 ***** ...
- Lintcode: Sort Colors II 解题报告
Sort Colors II 原题链接: http://lintcode.com/zh-cn/problem/sort-colors-ii/# Given an array of n objects ...
- SQLite 入门教程一 基本控制台(终端)命令
一.基本简介 SQLite 是一个自持的(self-contained).无服务器的.零配置的.事务型的关系型数据库引擎.因为他很小,所以也可以作为嵌入式数据库内建在你的应用程序中.SQLite 被应 ...