-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JavaScript专题之惰性函数 #44
Comments
function addEvent (type, el, fn) {
if (window.addEventListener) {
addEvent = function (type, el, fn) {
el.addEventListener(type, fn, false);
}
}
else if(window.attachEvent){
addEvent = function (type, el, fn) {
el.attachEvent('on' + type, fn);
}
}
} 如果我没理解错,这段函数,在第一次执行的时候,addEvent并不会绑定事件,只是对addEvent重新赋值了一次,这样修改如何? function addEvent (type, el, fn) {
if (window.addEventListener) {
el.addEventListener(type, fn, false);
addEvent = function (type, el, fn) {
el.addEventListener(type, fn, false);
}
}
else if(window.attachEvent){
el.attachEvent('on' + type, fn);
addEvent = function (type, el, fn) {
el.attachEvent('on' + type, fn);
}
}
} 或者立即执行它 |
@fi3ework 感谢补充哈~ 确实是这样的,第一次并会不绑定事件,所以其实还需要先执行一次: function addEvent (type, el, fn) {
if (window.addEventListener) {
addEvent = function (type, el, fn) {
el.addEventListener(type, fn, false);
}
}
else if(window.attachEvent){
addEvent = function (type, el, fn) {
el.attachEvent('on' + type, fn);
}
}
}
addEvent(); 然后再使用 addEvent 绑定事件 不过你补充的这种方法非常好,就不用再执行一次了~ o( ̄▽ ̄)d |
function addEvent (type, el, fn) {
if (window.addEventListener) {
addEvent = function (type, el, fn) {
el.addEventListener(type, fn, false);
}
}
else if(window.attachEvent){
addEvent = function (type, el, fn) {
el.attachEvent('on' + type, fn);
}
}
addEvent(type, el, fn)
} 其实最后直接执行一次就好了 |
怎么这么多人赞同的啊,这样写不是死循环了吗。。。 |
@lishihong addEvent经过条件判定后已经被重写了 |
哦 是啊 明白了 |
感觉用这个例子来引入惰性函数不是很适合
这个需求应该是用 once 函数实现比较好,不过 addEvent 的例子是适合惰性函数的。 function once(fn) {
var fire, ret
return function() {
var self = this
if (!fire) {
fire = true
ret = fn.apply(self, arguments)
}
return ret
}
} |
如果存在这么一款浏览器
|
如上代码,前后两次执行 foo() 返回同样的时间,我认为应该是利用了闭包的特性。
5.执行 foo 指向的匿名函数 B ,创建 匿名函数 B 执行上下文,匿名函数 B 上下文被压入执行上下文栈
7.匿名函数 B 执行,沿着作用域链查找 t 值,返回 t 值 而之所以形成闭包,是因为步骤 4 至步骤 5 中,对 foo 进行了重新赋值,从而让 foo 所指向函数的 [[Scope]] 值为 [ anonymousAContext.AO, globalContext.VO] 。 |
其实就是foo的指向发生了变化 还有就是一些闭包在起作用 |
妙啊 |
妙,之前就这样写过,不过就与 const 无缘了。 |
改成自执行函数就可以把。 const addEvent = (function(type, el, fn) {
if(window.addEventListener) {
return function(type, el, fn) {
el.addEventListener(type, fn, false);
}
}
if(window.attachEvent) {
return function(type, el, fn) {
el.attachEvent('on' + type, fn);
}
}
})(); |
个人觉得惰性函数是 通过改写函数来 避免多次做不必要的判断, once 函数 还是需要每次执行都进行判断 |
学习了,这两篇都简单了好多,之前看柯里化看得头大 |
element-ui 处理 dom 事件的源码就是这样写的。 export const on = (function() {
if (!isServer && document.addEventListener) {
return function(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
};
} else {
return function(element, event, handler) {
if (element && event && handler) {
element.attachEvent('on' + event, handler);
}
};
}
})(); |
@fi3ework @mqyqingfeng function addEvent (type, el, fn) {
if (window.addEventListener) {
// 在第一次调用时 根据特征进行重新定义
addEvent = function(type, el, fn) {
el.addEventListener(type, fn, false);
}
}
if (window.attachEvent) {
addEvent = function(type, el, fn) {
el.attachEvent('on' + type, fn);
}
}
// me: 我觉得应该有调用这一句,此时调用的已经是重新定义过的addEvent 不会无限递归
addEvent(type, el, fn);
} |
这样就不是惰性函数了。 |
妙妙妙 |
需求
我们现在需要写一个 foo 函数,这个函数返回首次调用时的 Date 对象,注意是首次。
解决一:普通方法
问题有两个,一是污染了全局变量,二是每次调用 foo 的时候都需要进行一次判断。
解决二:闭包
我们很容易想到用闭包避免污染全局变量。
然而还是没有解决调用时都必须进行一次判断的问题。
解决三:函数对象
函数也是一种对象,利用这个特性,我们也可以解决这个问题。
依旧没有解决调用时都必须进行一次判断的问题。
解决四:惰性函数
不错,惰性函数就是解决每次都要进行判断的这个问题,解决原理很简单,重写函数。
更多应用
DOM 事件添加中,为了兼容现代浏览器和 IE 浏览器,我们需要对浏览器环境进行一次判断:
问题在于我们每当使用一次 addEvent 时都会进行一次判断。
利用惰性函数,我们可以这样做:
当然我们也可以使用闭包的形式:
当我们每次都需要进行条件判断,其实只需要判断一次,接下来的使用方式都不会发生改变的时候,想想是否可以考虑使用惰性函数。
重要参考
Lazy Function Definition Pattern
专题系列
JavaScript专题系列目录地址:https://github.com/mqyqingfeng/Blog。
JavaScript专题系列预计写二十篇左右,主要研究日常开发中一些功能点的实现,比如防抖、节流、去重、类型判断、拷贝、最值、扁平、柯里、递归、乱序、排序等,特点是研(chao)究(xi) underscore 和 jQuery 的实现方式。
如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励。
The text was updated successfully, but these errors were encountered: