Javascript 使用三元运算符检查空值

Javascript 使用三元运算符检查空值,javascript,null,ternary-operator,Javascript,Null,Ternary Operator,在下面的代码中,我传递一个HMTL元素,并使用三元运算符检查传递的参数是否为null。如果不为null,则更改传递的元素的类名 var changeColorTo = { grey: function(e){ e ? (e.className = "grey") : "" ; }, red: function(e){ e ? (e.className = "red") : "" ; }, green: function(e){ e ? (e.clas

在下面的代码中,我传递一个HMTL元素,并使用三元运算符检查传递的参数是否为null。如果不为null,则更改传递的元素的类名

var changeColorTo = {

  grey: function(e){
    e ? (e.className = "grey") : "" ;
  },
  red: function(e){
    e ? (e.className = "red") : "" ;
  },
  green: function(e){
    e ? (e.className = "green") : "" ;
  },
  blue: function(e){
    e ? (e.className = "blue") : "" ;
  }
};
上面的代码工作正常,除非我传递任何随机字符串,如

changeColorTo.grey("random");
它不会造成任何伤害。但我想知道上面的代码是否正确?我错过什么了吗?或者有没有更好的方法达到同样的效果


谢谢。

如果您传入一个字符串,代码将正常工作。但是,如果希望确保只传入DOM元素(最好严格),可以将代码修改为:

function isNode(o){
  return (
    typeof Node === "object" ? o instanceof Node : 
    typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string"
  );
}    

function isElement(o){
  return (
    typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
    typeof o === "object" && o.nodeType === 1 && typeof o.nodeName==="string"
  );
}

var changeColorTo = {
    grey: function(e) {
        isNode(e) || isElement(e) ? (e.className = "grey") : "" ;
    },
    ...
}

有关
isNode
isElement
如何工作的更多信息,请参阅。此代码还将确保您不会尝试更改
null
undefined
变量的
className
属性,因为这些函数中的第一个条件(
o instanceof Node
o instanceof HTMLElement
)将失败,这将确保
isNode
isElement
对于
null
未定义的值将返回false。

如果传入字符串,则当前的代码将正常工作。但是,如果希望确保只传入DOM元素(最好严格),可以将代码修改为:

function isNode(o){
  return (
    typeof Node === "object" ? o instanceof Node : 
    typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string"
  );
}    

function isElement(o){
  return (
    typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
    typeof o === "object" && o.nodeType === 1 && typeof o.nodeName==="string"
  );
}

var changeColorTo = {
    grey: function(e) {
        isNode(e) || isElement(e) ? (e.className = "grey") : "" ;
    },
    ...
}

有关
isNode
isElement
如何工作的更多信息,请参阅。此代码还将确保您不会尝试更改
null
undefined
变量的
className
属性,因为这些函数中的第一个条件(
o instanceof Node
o instanceof HTMLElement
)将失败,这确保了
isNode
isElement
对于
null
未定义的
值将返回false。

您可以将条件从
e
扩展到
(e&&e.className)
。这应该可以防止由于传入随机垃圾甚至非元素节点而导致的脚本错误

更好的方法是将该条件实现为
函数hasClassName(e){return…}
,并使用
hasClassName(e)
作为测试


编辑:根据注释,替换了不完全兼容的
(typeof e==“object”)&&('className'在e中)
条件。另请参见

您可以将您的条件从
e
扩展到
(e&&e.className)
。这应该可以防止由于传入随机垃圾甚至非元素节点而导致的脚本错误

更好的方法是将该条件实现为
函数hasClassName(e){return…}
,并使用
hasClassName(e)
作为测试


编辑:根据注释,替换了不完全兼容的
(typeof e==“object”)&&('className'在e中)
条件。另请参见

如果您想简洁明了,可以编写
e&&e.className&&e.className=“grey”)完全没有三元。如果“更短”意味着更少的代码,那么在OP中它不是43个字符对32个字符。更少的代码本身并不是做任何事情的好理由。如果你想变得简短,你可以写
e&&e.className&&(e.className=“grey”)完全没有三元。如果“更短”指的是更少的代码,那么在OP中它不是43个字符对32个字符。更少的代码本身并不是做任何事情的好理由。如果e是一个宿主对象,那么没有理由相信它会为一个类型的测试返回“object”(主机对象不需要符合ECMA-262,在许多情况下也不需要)。因此,上述测试可能比
if(e&&e.className)…
之类的测试更容易出错,前提是e已经有了className属性。有趣。我没有遇到非“object”主机对象之前,但我们一直高度关注PC/Mac的流行浏览器。但是,他们不能也决定在成员查找上抛出异常,或者返回一个在布尔测试中爆炸的值吗?行为不端的主机对象很常见,那些在IE中使用ActiveX实现的主机对象臭名昭著(或臭名昭著)尽管浏览器开始在JavaScript上标准化™, 与ECMA-262保持一致,并为DOM对象实现原型继承,DOM的意图是语言中立,因此期望宿主对象实现一种特定语言的行为和特性并不符合web的精神(尽管HTML5似乎在很大程度上已经省去了这一点)@RobG我仍在学习Javascript(阅读Javascript:权威指南)。如果这是一个基本问题,请原谅,什么是“主机对象”?我看到了thread[我如何了解浏览器主机对象](),但没有如问卷所预期的明确答案。主机对象是主机环境提供的任何东西(如DOM元素)。严格来说,有内置对象,即ECMAScript提供的对象(对象、数组、数学等),也有本机对象,即使用ECMAScript构建的任何对象(例如
var obj={}
function foo(){}
),其他所有内容都必须由主机环境提供,主机对象也是如此(窗口、文档、XMLHttpRequest等)。如果e是一个主机对象,没有理由相信它会为一种类型的测试返回“object”(主机对象不需要符合ECMA-262,在许多情况下也不需要)。因此,上述测试可能比类似于
If(e&&e.className)的测试更容易出错…
,前提是e已经有一个className属性。有趣。我没有遇到非“object”主机对象之前,但我们一直高度关注PC/Mac的流行浏览器。但是,他们不能也决定在成员查找上抛出异常,或者返回一个在布尔测试中爆炸的值吗?行为不端的主机对象很常见,那些在IE中使用ActiveX实现的主机对象因此而臭名昭著(或臭名昭著)。Thoug