考虑以下示例:
angular.module('demo')
.service('MyService', function () {
this.fn = function () {
console.log('MyService:fn');
};
})
.factory('MyFactory', function () {
function fn() {
console.log('MyFactory:fn');
}
return { fn: fn };
})
.value('MyValue', {
fn: function () {
console.log('MyValue:fn');
}
})
.constant('MyConstant', {
fn: function () {
console.log('MyConstant:fn');
}
})
.run(function (MyService, MyFactory, MyValue, MyConstant) {
MyService.fn();
MyFactory.fn();
MyValue.fn();
MyConstant.fn();
MyService.fn = undefined;
MyFactory.fn = undefined;
MyValue.fn = undefined;
MyConstant.fn = undefined;
})
.run(function (MyService, MyFactory, MyValue, MyConstant) {
MyService.fn();
MyFactory.fn();
MyValue.fn();
MyConstant.fn();
});
当执行第一个run()
时,所有4个控制台日志都将被执行并在控制台上打印一些内容。然后,为了简化目的,我将每个提供程序 fn
函数设置为未定义,假设有人在某处重写了该函数(这是我想阻止的)。
在第二个 run()
block 上,所有内容都未定义,并且将引发错误。我对此感到困惑......至少其中一些(首先想到的是常量
)不应该是不可变的对象吗?
这是预期的行为还是我做错了什么?
最佳答案
为什么这是一个惊喜。 Angular 是一个运行在 Javascript 之上的框架,而 Javascript 是一种动态语言。你的问题实际上是关于语言结构的。
首先,认识到所有调用最终都会注册一个将返回要注入(inject)的对象的提供程序。 .service
、.factory
和 .value
只是 .provider
的缩写(.constant
有点不同)。
一旦确定对象被注入(inject)后它们之间就没有区别,那么您需要关心的是如何使该对象不可变。
Javascript提供了Object.freeze
函数,例如,你可以这样做:
var immutable = {
fn: function () {
console.log('MyConstant:fn');
}
};
Object.freeze(immutable);
app.constant("MyConstant", immutable);
关于angularjs - 如何在 AngularJS 中创建任何类型的不可变提供者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28262233/