Comments (18)
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);
}
}
}
或者立即执行它
from blog.
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)
}
其实最后直接执行一次就好了
from blog.
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) }其实最后直接执行一次就好了
怎么这么多人赞同的啊,这样写不是死循环了吗。。。
from blog.
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) }其实最后直接执行一次就好了
怎么这么多人赞同的啊,这样写不是死循环了吗。。。
如果存在这么一款浏览器
window.addEventListener
和window.attachEvent
都不存在时,就是死循环了吧
from blog.
@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
from blog.
@lishihong addEvent经过条件判定后已经被重写了
from blog.
妙,之前就这样写过,不过就与 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);
}
}
})();
from blog.
@lishihong addEvent经过条件判定后已经被重写了
哦 是啊 明白了
from blog.
感觉用这个例子来引入惰性函数不是很适合
我们现在需要写一个 foo 函数,这个函数返回首次调用时的 Date 对象,注意是首次。
这个需求应该是用 once 函数实现比较好,不过 addEvent 的例子是适合惰性函数的。
function once(fn) {
var fire, ret
return function() {
var self = this
if (!fire) {
fire = true
ret = fn.apply(self, arguments)
}
return ret
}
}
from blog.
var foo = function() { //假设这个是匿名函数A
var t = new Date();
foo = function() { //假设这个是匿名函数B
return t;
};
return foo();
};
foo(); //一个时间
foo(); //同样的事件
如上代码,前后两次执行 foo() 返回同样的时间,我认为应该是利用了闭包的特性。
如果按照您在JavaScript深入之执行上下文中的讲解,那此处的执行过程应该怎么描述呢(注:以下描述只描述到了执行第一个 foo() )。
1.进入全局代码,创建全局执行上下文,全局执行上下文压入执行上下文栈
2.全局执行上下文初始化
接下来就有点不清楚了,是?
3.执行 foo 指向的匿名函数 A ,创建 匿名函数 A 执行上下文,匿名函数 A 执行上下文被压入执行上下文栈
4.匿名函数 A 执行上下文初始化,创建变量对象、作用域链、this等
anonymousAContext = {
AO: {
arguments: {
length: 0
},
t: undefined,
},
Scope: [AO, globalContext.VO],
this: undefined
}
5.执行 foo 指向的匿名函数 B ,创建 匿名函数 B 执行上下文,匿名函数 B 上下文被压入执行上下文栈
6.匿名函数 B 执行上下文初始化,创建变量对象、作用域链、this等
anonymousBContext = {
AO: {
arguments: {
length: 0
},
},
Scope: [AO, anonymousAContext.AO, globalContext.VO],
this: undefined
}
7.匿名函数 B 执行,沿着作用域链查找 t 值,返回 t 值
8.匿名函数 B 函数执行完毕,匿名函数 B 函数上下文从执行上下文栈中弹出
9.匿名函数 A 函数执行完毕,匿名函数 A 执行上下文从执行上下文栈中弹出
而之所以形成闭包,是因为步骤 4 至步骤 5 中,对 foo 进行了重新赋值,从而让 foo 所指向函数的 [[Scope]] 值为 [ anonymousAContext.AO, globalContext.VO] 。
不知道这样的解释是否正确,对于 foo 是指向匿名函数的变量,之前的教程貌似没有介绍。
from blog.
其实就是foo的指向发生了变化
最开始初始化的时候
foo指向
function () {
var t = new Date()
foo = function () {
console.log(the same time: ${t}
);
}
return foo();
}
运行完成以后
foo指向
foo = function () {
console.log(the same time: ${t}
);
}
还有就是一些闭包在起作用
from blog.
妙啊
from blog.
妙,之前就这样写过,不过就与 const 无缘了。
from blog.
感觉用这个例子来引入惰性函数不是很适合
我们现在需要写一个 foo 函数,这个函数返回首次调用时的 Date 对象,注意是首次。
这个需求应该是用 once 函数实现比较好,不过 addEvent 的例子是适合惰性函数的。
function once(fn) { var fire, ret return function() { var self = this if (!fire) { fire = true ret = fn.apply(self, arguments) } return ret } }
个人觉得惰性函数是 通过改写函数来 避免多次做不必要的判断, once 函数 还是需要每次执行都进行判断
from blog.
学习了,这两篇都简单了好多,之前看柯里化看得头大
from blog.
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);
}
};
}
})();
from blog.
@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);
}
from blog.
妙,之前就这样写过,不过就与 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); } } })();
这样就不是惰性函数了。
from blog.
Related Issues (20)
- 冴羽答读者问:如何在工作中打造影响力,带动同事?
- 无
- 冴羽答读者问:如何学习更有计划性、提升更稳更快? HOT 4
- 冴羽答读者问:过程比结果重要吗? HOT 1
- 冴羽答读者问:冴羽,你为什么写起了鸡汤? HOT 3
- 聊聊 npm 的语义化版本(Semver) HOT 4
- How to create Backlinks 😤
- 思考题第2题
- 可以理解为原型是prototype,原型链是通过__proto__ 链接起来的吗
- React 之 createElement 源码解读 HOT 8
- React 之元素与组件的区别 HOT 1
- React 之 Refs 的使用和 forwardRef 的源码解读
- React 之 Context 的变迁与背后实现 HOT 1
- 第一段不报错啊,刚试过了,会打印1
- how can i HOT 1
- Hosting of Blog Issue
- 全局对象
- 为啥每次都要创建一个 Child函数来new 子类?现在不都是 const p1 = new Person(); const p2 = new Person()吗
- 文档内容中文件结构的错位 HOT 1
- 原型链继承
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from blog.