“injector.js”中的“getService”是如何从angular中的调用方访问本地变量的
How did `getService` in `injector.js` access local variable from its caller in angular?
考虑官方角度存储库中的以下代码
function createInjector(modulesToLoad, strictDi) {
strictDi = (strictDi === true);
var testingScope = 'this is a test';
var INSTANTIATING = {},
providerSuffix = 'Provider',
path = [],
loadedModules = new HashMap([], true),
providerCache = {
$provide: {
provider: supportObject(provider),
factory: supportObject(factory),
service: supportObject(service),
value: supportObject(value),
constant: supportObject(constant),
decorator: decorator
}
},
providerInjector = (providerCache.$injector =
createInternalInjector(providerCache, function(serviceName, caller) {
if (angular.isString(caller)) {
path.push(caller);
}
throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- '));
})),
instanceCache = {},
protoInstanceInjector =
createInternalInjector(instanceCache, function(serviceName, caller) {
var provider = providerInjector.get(serviceName + providerSuffix, caller);
return instanceInjector.invoke(
provider.$get, provider, undefined, serviceName);
}),
instanceInjector = protoInstanceInjector;
providerCache['$injector' + providerSuffix] = { $get: valueFn(protoInstanceInjector) };
var runBlocks = loadModules(modulesToLoad);
instanceInjector = protoInstanceInjector.get('$injector');
instanceInjector.strictDi = strictDi;
forEach(runBlocks, function(fn) { if (fn) instanceInjector.invoke(fn); });
return instanceInjector;
和
function createInternalInjector(cache, factory) {
function getService(serviceName, caller) {
console.log(testingScope);
if (cache.hasOwnProperty(serviceName)) {
if (cache[serviceName] === INSTANTIATING) {
throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
serviceName + ' <- ' + path.join(' <- '));
}
return cache[serviceName];
} else {
try {
path.unshift(serviceName);
cache[serviceName] = INSTANTIATING;
return cache[serviceName] = factory(serviceName, caller);
} catch (err) {
if (cache[serviceName] === INSTANTIATING) {
delete cache[serviceName];
}
throw err;
} finally {
path.shift();
}
}
}
return {
get: getService,
};
}
我们看到createInternalInjector
能够访问其调用方的作用域createInjector
中的局部变量(如path
),而无需传入参数。
事实上,如果我将testingScope
添加到createInjector
并尝试在createInternalInjector
中访问,我就可以做到
这很奇怪,因为我试图像下面这样复制这种行为。
testOuter();
function testOuter() {
var outer = 'outer'
testInner().test();
}
function testInner() {
function testing() {
console.log(outer);
}
return {
test: testing
}
}
但却出现了错误。
ReferenceError: outer is not defined
有人能告诉我为什么会发生这种事吗?
这里的问题是范围链接。createInternalInjector
函数是在createInjector
函数中调用的,因此它可以访问其父属性。在您的案例中,您有不知道彼此变量的兄弟函数。
有关作用域链和闭包的更多信息:https://stackoverflow.com/a/1484230/5954939
相关文章:
- 为什么可以't在对指令的html调用中访问$rootScope
- 如何在下一次 AJAX 调用中访问从一个 AJAX 调用返回的变量
- 在 JavaScript 中捕获调用方的范围
- .load() 事件在 SVG 完成加载后未被调用/无法访问其内容
- 您可以从方法外部识别事件的调用方吗
- 访问外部调用方函数参数
- 在JavaScript中查找调用方脚本
- 事件调用方似乎无法正常工作
- JS - 无法在自定义事件的处理程序中将其指向调用方
- 获取模式调用方
- JavaScript 函数 通过调用 Element 访问此内容
- 流星,如何将回调和错误传递给调用方方法
- 我怎么知道谁是 js 函数的调用方
- 如何在上一次 JQuery 调用后访问 DOM
- 如果被调用方被定义为变量,JavaScript 函数能否知道调用它的内容
- JavaScript 允许调用函数访问调用函数变量
- 获取被调用方之一的 Function.Arguments.Arguments
- jQuery:跨域 AJAX 调用导致“访问受限 URI 被拒绝”(代码 1012)
- 将Finuploader与ASP.NET Web表单一起使用.对严格模式调用方函数的访问被审查
- “injector.js”中的“getService”是如何从angular中的调用方访问本地变量的