美文网首页
2020-05-13 5kyu Simple Events

2020-05-13 5kyu Simple Events

作者: 苦庭 | 来源:发表于2020-05-13 18:21 被阅读0次

    https://www.codewars.com/kata/52d3b68215be7c2d5300022f/javascript

    Your goal is to write an Event constructor function, which can be used to make event objects.

    An event object should work like this:

    it has a .subscribe() method, which takes a function and stores it as its handler
    it has an .unsubscribe() method, which takes a function and removes it from its handlers
    it has an .emit() method, which takes an arbitrary number of arguments and calls all the stored functions with these arguments
    As this is an elementary example of events, there are some simplifications:

    all functions are called with correct arguments (e.g. only functions will be passed to unsubscribe)
    you should not worry about the order of handlers' execution
    the handlers will not attempt to modify an event object (e.g. add or remove handlers)
    the context of handlers' execution is not important
    each handler will be subscribed at most once at any given moment of time. It can still be unsubscribed and then subscribed again
    Also see an example test fixture for suggested usage

    My answer (NAC)

    function Event() {
      //your implementation goes here 
      this.ob = {};
    }
    
    Event.prototype.subscribe = function(f) {
      if(!this.ob[f.name])
      this.ob[f.name] = f;
    }
    Event.prototype.emit = function(){
      for(var func in this.ob) {
        this.ob[func] && this.ob[func].call(this, ...Object.values(arguments));
      }
    }
    Event.prototype.unsubscribe = function(f){
      if(this.ob[f.name]){
        this.ob[f.name] = undefined;
      }
    }
    

    问题出在哪?

    • 数据结构选错了,用对象来存储函数了(应该用数组!)
    • 没有理解apply/call(如何区分)、forEach()的用法
    • 对arguments对象、prototype、插入删除小能手splice()的不了解

    My answer (AC,根据正确答案改的)

    function Event() {
      //your implementation goes here 
      this.ob = [];
    }
    
    Event.prototype.subscribe = function(f) {
      if(!this.ob[f.name])
      this.ob.push(f);
    }
    Event.prototype.emit = function(){
      var args = arguments;
      this.ob.forEach(function(o){
        o.call(this, ...Object.values(args))
      });
    }
    Event.prototype.unsubscribe = function(f){
      var index = this.ob.indexOf(f);
      if (index !== -1) {
        this.ob.splice(index, 1);
      }
    }
    

    Best answer

    class Event {
      constructor() {
        this.subscribers = new Set();
      }
    
      subscribe(func) {
        this.subscribers.add(func);
      }
      
      unsubscribe(func) {
        this.subscribers.delete(func);
      }
      
      emit(...args) {
        this.subscribers.forEach(s => s(...args));
      }
    }
    

    好在哪?

    • 用了TS的class写法,避免对原型进行处理
    • 使用ES6原生对象Set,对函数的操作十分优雅

    Recap

    call/apply的区别?
    接受参数的不同:a in apply() for array of args and c in call() for comma between args(i.e comma separated arguments)

    theFunction.apply(valueForThis, arrayOfArgs)
    theFunction.call(valueForThis, arg1, arg2, ...)
    

    splice()为什么是插入删除小能手?

    let arrDeletedItems = array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
    

    start:开始index
    deleteCount:在该index开始删几个数
    items:要插入的item们

    相关文章

      网友评论

          本文标题:2020-05-13 5kyu Simple Events

          本文链接:https://www.haomeiwen.com/subject/lolonhtx.html