为什么设置element.className = null会导致class =“null”?

时间:2015-03-20 05:43:20

标签: javascript html dom

显然,尝试将className属性设置为null不会删除class属性 - 而是将其替换为字面上称为“null”的类名:

document.querySelector('p:nth-of-type(2)').className = null;
p[class]::before {
  content: '<p class="' attr(class) '">';
}

p:not([class])::before, p[class=""]::before {
  content: '<p>';
}

p.null {
  color: red;
}
<p class="a b c">
<p class="x y z">

最重要的是,有完整的互操作。

我希望className = null删除class属性,或null为了className而转换为空字符串,或者至少它会产生一个TypeError。

是什么给出了?

1 个答案:

答案 0 :(得分:6)

在JavaScript中,null不会转换为空字符串。它会转换为字符串"null"。如果您手动转换它,您可以看到这个:

var x = String(null);
console.log(x);

MDN的DOMString文档中也提到了这一点:

  

null传递给接受DOMString的方法或参数通常会字符串化为"null"

className属性(以及id等相关属性)的类型为DOMString,它直接映射到JS中的String。正是这种转换产生了一个字面名称为“null”的类名,然后它反映在class属性中,并被.null[class~=null]等选择器匹配。

如果您期望null转换为空字符串,因为两者都是假值,那么它不会那样工作。仅仅因为两个值是假的,即当转换为布尔值时两个值都导致false,不会使这两个值等于彼此,甚至不会松散。特别是,大多数对象(包括字符串)从不松散地等于null,因为某些东西不能等于任何东西(由于遗留原因,有一些例外)。您可以参考一个方便的比较表here in MDN

要删除class属性并从元素中删除所有类名,请将className设置为空字符串而不是null:

document.querySelector('p:nth-of-type(2)').className = '';
p[class]::before {
  content: '<p class="' attr(class) '">';
}

p:not([class])::before, p[class=""]::before {
  content: '<p>';
}

p.null {
  color: red;
}
<p class="a b c">
<p class="x y z">

(您也可以迭代classList并单独删除每个类,如果browser compatibility is not a concern for you。有趣的是,对于表演爱好者来说,修改classList实际上比设置className更快 - 请参阅下面的评论。大概,设置className会产生更新{​​{1}}的副作用,这可能是它变慢的原因。)