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

Bol*_*ock 3 html javascript dom

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

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

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

p.null {
  color: red;
}
Run Code Online (Sandbox Code Playgroud)
<p class="a b c">
<p class="x y z">
Run Code Online (Sandbox Code Playgroud)

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

我本来希望className = null擦除class属性,或者null为了目的而转换为空字符串className,或者至少会产生TypeError.

是什么赋予了?

Bol*_*ock 6

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

var x = String(null);
console.log(x);
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

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

p.null {
  color: red;
}
Run Code Online (Sandbox Code Playgroud)
<p class="a b c">
<p class="x y z">
Run Code Online (Sandbox Code Playgroud)

(你也可以classList单独迭代和删除每个类,如果你不关心浏览器兼容性.有趣的是,对于性能爱好者来说,修改classList实际上比设置更快className- 请参阅下面的评论.可能,设置className有副作用也是更新classList,这可能是它变慢的原因.)

  • 非常反直觉,在针对*[较新的浏览器](http://caniuse.com/)时,迭代`classList`会[更快](http://jsperf.com/empty-classname-vs-classlist/2) #搜索=班级名册)* (2认同)