简体   繁体   English

Javascript私有函数和object.prototype扩展

[英]Javascript private functions and object.prototype extend

I have the following angularJS service 我有以下angularJS服务

define(["angular"], function(Angular) {

var dataStorageService = function() {
    var serviceConstructor = function() {
        var _getColor = function(color) {
            return this.config.categoryColorMapping.colors[color];
        }
    }

    var serviceInstance = new serviceConstructor();

    angular.extend(serviceInstance.prototype, {
        config: {
            numberOfMessagesDisplayed: 5,
            maxTitleLength: 48,
            maxPreambleLength: 140,
            categoryColorMapping: {
                colors : {
                    nyheter: '#2B2B2B',
                    sport: '#F59331',
                    underholding: '#F9B00D'
                },
                categories: {
                    nyheter: _getColor('nyheter'),
                    sport: _getColor('sport'),
                    underholding: _getColor('underholding')
                }
            }
        },
        get: function(param) {
            if(this.config.hasOwnProperty(param)) {
                return this.config[param];
            } else {
                console.warn('Playlist::configService:no "' + param + '" config found');
                return false;
            }
        },
        set: function(param, value) {
            this.config[param] = value;
        }
    });

    return serviceInstance;
};

return dataStorageService;
});

now my goal is to make public the following methods: 现在,我的目标是公开以下方法:

  1. get 得到
  2. set

and I want '_getColor' method private but I want to use it within the JSON object config. 并且我想将'_getColor'方法设为私有,但是我想在JSON对象配置中使用它。 When I run the code I have 当我运行代码时

"ReferenceError: _getColor is not defined" “ ReferenceError:_getColor未定义”

is it possibie to achievie it this way? 这样可以实现吗? (to have _getColor private and use it within the JSON object within angular.extend?) (要具有_getColor私有并在angular.extend的JSON对象中使用它?)

Functions added to the prototype are defined outside the lexical scope of the constructor, and therefore have no access to "private" methods. 添加到prototype函数是在构造函数的词法范围之外定义的,因此无法访问“私有”方法。

The former are shared between all instances, and the latter are per-instance. 前者在所有实例之间共享,后者在每个实例之间共享。 The only way to get around this is to explicitly export the (per-instance) function as a property of the instance, making it non-private. 解决此问题的唯一方法是将(每个实例)函数显式导出为实例的属性,使其成为非私有的。

Functions can be shared and still be private, instance specific private members have to be defined in the constructor though. 函数可以共享,也可以是私有的,但是必须在构造函数中定义实例专用的私有成员。 Since your private function doesn't need to access instance specific private members you can do the following: 由于您的私有函数不需要访问实例特定的私有成员,因此可以执行以下操作:

define(["angular"], function(Angular) {

var dataStorageService = function() {
    var serviceConstructor = function() {
    }

    var serviceInstance = new serviceConstructor();
    //IIFE returning object that will have private members as closure
    // privileged methods have to be in the same function body as the
    // private fucnction
    serviceInstance.prototype = (function() {
        var _getColor = function(instance, color) {
            return instance.config.categoryColorMapping.colors[color];
        };
        return {
          constructor: serviceConstructor
          ,config: {
            numberOfMessagesDisplayed: 5,
            maxTitleLength: 48,
            maxPreambleLength: 140,
            categoryColorMapping: {
                colors : {
                    nyheter: '#2B2B2B',
                    sport: '#F59331',
                    underholding: '#F9B00D'
                },
                categories: {
                    //since categories is a sub object of serviceinstance.categorycolormapper
                    // it is not possible to get the instance of serviceinstance
                    // at this time unless you set it in the constructor
                    // solution could be that each serviceinstance has it's own categorycolormaper
                    // and when categorycolormapper is created pass the serviceinstance instance
                    nyheter: _getColor(this,'nyheter'),
                    sport: _getColor(this, 'sport'),
                    underholding: _getColor(this, 'underholding')
                }
            }
          },
          get: function(param) {
            if(this.config.hasOwnProperty(param)) {
                return this.config[param];
            } else {
                console.warn('Playlist::configService:no "' + param + '" config found');
                return false;
            }
          },
          set: function(param, value) {
            this.config[param] = value;
          }
        }
    }());

    return serviceInstance;
};

return dataStorageService;
});

More info on constructor functions and prototype can be found here: https://stackoverflow.com/a/16063711/1641941 有关构造函数和原型的更多信息,请参见: https : //stackoverflow.com/a/16063711/1641941

serviceConstructor的定义内,在_getColor的定义后添加以下行

serviceConstructor.prototype._getColor = _getColor ;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM