"Natural Earth II" === "Natural Earth II"是false?你知道空 格的四种写法吗?
前言
有一回对我说道,“你学过前端么?”我略略点一点头。他说,“学过前端?……我便考你一考。html 里面的空格,怎样 coding 的?”我想,讨饭一样的人,也配考我么?便回过脸去,不再理会。孔乙己等了许久,很恳切的说道,“不能写罢?……我教给你,记着!这些 code 应该记着。将来做 leader 的时候,coding 要用。”我暗想我和 leader 的等级还很远呢,而且我们 leader 也从不 coding;又好笑,又不耐烦,懒懒的答他道,“谁要你教,不是&后面坠一串 nbsp;么?”孔乙己显出极高兴的样子,将两个指头的长指甲敲着柜台,点头说,“对呀对呀!……空格有四样写法,你知道么?”
天下何人不孔乙己!(^▽^) 不开玩笑啦!接下来来细究一下这个空格的的四种写法,实际上是六种编码方式,后面会用代码来验证。
问题来源
在编写关于 Cesium 的代码的时候,我想用 filter 过滤使用提供的默认选择地图,然后使用名字来作为条件,然后就有了如下图所示的问题,主要还是太相信自己的眼睛了,这个问题和写什么代码没有太大关系,主要是对于 utf8 字符集编码中空格区别的认识。
上图中把控制台输出的两个字符串复制,在 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-test</title>
<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
的问题了,这段字符串中前面是用了alt+1060
,而后面是键入空格,所以只要保持两边空格字符编码一致就可以了。请不要直接复制这串等式到控制台验证,下面有解释原因。
解决这个问题后,就赶紧修复了代码问题,但是回头仔细想想,Cesium 开发人员应该不能用alt+1060
这种方式输入空格吧,这不合理,然后打开调试窗口查看了一下该出字符的原文(如下图所示),在 Cesium 源代码里面也是
,这不就是刚开始学前端的时候 html 对特殊字符的处理吗,就是把关键的字符都做了转义,除了空格,还有许多特殊字符,比如左右尖括号,这里就不过多赘述了,这是前端开发者的基本知识。
往后面再延伸一步,为啥
和我直接敲的空格不一样?我又编写 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 编码):
有什么实际意义?
如果非要说有什么意义的话,那就是没有意义,对于写代码来说其实很少会遇到这种问题;唯一的作用就是遇到像我这样的问题至少能知道为啥,如果不搞清楚就很难知道问题的根本原因,所以多少还是可以了解一下;当然在实际的应用中,对于一些排版文字,对这些编码是有明确要求的,空格输入的这几种方式参考了这篇文章——空格的 6 种 Html 书写形式。
如果本篇文章对您有帮助欢迎点赞、收藏、转发,非常感谢您的支持(~ ̄ ▽  ̄)~
转载自:https://juejin.cn/post/7223276236171903033