自我梳理

387 阅读5分钟

知识架构

html的语义化

其实前端大多数情况下是可以靠div和span就能搭建一个基本的网站,但是语义化也有语义化的意义,

  1. 更适合机器阅读,如引擎搜索,又如盲人阅读器
  2. 使结构更明确,即使没有css的情况下,也可以清晰看出网页的结构

很多情况下,我们说话没有唯一的表达方式,语义话标签的使用也是这样,下面是几个使用场景。

  • 作为纯文本的补充,用于表达一定的结构或者消除歧义
    今天我吃了一个苹果 可以表述为
<em>今天</em>我吃了一个苹果
今天我吃了<em>一个</em>苹果
今天我吃了一个<em>苹果</em>

  • 作为标题摘要的语义类标签
<h1>HTML语义</h1>
<p>balah balah balah balah</p>
<h2>弱语义</h2>
<p>balah balah</p>
<h2>结构性元素</h2>
<p>balah balah</p>

当h元素放在section中时,h的层级会下降

<section>
    <h1>大标题</h1>
    <p>balbalba</p>
    <h2>小标题</h2>
    <p>balaala</p>
    <h2>小标题2</h2>
    <p>balabal</p>
</section>

一个典型的body

<body>
    <header>
        <nav>
            ……
        </nav>
    </header>
    <aside>
        <nav>
            ……
        </nav>
    </aside>
    <section>……</section>
    <section>……</section>
    <section>……</section>
    <footer>
        <address>……</address>
    </footer>
</body>

部分标签的意义

  • aside -- 导航性质的工具内容(侧边栏)
  • nav -- 导航(目录、导航栏、超链接)
  • article -- 文章
  • abbr -- 缩写
  • hr -- 效果为一条横线,意义为故事走向的转变或话题的转变
  • strong -- 强调 表现为加粗
  • time -- 时间
  • figure, figcaption -- 与主文章相关的图像、照片等流内容
  • dfn -- 被定义的元素
  • pre -- 预定义的内容,不需要浏览器进行排版
  • code -- 代码
  • small -- 补充评论
  • s -- 错误的内容,如打折前的价格,表现为中间的一条横线
  • i -- 表示读的时候变调
  • b -- 表示关键字
  • u -- 表示避免歧义的标注
  • data -- 和time类似,只是给机器读的内容
  • menu -- ul的变体,用于功能菜单时使用
  • main -- 整个页面只出现一个,表示页面的主要内容,可以理解为特殊的div

javascript类型

  • undefined -- 未定义
    一个变量 而不是关键字 我们可以使用 void 0 来获取undefined值,防止undefined被篡改
  • null -- 定义了 但是是空值
  • boolean
  • string -- 有长度限制的字符串
  • number
    注意 +0 和 -0相加时没有区别 但是除法时,1/0 = Infinity 1/-0 = -Infinity
    小数相加有精度问题 判断可以这么判断,javaScript提供的最小精度值:Number.EPSILON
console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON);
  • symbol -- 一切非字符串的对象key的集合,es6引入的新类型
var mySymbol = Symbol("my symbol");
  • object -- 属性的集合

属性分为数据属性和访问器属性,两者都是key-value结构,key可以是字符串或Symbol类型

Number/String/Boolean/Symbol都有自己的创建对象方法,如

new Number(2); --> 对象类型

对象的方法也可以在基本类型上使用 ,如

cosole.log("abc".charAt(0)); //a

当与new搭配时,他们产生对象,当直接调用时,他们表示强制类型转换

但symbol不同,直接new会报错

问题:为什么给对象添加的方法能用在基本类型上?

因为运算符提供了装箱操作,它会根据基础类型构建一个临时对象,使得我们能在基础类型上调用对应对象的方法.

类型转换

最好不要使用 == 比较, 而在显示地类型转换后使用 === 比较,因为试图实现跨类型的比较,它的规则复杂到没人能记住

=== 的比较规则

string to number

parseInt/parseFloat/Number

我们知道 0b --> 二进制 0o --> 八进制 0x -- >十进制,但是一些比较老的浏览器会识别错误,所以转化时应该传入parseInt的第二个参数,指定明确转化进制

装箱转换

每一种基本类型Number、String、Boolean、Symbol在对象中都有对应的类,所谓装箱转换,正是把基本类型转换为对应的对象,它是类型转换中一种相当重要的种类。

那么Symbol函数无法new出对应的对象,但我们仍可以利用函数的call方法来强迫产生装箱

 var symbolObject = (function(){ return this; }).call(Symbol("a"));

    console.log(typeof symbolObject); //object
    console.log(symbolObject instanceof Symbol); //true
    console.log(symbolObject.constructor == Symbol); //true

更好的方法是使用内置的Object函数

var symbolObject = Object((Symbol("a"));

    console.log(typeof symbolObject); //object
    console.log(symbolObject instanceof Symbol); //true
    console.log(symbolObject.constructor == Symbol); //true

每一类装箱对象皆有私有的 Class 属性,这些属性可以用 Object.prototype.toString 获取:

var symbolObject = Object((Symbol("a"));

console.log(Object.prototype.toString.call(symbolObject)); //[object Symbol]

在 JavaScript 中,没有任何方法可以更改私有的 Class 属性,因此Object.prototype.toString 是可以准确识别对象对应的基本类型的方法,它比 instanceof 更加准确。
call操作本身会产生装箱操作,需要配合typeod来区分基本类型和对象类型.

拆箱转换

先拆箱再转换,拆箱转换会尝试调用 valueOf 和 toString 来获得拆箱后的基本类型。如果 valueOf 和 toString 都不存在,或者没有返回基本类型,则会产生类型错误 TypeError。

number先执行valueOf再执行toString

 var o = {
        valueOf : () => {console.log("valueOf"); return {}},
        toString : () => {console.log("toString"); return {}}
    }

    o * 2
    // valueOf
    // toString
    // TypeError

string先执行toString再执行valueOf 新版google也是先valueOf再toString

 var o = {
        valueOf : () => {console.log("valueOf"); return {}},
        toString : () => {console.log("toString"); return {}}
    }

    o + ""
    // valueOf
    // toString
    // TypeError

在 ES6 之后,还允许对象通过显式指定 @@toPrimitive Symbol 来覆盖原有的行为。

var o = {
    valueOf : () => {console.log("valueOf"); return {}},
    toString : () => {console.log("toString"); return {}}
}

o[Symbol.toPrimitive] = () => {console.log("toPrimitive"); return "hello"}


console.log(o + "")
// toPrimitive
// hello

事实上,“类型”在 JavaScript 中是一个有争议的概念。一方面,标准中规定了运行时数据类型; 另一方面,JS语言中提供了 typeof 这样的运算,用来返回操作数的类型,但 typeof 的运算结果,与运行时类型的规定有很多不一致的地方。我们可以看下表来对照一下。