From 9af18c2fd07129171fbacd528ad109adfdb9f784 Mon Sep 17 00:00:00 2001 From: Benedikt Meurer Date: Mon, 28 Jan 2019 15:14:05 +0100 Subject: [PATCH] perf(core): be more consistent about typeof checks (#28400) When testing whether `value` is an object, use the ideal sequence of strictly not equal to `null` followed by `typeof value === 'object'` consistently. Specifically there's no point in using double equal with `null` since `undefined` is ruled out by the `typeof` check. Also avoid the unnecessary ToBoolean check on `value.ngOnDestroy` in `hasOnDestroy()`, since the `typeof value.ngOnDestroy === 'function'` will only let closures pass and all closures are truish (with the notable exception of `document.all`, but that shouldn't be relevant for the `ngOnDestroy` hook). PR Close #28400 --- packages/core/src/di/r3_injector.ts | 4 ++-- packages/core/src/render3/interfaces/injector.ts | 2 +- packages/core/src/view/ng_module.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/core/src/di/r3_injector.ts b/packages/core/src/di/r3_injector.ts index 2f16c70f6d..c618d5d5b3 100644 --- a/packages/core/src/di/r3_injector.ts +++ b/packages/core/src/di/r3_injector.ts @@ -435,7 +435,7 @@ function deepForEach(input: (T | any[])[], fn: (value: T) => void): void { } function isValueProvider(value: SingleProvider): value is ValueProvider { - return value && typeof value == 'object' && USE_VALUE in value; + return value !== null && typeof value == 'object' && USE_VALUE in value; } function isExistingProvider(value: SingleProvider): value is ExistingProvider { @@ -456,7 +456,7 @@ function hasDeps(value: ClassProvider | ConstructorProvider | StaticClassProvide } function hasOnDestroy(value: any): value is OnDestroy { - return typeof value === 'object' && value != null && (value as OnDestroy).ngOnDestroy && + return value !== null && typeof value === 'object' && typeof(value as OnDestroy).ngOnDestroy === 'function'; } diff --git a/packages/core/src/render3/interfaces/injector.ts b/packages/core/src/render3/interfaces/injector.ts index f93fd5f18a..9b8a6695e8 100644 --- a/packages/core/src/render3/interfaces/injector.ts +++ b/packages/core/src/render3/interfaces/injector.ts @@ -248,7 +248,7 @@ export class NodeInjectorFactory { const FactoryPrototype = NodeInjectorFactory.prototype; export function isFactory(obj: any): obj is NodeInjectorFactory { // See: https://jsperf.com/instanceof-vs-getprototypeof - return obj != null && typeof obj == 'object' && Object.getPrototypeOf(obj) == FactoryPrototype; + return obj !== null && typeof obj == 'object' && Object.getPrototypeOf(obj) == FactoryPrototype; } // Note: This hack is necessary so we don't erroneously get a circular dependency diff --git a/packages/core/src/view/ng_module.ts b/packages/core/src/view/ng_module.ts index cfd5462e92..a09f79943d 100644 --- a/packages/core/src/view/ng_module.ts +++ b/packages/core/src/view/ng_module.ts @@ -158,7 +158,7 @@ function _createProviderInstance(ngModule: NgModuleData, providerDef: NgModulePr // avoided if possible. The sequence of checks here determines whether ngOnDestroy needs to be // checked. It might not if the `injectable` isn't an object or if NodeFlags.OnDestroy is already // set (ngOnDestroy was detected statically). - if (injectable !== UNDEFINED_VALUE && injectable != null && typeof injectable === 'object' && + if (injectable !== UNDEFINED_VALUE && injectable !== null && typeof injectable === 'object' && !(providerDef.flags & NodeFlags.OnDestroy) && typeof injectable.ngOnDestroy === 'function') { providerDef.flags |= NodeFlags.OnDestroy; }