Javascript相当于C“s”;“受保护”;
下面的代码使用Javascript创建一个基类,Javascript相当于C“s”;“受保护”;,javascript,javascript-objects,Javascript,Javascript Objects,下面的代码使用Javascript创建一个基类,eventRaiser,该基类具有允许客户端订阅事件所需的内部结构,以及引发这些事件的子类。其思想是,其他类,如ThingWithEvent,将继承eventRaiser,并公开subscribe方法,并在内部触发raise方法。jqueryinit函数演示了这一点 按照编写方式,没有任何东西可以阻止客户端直接引发事件。换句话说,添加er.raise(“Y”)会毫无困难地引发Y事件 理想情况下,我希望使外部代码通过继承自它的某个类与eventRai
eventRaiser
,该基类具有允许客户端订阅事件所需的内部结构,以及引发这些事件的子类。其思想是,其他类,如ThingWithEvent
,将继承eventRaiser
,并公开subscribe方法,并在内部触发raise方法。jqueryinit函数演示了这一点
按照编写方式,没有任何东西可以阻止客户端直接引发事件。换句话说,添加er.raise(“Y”)会毫无困难地引发Y事件
理想情况下,我希望使外部代码通过继承自它的某个类与eventRaiser
交互时,只能订阅事件,而不能引发事件
换句话说,我希望提升
成为C#受保护的
的等价物-仅对其自身和从其继承的类可见。
我是否应该使用一些巧妙的忍者闭包来实现这一点,或者我应该认识到Javascript不应该包含OO加密,将raise
重命名为\u raise
以向客户端代码暗示\u raise
是私有的,不应该被调用,然后继续
$(function() {
var er = new ThingWithEvent();
er.subscribe("X", function() { alert("Hello"); });
er.subscribe("X", function() { alert("World"); });
er.subscribe("Y", function() { alert("Not Called"); });
er.doSomething("X");
});
function eventRaiser() {
var events = {};
this.subscribe = function(key, func) {
if (!events[key])
events[key] = { name: key, funcs: [] };
events[key].funcs.push(func);
};
this.raise = function(key) {
if (!events[key]) return;
for (var i = 0; i < events[key].funcs.length; i++)
events[key].funcs[i]();
};
}
function ThingWithEvent() {
eventRaiser.call(this);
var self = this;
this.doSomething = function() {
alert("doing something");
self.raise("X");
}
}
function surrogate() { }
surrogate.prototype = eventRaiser;
ThingWithEvent.prototype = new surrogate();
ThingWithEvent.prototype.constructor = ThingWithEvent;
$(函数(){
var er=新事物WithEvent();
subscribe(“X”,function(){alert(“Hello”);});
订阅(“X”,function(){alert(“World”);});
subscribe(“Y”,function(){alert(“Not Called”);});
er.剂量测定法(“X”);
});
函数eventRaiser(){
var事件={};
this.subscribe=函数(键,func){
如果(!事件[键])
事件[key]={name:key,funcs:[]};
事件[key].func.push(func);
};
this.raise=功能(键){
如果(!events[key])返回;
对于(var i=0;i
阅读以下内容:
javascript中没有类,因此您可以使用this.subscribe(obj)
作为订阅方法,使用var-raise(event)
作为提升它们的私有方法,为事件管理器创建构造函数,这只能由它的实例调用
function EventRaiser () {
var foo = 1; // will be private
function raise() { ... }; // will be private
var raise1 = function () { ... }; // will be private
this.subscribe = function () { ... }; // will be privileged, has access to private vars and methods
this.foo = 1; // public, anyone can read/write
return this;
}
var er = new EventRaiser (); // here we make instance of constructor
er.subscribe(); // will work
er.raise(); // will THROW error, because it is 'private'
本地函数raise(event)
仅对eventRaiser
的实例可见,而对派生构造函数的实例不可见。(但他们将拥有自己的私人提升
功能,其他人无法访问)。阅读以下内容:
javascript中没有类,因此您可以使用this.subscribe(obj)
作为订阅方法,使用var-raise(event)
作为提升它们的私有方法,为事件管理器创建构造函数,这只能由它的实例调用
function EventRaiser () {
var foo = 1; // will be private
function raise() { ... }; // will be private
var raise1 = function () { ... }; // will be private
this.subscribe = function () { ... }; // will be privileged, has access to private vars and methods
this.foo = 1; // public, anyone can read/write
return this;
}
var er = new EventRaiser (); // here we make instance of constructor
er.subscribe(); // will work
er.raise(); // will THROW error, because it is 'private'
本地函数raise(event)
仅对eventRaiser
的实例可见,而对派生构造函数的实例不可见。(但他们将拥有自己的私人提升
功能,其他人无法访问)。考虑:
function ThingWithEvent() {
var thing = {},
events = {};
function raise( key ) {
if ( !events[ key ] ) { return; }
for ( var i = 0; i < events[ key ].funcs.length; i++ )
events[ key ].funcs[ i ]();
}
thing.subscribe = function ( key, func ) {
if ( !events[ key ] ) {
events[ key ] = { name: key, funcs: [] };
}
events[ key ].funcs.push( func );
};
thing.doSomething = function () {
alert( "doing something" );
raise( "X" );
};
return thing;
}
用法:
var thing = new Thing();
thing.subscribe( ... );
thing.doSomething( ... );
考虑:
function ThingWithEvent() {
var thing = {},
events = {};
function raise( key ) {
if ( !events[ key ] ) { return; }
for ( var i = 0; i < events[ key ].funcs.length; i++ )
events[ key ].funcs[ i ]();
}
thing.subscribe = function ( key, func ) {
if ( !events[ key ] ) {
events[ key ] = { name: key, funcs: [] };
}
events[ key ].funcs.push( func );
};
thing.doSomething = function () {
alert( "doing something" );
raise( "X" );
};
return thing;
}
用法:
var thing = new Thing();
thing.subscribe( ... );
thing.doSomething( ... );
通过返回具有有限接口的对象,可以更接近所需的内容:
function EventSource() {
var events = {};
var self = this;
this.subscribe = function(key, func) {
if (!events[key])
events[key] = { name: key, funcs: [] };
events[key].funcs.push(func);
};
this.raise = function(key) {
if (!events[key]) return;
for (var i = 0; i < events[key].funcs.length; i++)
events[key].funcs[i]();
};
this.limited = function() {
return {
subscribe: function(k, f) { return self.subscribe(k,f);}
};
};
}
函数EventSource(){
var事件={};
var self=这个;
this.subscribe=函数(键,func){
如果(!事件[键])
事件[key]={name:key,funcs:[]};
事件[key].func.push(func);
};
this.raise=功能(键){
如果(!events[key])返回;
对于(var i=0;i
然后,您可以在事件源上调用.limited()
,并获得一个可在上调用.subscribe()
,但不能调用.raise()
的受限访问对象。如果你能控制这些被实例化的地方,比如说,通过工厂,你可以限制损害
jQuery将此模式与它的延迟对象一起使用;有限对象称为promises
,是使用.promise()
创建的。通过返回具有有限接口的对象,您可以更接近所需的内容:
function EventSource() {
var events = {};
var self = this;
this.subscribe = function(key, func) {
if (!events[key])
events[key] = { name: key, funcs: [] };
events[key].funcs.push(func);
};
this.raise = function(key) {
if (!events[key]) return;
for (var i = 0; i < events[key].funcs.length; i++)
events[key].funcs[i]();
};
this.limited = function() {
return {
subscribe: function(k, f) { return self.subscribe(k,f);}
};
};
}
函数EventSource(){
var事件={};
var self=这个;
this.subscribe=函数(键,func){
如果(!事件[键])
事件[key]={name:key,funcs:[]};
事件[key].func.push(func);
};
this.raise=功能(键){
如果(!events[key])返回;
对于(var i=0;i
然后,您可以在事件源上调用.limited()
,并获得一个可在上调用.subscribe()
,但不能调用.raise()
的受限访问对象。如果你能控制这些被实例化的地方,比如说,通过工厂,你可以限制损害
jQuery将此模式与它的延迟对象一起使用;有限的对象被称为承诺
,是用.promise()
创建的。我讨厌回答我自己的问题,更不用说接受我自己的答案了,但事实证明这不仅是可能的,而且非常简单。这段代码背后的想法来自道格拉斯·克罗克福德(Douglas Crockford)。诀窍是抛弃构造函数(neocla)