最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

performance - Null checking in Javascript (with ternary operator) - Stack Overflow

programmeradmin3浏览0评论

want to check null values. any() method returns null or array of matched result (actually there's a match() method inside which is returned).

$scope.isMobileBrowser = !isMobile.any() ? false : true;

If any() method returns null I want false to be assigned to $scope.isMobileBrowser variable, otherwise true. will the over mentioned snippet fail in any probable case? Is there any other more efficient workaround?

for more details of isMobile object:

var isMobile = {
    Android: function() {
        return navigator.userAgent.match(/Android/i);
    },
    BlackBerry: function() {
        return navigator.userAgent.match(/BlackBerry/i);
    },
    iOS: function() {
        return navigator.userAgent.match(/iPhone|iPad|iPod/i);
    },
    Opera: function() {
        return navigator.userAgent.match(/Opera Mini/i);
    },
    Windows: function() {
        return navigator.userAgent.match(/IEMobile/i);
    },
    any: function() {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
};

want to check null values. any() method returns null or array of matched result (actually there's a match() method inside which is returned).

$scope.isMobileBrowser = !isMobile.any() ? false : true;

If any() method returns null I want false to be assigned to $scope.isMobileBrowser variable, otherwise true. will the over mentioned snippet fail in any probable case? Is there any other more efficient workaround?

for more details of isMobile object:

var isMobile = {
    Android: function() {
        return navigator.userAgent.match(/Android/i);
    },
    BlackBerry: function() {
        return navigator.userAgent.match(/BlackBerry/i);
    },
    iOS: function() {
        return navigator.userAgent.match(/iPhone|iPad|iPod/i);
    },
    Opera: function() {
        return navigator.userAgent.match(/Opera Mini/i);
    },
    Windows: function() {
        return navigator.userAgent.match(/IEMobile/i);
    },
    any: function() {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
};
Share Improve this question edited Oct 8, 2015 at 7:41 fatCop asked Oct 8, 2015 at 6:34 fatCopfatCop 2,58610 gold badges36 silver badges59 bronze badges 5
  • Is there any other more efficient workaround? - Are you sure that your program is slow just because of this line? – thefourtheye Commented Oct 8, 2015 at 6:35
  • No, it's not slow. I would like to know the correctness, also if there exists any other better options. – fatCop Commented Oct 8, 2015 at 6:36
  • 1 If you really don't need the returned array, use test() instead of match(). – Teemu Commented Oct 8, 2015 at 6:38
  • 1 String.match does not return a string. It returns null or Array. – Salman Arshad Commented Oct 8, 2015 at 6:57
  • Please add the any method as well too check what values will be returned. – sabithpocker Commented Oct 8, 2015 at 7:10
Add a ment  | 

4 Answers 4

Reset to default 5

Empty string is also a falsy value.
If any() returns an empty string, !isMobile.any() ? false : true will return false, but you probably want true.

This means your code is incorrect for this case.

I'd just do something like isMobile.any() !== null.

As per the any() function, you are returning value of the following expression:

(isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() 
                             || isMobile.Opera() || isMobile.Windows())

Each of these functions can either return an Array or null as seen in the doc for match

So while evaluating the OR it will evaluate to the first truth value encountered and doesnt evaluate any further as the expression is already fit to be true. So, for example if the browser is android the expression evaluates to ["Android"]. If windows it will be ["Windows"]. If none of these, it will be null. Which makes it clear that any() can only return an Array or null.

isMobileBrowser should be true if it's any of these mobile browsers, which means isMobileBrowser should be true if:

any() evaluates to an Array

OR in other way:

If any() does not evaluate to null

which is:

$scope.isMobileBrowser = isMobile.any() instanceof Array;//looks messy
$scope.isMobileBrowser = (isMobile.any()).constructor === Array;//looks messy
$scope.isMobileBrowser = Array.isArray(isMobile.any());//looks messy
$scope.isMobileBrowser = Object.prototype.toString.call(isMobile.any()) 
                                   === "[object Array]";//looks messy

OR the other way:

$scope.isMobileBrowser = isMobile.any() !== null;
$scope.isMobileBrowser = !(isMobile.any() === null);
isMobileBrowser = !(Object.prototype.toString.call(isMobile.any()) 
                                   === "[object Null]");//looks messy

So we just discussed different ways to check for null and Array. You have two possible sets of outputs

  1. null value which is always false
  2. An Array which is always true (You can check this empty array scenario although that doesn't apply here)

So you can simply do the following to convert those to exact boolean without worrying much:

isMobileBrowser = Boolean(isMobile.any()); //to convert value to boolean
isMobileBrowser = !!isMobile.any(); //another way to convert to boolean
                                   //!!["Android"] is true
                                   //!!null is false

@rossipedia explains the !! well in his answer.

A pact way of representing what you want would be:

$scope.isMobileBrowser = !!isMobile.any();

The !! there does two things:

  1. The first ! evaluates the "truthiness"1 of the return value of isMobile.any() and then negates it.
  2. The second ! negates that value again.

So what you end up with is false if .any() returns null, otherwise true.

However, this may fail in edge cases where .any() returns something that is "falsy". In that case, checking for null specifically is what you want:

isMobile.any() !== null

1: "Truthiness":

In JavaScript, a truthy value is a value that translates to true when evaluated in a Boolean context. All values are truthy unless they are defined as falsy (i.e., except for false, 0, "", null, undefined, and NaN).

From MDN

Try this:

$scope.isMobileBrowser = isMobile.any() === null;

发布评论

评论列表(0)

  1. 暂无评论