Giter VIP home page Giter VIP logo

Comments (18)

fi3ework avatar fi3ework commented on May 2, 2024 38
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.

forzalianjunting avatar forzalianjunting commented on May 2, 2024 34
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.

lishihong avatar lishihong commented on May 2, 2024 10
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.

panyanbin avatar panyanbin commented on May 2, 2024 10
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.addEventListenerwindow.attachEvent都不存在时,就是死循环了吧

from blog.

mqyqingfeng avatar mqyqingfeng commented on May 2, 2024 8

@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.

forzalianjunting avatar forzalianjunting commented on May 2, 2024 8

@lishihong addEvent经过条件判定后已经被重写了

from blog.

anjina avatar anjina commented on May 2, 2024 2

妙,之前就这样写过,不过就与 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 avatar lishihong commented on May 2, 2024

@lishihong addEvent经过条件判定后已经被重写了

哦 是啊 明白了

from blog.

DarkoPeng avatar DarkoPeng commented on May 2, 2024

感觉用这个例子来引入惰性函数不是很适合

我们现在需要写一个 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.

Mcqueengit avatar Mcqueengit commented on May 2, 2024
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.

gtandsn avatar gtandsn commented on May 2, 2024

其实就是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.

wubianluoye avatar wubianluoye commented on May 2, 2024

妙啊

from blog.

ferrinweb avatar ferrinweb commented on May 2, 2024

妙,之前就这样写过,不过就与 const 无缘了。

from blog.

anjina avatar anjina commented on May 2, 2024

感觉用这个例子来引入惰性函数不是很适合

我们现在需要写一个 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.

cw84973570 avatar cw84973570 commented on May 2, 2024

学习了,这两篇都简单了好多,之前看柯里化看得头大

from blog.

dadong-coder avatar dadong-coder commented on May 2, 2024

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.

BlueStoneQ avatar BlueStoneQ commented on May 2, 2024

@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.

ferrinweb avatar ferrinweb commented on May 2, 2024

妙,之前就这样写过,不过就与 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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.