“Natural Earth II“ === “Natural Earth II“是false?你知道空 格的四种写法吗?

前言

有一回对我说道,“你学过前端么?”我略略点一点头。他说,“学过前端?……我便考你一考。html 里面的空格,怎样 coding 的?”我想,讨饭一样的人,也配考我么?便回过脸去,不再理会。孔乙己等了许久,很恳切的说道,“不能写罢?……我教给你,记着!这些 code 应该记着。将来做 leader 的时候,coding 要用。”我暗想我和 leader 的等级还很远呢,而且我们 leader 也从不 coding;又好笑,又不耐烦,懒懒的答他道,“谁要你教,不是&后面坠一串 nbsp;么?”孔乙己显出极高兴的样子,将两个指头的长指甲敲着柜台,点头说,“对呀对呀!……空格有四样写法,你知道么?”

天下何人不孔乙己!() 不开玩笑啦!接下来来细究一下这个空格的的四种写法,实际上是六种编码方式,后面会用代码来验证。

问题来源

在编写关于 Cesium 的代码的时候,我想用 filter 过滤使用提供的默认选择地图,然后使用名字来作为条件,然后就有了如下图所示的问题,主要还是太相信自己的眼睛了,这个问题和写什么代码没有太大关系,主要是对于 utf8 字符集编码中空格区别的认识。

“Natural Earth II“ === “Natural Earth II“是false?你知道空 格的四种写法吗?_第1张图片

上图中把控制台输出的两个字符串复制,在 Chrome 浏览器的控制台中做比较会发现,他们两个不相等,虽然看起来一毛一样。

下面是遇到问题的源代码,由于是自己的 http 服务,所以大家可能要自己引入 CDN 或者别的方法配置一下,这里不做赘述了。

<html>
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>rollup-testtitle>
    <style>
      html,
      body,
      #cesiumContainer {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
      }
      .cesium-viewer-bottom {
        display: none !important;
      }
    style>
    
    <link href="./cesium/Build/Cesium/Widgets/widgets.css" rel="stylesheet" />
  head>

  <body>
    <div id="cesiumContainer">div>
    
    <script type="module">
      import * as Cesium from "./cesium/Build/Cesium/index.js";

      window.CESIUM_BASE_URL = "./cesium/Build/Cesium";
      const viewer = new Cesium.Viewer("cesiumContainer");
      const viewModel = viewer.baseLayerPicker.viewModel;
      viewModel.selectedImagery = viewModel.imageryProviderViewModels.filter(
        ({ name }) => name === "Natural Earth II"
      )[0];

      const i =
        viewModel.imageryProviderViewModels[
          viewModel.imageryProviderViewModels.length - 1
        ];
      console.log(`${i.name}\nNatural Earth II`);
      console.log(i.name === "Natural Earth II");
    script>
  body>
html>

如何解决?为什么?

其实一开始我还是找了老半天问题,如果不是 VsCode 我可能还需要再找半天才能知道,我把两个字符串都复制到 VsCode 中发现 VsCode 有提示(如下图提示),正常敲的空格没啥问题,但是这种格式的空格,查了一下才知道,原来是一种特有的空格编码,其作用是为了防止空格两边的单词换行,只能说 Cesium 源码的库实在是太细致了,这一点都做了优化,可以看到 Natural 和 Earth 之间是正常的空格,但是 Earth 和 II 直接为了防止换行,所以使用了非断行空格,目的就是为了保证让 Earth 字符和 II 字符在一行内显示,依据查到的资料显示,这种空格输入方式是按住alt然后数字键盘输入1060再松开 alt 键(即alt+1060),还可以用到系统文件名中,只不过不建议这样尝试,因为可能会遇到许多问题。

“Natural Earth II“ === “Natural Earth II“是false?你知道空 格的四种写法吗?_第2张图片

知道问题的来源之后,就可以解决"Natural Earth II" === "Natural Earth II"为什么等于false的问题了,这段字符串中前面是用了alt+1060,而后面是键入空格,所以只要保持两边空格字符编码一致就可以了。请不要直接复制这串等式到控制台验证,下面有解释原因。

解决这个问题后,就赶紧修复了代码问题,但是回头仔细想想,Cesium 开发人员应该不能用alt+1060这种方式输入空格吧,这不合理,然后打开调试窗口查看了一下该出字符的原文(如下图所示),在 Cesium 源代码里面也是 ,这不就是刚开始学前端的时候 html 对特殊字符的处理吗,就是把关键的字符都做了转义,除了空格,还有许多特殊字符,比如左右尖括号,这里就不过多赘述了,这是前端开发者的基本知识。

“Natural Earth II“ === “Natural Earth II“是false?你知道空 格的四种写法吗?_第3张图片

往后面再延伸一步,为啥 和我直接敲的空格不一样?我又编写 html 把 输出到页面,发现在网页中展示的空格和我手敲的是一个字符,但是在 js 代码里面输出到控制台的又不一样。所以同样的 如果在浏览器页面内复制是和键入的空格一样的字符,但是直接获取到 Elemnt 中的 innerText 用 js 输出这种空格,则编码格式和键入的空格不同;在这基础上我又查了一下 utf8 里面到底有多少种空格编码。最后用代码做了验证,如下文所示。

代码验证

将下面这段代码,复制到浏览器控制台直接回车,可以看到后面附上的结果图片,这里只验证了 js;如果 直接输出到页面再复制对比,实际上和键入的空格是一致的,这个可自行验证尝试。

function charToUtf8(text) {
  return text.charCodeAt(0).toString(16);
}

//     /*非断行空格*/ 键入方式:alt+0160
//     /*半角空格*/
//     /*全角空格*/
//   /*窄空格*/
// ‌   /*零宽不连字空格*/
// ‍    /*零宽连字空格*/
const spaceList = {
  输入空格: " ",
  非断行空格: " ",
  半角空格: " ",
  全角空格: " ",
  窄空格: " ",
  零宽不连字空格: "‌",
  零宽连字空格: "‍"
};
for (let [key, val] of Object.entries(spaceList)) {
  const myDiv = document.createElement("div");
  myDiv.innerHTML = val;
  console.log(key, `'${myDiv.innerText}'`, myDiv, charToUtf8(myDiv.innerText));
}

上述代码运行结果(空格类型+输出+元素+utf8 编码):
“Natural Earth II“ === “Natural Earth II“是false?你知道空 格的四种写法吗?_第4张图片

有什么实际意义?

如果非要说有什么意义的话,那就是没有意义,对于写代码来说其实很少会遇到这种问题;唯一的作用就是遇到像我这样的问题至少能知道为啥,如果不搞清楚就很难知道问题的根本原因,所以多少还是可以了解一下;当然在实际的应用中,对于一些排版文字,对这些编码是有明确要求的,空格输入的这几种方式参考了这篇文章——空格的 6 种 Html 书写形式。

如果本篇文章对您有帮助欢迎点赞、收藏、转发,非常感谢您的支持(~ ̄ ▽  ̄)~

你可能感兴趣的:(前端,typescript)