refactor(*): introduce isNumberNaN
window.isNaN(‘lol’); //=> true Number.isNaN(‘lol’); //=> false isNaN converts it’s arguments into a Number before checking if it’s NaN. In various places in the code base, we are checking if a variable is a Number and NaN (or not), so this can be simplified with this new method (which is not exported on the global Angular object). Closes #11242
This commit is contained in:
@@ -45,6 +45,7 @@
|
||||
"isObject": false,
|
||||
"isString": false,
|
||||
"isNumber": false,
|
||||
"isNumberNaN": false,
|
||||
"isDate": false,
|
||||
"isArray": false,
|
||||
"isFunction": false,
|
||||
|
||||
+7
-1
@@ -40,6 +40,7 @@
|
||||
isBlankObject,
|
||||
isString,
|
||||
isNumber,
|
||||
isNumberNaN,
|
||||
isDate,
|
||||
isArray,
|
||||
isFunction,
|
||||
@@ -412,6 +413,11 @@ function toInt(str) {
|
||||
return parseInt(str, 10);
|
||||
}
|
||||
|
||||
var isNumberNaN = Number.isNaN || function isNumberNaN(num) {
|
||||
// eslint-disable-next-line no-self-compare
|
||||
return num !== num;
|
||||
};
|
||||
|
||||
|
||||
function inherit(parent, extra) {
|
||||
return extend(Object.create(parent), extra);
|
||||
@@ -1276,7 +1282,7 @@ function timezoneToOffset(timezone, fallback) {
|
||||
// IE/Edge do not "understand" colon (`:`) in timezone
|
||||
timezone = timezone.replace(ALL_COLONS, '');
|
||||
var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
|
||||
return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
|
||||
return isNumberNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1526,7 +1526,7 @@ function parseNumberAttrVal(val) {
|
||||
if (isDefined(val) && !isNumber(val)) {
|
||||
val = parseFloat(val);
|
||||
}
|
||||
return isNumber(val) && !isNaN(val) ? val : undefined;
|
||||
return !isNumberNaN(val) ? val : undefined;
|
||||
}
|
||||
|
||||
function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
||||
@@ -1650,7 +1650,7 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
||||
function minChange(val) {
|
||||
minVal = parseNumberAttrVal(val);
|
||||
// ignore changes before model is initialized
|
||||
if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
|
||||
if (isNumberNaN(ctrl.$modelValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1671,7 +1671,7 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
||||
function maxChange(val) {
|
||||
maxVal = parseNumberAttrVal(val);
|
||||
// ignore changes before model is initialized
|
||||
if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
|
||||
if (isNumberNaN(ctrl.$modelValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1693,7 +1693,7 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
||||
function stepChange(val) {
|
||||
stepVal = parseNumberAttrVal(val);
|
||||
// ignore changes before model is initialized
|
||||
if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
|
||||
if (isNumberNaN(ctrl.$modelValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -552,7 +552,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
||||
*/
|
||||
this.$validate = function() {
|
||||
// ignore $validate before model is initialized
|
||||
if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
|
||||
if (isNumberNaN(ctrl.$modelValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -723,7 +723,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
|
||||
if (isNumberNaN(ctrl.$modelValue)) {
|
||||
// ctrl.$modelValue has not been touched yet...
|
||||
ctrl.$modelValue = ngModelGet($scope);
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
|
||||
|
||||
scope.$watch(numberExp, function ngPluralizeWatchAction(newVal) {
|
||||
var count = parseFloat(newVal);
|
||||
var countIsNaN = isNaN(count);
|
||||
var countIsNaN = isNumberNaN(count);
|
||||
|
||||
if (!countIsNaN && !(count in whens)) {
|
||||
// If an explicit number rule such as 1, 2, 3... is defined, just use it.
|
||||
@@ -216,7 +216,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
|
||||
|
||||
// If both `count` and `lastCount` are NaN, we don't need to re-register a watch.
|
||||
// In JS `NaN !== NaN`, so we have to explicitly check.
|
||||
if ((count !== lastCount) && !(countIsNaN && isNumber(lastCount) && isNaN(lastCount))) {
|
||||
if ((count !== lastCount) && !(countIsNaN && isNumberNaN(lastCount))) {
|
||||
watchRemover();
|
||||
var whenExpFn = whensExpFns[count];
|
||||
if (isUndefined(whenExpFn)) {
|
||||
|
||||
@@ -259,7 +259,7 @@ var maxlengthDirective = function() {
|
||||
var maxlength = -1;
|
||||
attr.$observe('maxlength', function(value) {
|
||||
var intVal = toInt(value);
|
||||
maxlength = isNaN(intVal) ? -1 : intVal;
|
||||
maxlength = isNumberNaN(intVal) ? -1 : intVal;
|
||||
ctrl.$validate();
|
||||
});
|
||||
ctrl.$validators.maxlength = function(modelValue, viewValue) {
|
||||
|
||||
@@ -106,7 +106,7 @@ function limitToFilter() {
|
||||
} else {
|
||||
limit = toInt(limit);
|
||||
}
|
||||
if (isNaN(limit)) return input;
|
||||
if (isNumberNaN(limit)) return input;
|
||||
|
||||
if (isNumber(input)) input = input.toString();
|
||||
if (!isArrayLike(input)) return input;
|
||||
|
||||
+1
-2
@@ -806,8 +806,7 @@ function $RootScopeProvider() {
|
||||
if ((value = get(current)) !== (last = watch.last) &&
|
||||
!(watch.eq
|
||||
? equals(value, last)
|
||||
: (typeof value === 'number' && typeof last === 'number'
|
||||
&& isNaN(value) && isNaN(last)))) {
|
||||
: (isNumberNaN(value) && isNumberNaN(last)))) {
|
||||
dirty = true;
|
||||
lastDirtyWatch = watch;
|
||||
watch.last = watch.eq ? copy(value, null) : value;
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"isObject": false,
|
||||
"isString": false,
|
||||
"isNumber": false,
|
||||
"isNumberNaN": false,
|
||||
"isDate": false,
|
||||
"isArray": false,
|
||||
"isFunction": false,
|
||||
|
||||
@@ -1375,7 +1375,7 @@ describe('select', function() {
|
||||
expect(element.find('option').eq(0).val()).toBe('? boolean:false ?');
|
||||
|
||||
browserTrigger(element.find('option').eq(0));
|
||||
if (typeof prop === 'number' && isNaN(prop)) {
|
||||
if (isNumberNaN(prop)) {
|
||||
expect(scope.selected).toBeNaN();
|
||||
} else {
|
||||
expect(scope.selected).toBe(prop);
|
||||
@@ -1419,7 +1419,7 @@ describe('select', function() {
|
||||
expect(selectController.removeOption.calls.count()).toBe(1);
|
||||
|
||||
// Updating the option value currently does not update the select model
|
||||
if (typeof prop === 'number' && isNaN(prop)) {
|
||||
if (isNumberNaN(prop)) {
|
||||
expect(selectController.removeOption.calls.argsFor(0)[0]).toBeNaN();
|
||||
} else {
|
||||
expect(selectController.removeOption.calls.argsFor(0)[0]).toBe(prop);
|
||||
|
||||
Reference in New Issue
Block a user