关于js继承属性的一些疑惑
最近闲着无聊,看了下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上的,所以是本地属性,不继承,自己看的太不仔细了