Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/439.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript相当于C“s”;“受保护”;_Javascript_Javascript Objects - Fatal编程技术网

Javascript相当于C“s”;“受保护”;

Javascript相当于C“s”;“受保护”;,javascript,javascript-objects,Javascript,Javascript Objects,下面的代码使用Javascript创建一个基类,eventRaiser,该基类具有允许客户端订阅事件所需的内部结构,以及引发这些事件的子类。其思想是,其他类,如ThingWithEvent,将继承eventRaiser,并公开subscribe方法,并在内部触发raise方法。jqueryinit函数演示了这一点 按照编写方式,没有任何东西可以阻止客户端直接引发事件。换句话说,添加er.raise(“Y”)会毫无困难地引发Y事件 理想情况下,我希望使外部代码通过继承自它的某个类与eventRai

下面的代码使用Javascript创建一个基类,
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)