2016-08-01 3 views
0

我々はcreateInternalInjectorをパラメータにして通過することなくその呼び出し元のスコープcreateInjectorにローカル変数(pathなど)にアクセスすることが可能であることがわかり公式angular repository`injector.js`の` getService`は、呼び出し元のローカル変数に角度でアクセスしましたか?

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, 
    }; 
    } 

に次のコードを考えてみましょう。

実際にtestingScopecreateInjectorに追加して、createInternalInjectorにアクセスしようとしました。

次のようにこの動作を再現しようとしているので、これは奇妙です。

testOuter(); 

function testOuter() { 
    var outer = 'outer' 

    testInner().test(); 

} 

function testInner() { 
    function testing() { 
    console.log(outer); 
    } 
    return { 
     test: testing 
    } 
} 

代わりにエラーが発生しました。

ReferenceError: outer is not defined 

なぜこのようなことが起こっているのかを教えていただけますか?

答えて

1

ここでの問題は、スコープチェーンです。 createInternalInjector関数はcreateInjector関数内で呼び出されます。したがって、その親プロパティにアクセスできます。あなたのケースでは、お互いの変数に気づいていない兄弟関数があります。

スコープチェーンとクロージャの詳細:https://stackoverflow.com/a/1484230/5954939

関連する問題