关于js继承属性的一些疑惑
发布于 7 年前 作者 qichangjun 3175 次浏览 来自 问答

最近闲着无聊,看了下dropzone.js的源码,发现有个问题: 源代码中新建了一个Emitter的构造函数,用来实现消息的收发,

	Emitter = (function() {
		function Emitter() {}

		Emitter.prototype.addEventListener = Emitter.prototype.on;
		//监听自定义事件,并触发所有该事件的监听函数
		Emitter.prototype.on = function(event, fn) {
		  this._callbacks = this._callbacks || {};
		  if (!this._callbacks[event]) {
			this._callbacks[event] = [];
		  }
		  this._callbacks[event].push(fn);
		  return this;
		};
		//注册自定义事件
	  Emitter.prototype.emit = function() {
		var args, callback, callbacks, event, j, len;
		event = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
		this._callbacks = this._callbacks || {};
		callbacks = this._callbacks[event];
		if (callbacks) {
		  for (j = 0, len = callbacks.length; j < len; j++) {
			callback = callbacks[j];
			callback.apply(this, args);
		  }
		}
		return this;
	  };
	...
  return Emitter;

})();

Emitter上添加了on,emit两个继承属性,用来注册和监听自定义事件,然后在Dropzone构造函数中是这样用的:

Dropzone = (function(superClass) {
  ...
	//这里的Emitter就是上面Emitter函数返回的Emitter,这里把他赋值给了Dropzone的继承属性中
  Dropzone.prototype.Emitter = Emitter;
  ...
  //在某个函数中注册了一个自定义事件:sending
  //其实就是在文件上传中,会触发一次这个事件
  this.emit("sending", file, xhr, formData);
 ...
 //还有一点不明白的就是这里将Emitter作为superClass参数传进去了,然后又在函数内部直接引用了Emitter
 }) ( Emitter )

当时我猜想,既然是赋值给了继承属性,那我new一个DropA和DropB, 这两个实例应该会监听同一个 sending 事件把,于是我试着测了下

var options = {
        url : 'test.php'            
    }
    var DropA = new Dropzone(document.getElementById('dropzoneA'),options)
    var DropB = new Dropzone(document.getElementById('dropzoneB'),options)
    DropA.on('sending',function(files,xhr){
        console.log(1234)
    })
    DropB.on('sending',function(files,xhr){
        console.log('32323232')
    })

发现两者的监听事件竟然没有冲突,DropA只会监听到 DropA.on,有哪位大神能根我解释下原因吗?

1 回复

找到原因了,注册事件是注册在this._callback上的,所以是本地属性,不继承,自己看的太不仔细了

回到顶部