回顾前端基本知识二

91 阅读15分钟

StringToNumber

Number 是比 parseInt 和 parseFloat 更好的选择 或者 +

JavaScript 对象的特征

对象具有唯一标识性:即使完全相同的两个对象,也并非同一个对象。(各种语言的对象唯一标识性都是用内存地址来体现的, 对象具有唯一标识的内存地址,所以具有唯一的标识。) 对象有状态:对象具有状态,同一对象可能处于不同状态之下。 对象具有行为:即对象的状态,可能因为它的行为产生变迁。

    var o2 = { a: 1 };
    console.log(o1 == o2); // false

先来说第一类属性,数据属性。它比较接近于其它语言的属性概念。数据属性具有四个特征。 value:就是属性的值。 writable:决定属性能否被赋值。 enumerable:决定 for in 能否枚举该属性。 configurable:决定该属性能否被删除或者改变特征值。

第二类属性是访问器(getter/setter)属性,它也有四个特征。 getter:函数或 undefined,在取属性值时被调用。 setter:函数或 undefined,在设置属性值时被调用。 enumerable:决定 for in 能否枚举该属性。 configurable:决定该属性能否被删除或者改变特征值。

闭包:

闭包其实只是一个绑定了执行环境的函数,这个函数并不是印在书本里的一条简单的表达式,闭包与普通函数的区别是,它携带了执行的环境

编译

按照编译原理相关的知识,我们来设计一下工作,这里我们分成几个步骤。定义四则运算:产出四则运算的词法定义和语法定义。词法分析:把输入的字符串流变成 token。语法分析:把 token 变成抽象语法树 AST。解释执行:后序遍历 AST,执行得出结果。定义四则运算

脚本是可以由浏览器或者 node 环境引入执行的,而模块只能由 JavaScript 代码用 import 引入执行。从概念上,我们可以认为脚本具有主动性的 JavaScript 代码段,是控制宿主完成一定任务的代码;而模块是被动性的 JavaScript 代码段,是等待被调用的库。

现代浏览器可以支持用 script 标签引入模块或者脚本,如果要引入模块,必须给 script 标签添加 type=“module”。如果引入脚本,则不需要 type。

这样,就回答了我们标题中的问题,script 标签如果不加type=“module”,默认认为我们加载的文件是脚本而非模块,如果我们在脚本中写了 export,当然会抛错

import 声明我们首先来介绍一下 import 声明,import 声明有两种用法,一个是直接 import 一个模块,另一个是带 from 的 import,它能引入模块里的一些信息。

import "mod"; //引入一个模块import v from "mod"; //把模块默认的导出值放入变量v

直接 import 一个模块,只是保证了这个模块代码被执行,引用它的模块是无法获得它的任何信息的。带 from 的 import 意思是引入模块中的一部分信息,可以把它们变成本地的变量。

带 from 的 import 细分又有三种用法,我们可以分别看下例子:

import x from "./a.js" 引入模块中导出的默认值。
import {a as x, modify} from "./a.js"; 引入模块中的变量。
import * as x from "./a.js" 把模块中所有的变量以类似对象属性的方式引入。

语法要求不带 as 的默认值永远在最前。注意,这里的变量实际上仍然可以受到原来模块的控制。

我们看一个例子,假设有两个模块 a 和 b。我们在模块 a 中声明了变量和一个修改变量的函数,并且把它们导出。我们用 b 模块导入了变量和修改变量的函数。

模块 a:
export var a = 1;
export function modify(){ a = 2;}
模块 b:
import {a, modify} from "./a.js";
console.log(a); //1
modify();
console.log(a);//2

当我们调用修改变量的函数后,b 模块变量也跟着发生了改变。这说明导入与一般的赋值不同,导入后的变量只是改变了名字,它仍然与原来的变量是同一个。

export 声明我们再来说说 export 声明。

与 import 相对,export 声明承担的是导出的任务。

模块中导出变量的方式有两种,一种是独立使用 export 声明,另一种是直接在声明型语句前添加 export 关键字。独立使用 export 声明就是一个 export 关键字加上变量名列表,例如:export {a, b, c};

我们也可以直接在声明型语句前添加 export 关键字,这里的 export 可以加在任何声明性质的语句之前,整理如下:

var function (async 和 generator) class let const export

还有一种特殊的用法,就是跟 default 联合使用。

export default 表示导出一个默认变量值,它可以用于 function 和 class。这里导出的变量是没有名称的,可以使用import x from "./a.js"这样的语法,在模块中引入。export default 还支持一种语法,后面跟一个表达式,例如:var a = {};export default a;但是,这里的行为跟导出变量是不一致的,这里导出的是值,导出的就是普通变量 a 的值,以后 a 的变化与导出的值就无关了,修改变量 a,不会使得其他模块中引入的 default 值发生改变。在 import 语句前无法加入 export,但是我们可以直接使用 export from 语法。export a from "a.js"JavaScript 引擎除了执行脚本和模块之外,还可以执行函数。而函数体跟脚本和模块有一定的相似之处,所以接下来,给你讲讲函数体的相关知识。

表达式

PrimaryExpression 主要表达式

MemberExpression 成员表达式

NewExpression NEW 表达式

CallExpression 函数调用表达式

LeftHandSideExpression 左值表达式 a() = b;

AssignmentExpression 赋值表达式

更新表达式 UpdateExpression

-- a; ++ a; a -- a ++

一元运算表达式 UnaryExpression

delete a.b; void a; typeof a;

a; ~ a; ! a; await a;

乘方表达式 ExponentiationExpression

乘法表达式 MultiplicativeExpression

加法表达式 AdditiveExpression

移位表达式 ShiftExpression

关系表达式 RelationalExpression

相等表达式 EqualityExpression

位运算表达式位运算表达式含有三种:

按位与表达式 BitwiseANDExpression

按位异或表达式 BitwiseANDExpression

按位或表达式 BitwiseORExpression。位运算表达式关系比较紧密,我们这里放到一起来讲。

按位与表达式由按位与运算符(&)连接按位异或表达式构成,按位与表达式把操作数视为二进制整数,然后把两个操作数按位做与运算。(两个都是1就是1,其他都是0)

按位异或表达式由按位异或运算符(^)连接按位与表达式构成,按位异或表达式把操作数视为二进制整数,然后把两个操作数按位做异或运算。异或两位相同时得 0,两位不同时得 1。

异或运算有个特征,那就是两次异或运算相当于取消。所以有一个异或运算的小技巧,就是用异或运算来交换两个整数的值。(两个都是0的时候才是0)

参考: www.runoob.com/w3cnote/bit…

逻辑与表达式和逻辑或表达式

条件表达式 ConditionalExpression

css

@charset

@charset 用于提示 CSS 文件使用的字符编码方式,它如果被使用,必须出现在最前面。这个规则只在给出语法解析阶段前使用,并不影响页面上的展示效果。@charset "utf-8";@import@import 用于引入一个 CSS 文件,除了 @charset 规则不会被引入,

@import 可以引入另一个文件的全部内容。@import "mystyle.css";@import url("mystyle.css");@import | ) ]? ? ;通过代码,我们可以看出,import 还支持 supports 和 media query 形式。

@media media 就是大名鼎鼎的 media query 使用的规则了,它能够对设备的类型进行一些判断。在 media 的区块内,是普通规则列表。@media print { body { font-size: 10pt }}

@page page 用于分页媒体访问网页时的表现设置,页面是一种特殊的盒模型结构,除了页面本身,还可以设置它周围的盒。@page { size: 8.5in 11in; margin: 10%; @top-left { content: "Hamlet"; } @top-right { content: "Page " counter(page); }}

@ counter-stylecounter-style 产生一种数据,用于定义列表项的表现。@counter-style triangle { system: cyclic; symbols: ‣; suffix: " ";}@ key-frameskeyframes 产生一种数据,用于定义动画关键帧。

@keyframes diagonal-slide { from { left: 0; top: 0; } to { left: 100px; top: 100px; }}

@ fontfacefontface 用于定义一种字体,icon font

选择器用法
id选择器#myid
类选择器.myclassname
标签选择器div,h1,p
相邻选择器h1+p
子选择器ul > li
后代选择器li a
通配符选择器*
属性选择器a[rel="external"]
伪类选择器a:hover, li:nth-child

通常我们用1表示标签名选择器的优先级,用10表示类选择器的优先级,用 100 标示 ID选择器的优先级。

” : 后继,表示选中所有符合条件的后继节点,后继节点即跟当前节点具有同一个父元素,并出现在它之后的节点,例如“ .a.b ”表示选中所有具有 class 为 a 的后继中,class 为 b 的节点。

“||”:列选择器,表示选中对应列中符合条件的单元格。

CSS 范围的关键字:initial,unset,inherit(参考: www.jianshu.com/p/cfac4f5e6…)

CSS 支持一批特定的计算型函数:calc() max() min() clamp() toggle() attr()

calc() 函数是基本的表达式计算,它支持加减乘除四则运算。在针对维度进行计算时,

calc() 函数允许不同单位混合运算,这非常的有用。

例如:section { float: left; margin: 1em; border: solid 1px; width: calc(100%/3 - 21em - 21px);}

max()、min() 和 clamp() 则是一些比较大小的函数,max() 表示取两数中较大的一个,min() 表示取两数之中较小的一个,clamp() 则是给一个值限定一个范围,超出范围外则使用范围的最大或者最小值。

toggle() 函数在规则选中多于一个元素时生效,它会在几个值之间来回切换,比如我们要让一个列表项的样式圆点和方点间隔出现,可以使用下面代码:

ul { list-style-type: toggle(circle, square); }

attr() 函数允许 CSS 接受属性值的控制。

属性选择器属性选择器根据 HTML 元素的属性来选中元素。

属性选择器有四种形态。

第一种,[att]直接在方括号中放入属性名,是检查元素是否具有这个属性,只要元素有这个属性,不论属性是什么值,都可以被选中。

第二种,[att=val]精确匹配,检查一个元素属性的值是否是 val。

第三种,[att~=val]多种匹配,检查一个元素的值是否是若干值之一,这里的 val 不是一个单一的值了,可以是用空格分隔的一个序列。

第四种,[att|=val]开头匹配,检查一个元素的值是否是以 val 开头,它跟精确匹配的区别是属性只要以 val 开头即可,后面内容不管。

\

树结构关系伪类选择器:

root 伪类表示树的根元素,在选择器是针对完整的 HTML 文档情况,我们一般用 HTML 标签即可选中根元素。但是随着 scoped css 和 shadow root 等场景出现,选择器可以针对某一子树来选择,这时候就很需要 root 伪类了。

:empty 伪类表示没有子节点的元素,这里有个例外就是子节点为空白文本节点的情况。

:nth-child 和 :nth-last-child 这是两个函数型的伪类,CSS 的 An+B 语法设计的是比较复杂的,我们这里仅仅介绍基本用法。

我们还是看几个例子::nth-last-child 的区别仅仅是从后往前数。:first-child :last-child 分别表示第一个和最后一个元素。:only-child 按字面意思理解即可,选中唯一一个子元素。of-type 系列,是一个变形的语法糖,S:nth-of-type(An+B) 是:nth-child(|An+B| of S) 的另一种写法。以此类推,还有 nth-last-of-type、first-of-type、last-of-type、only-of-type。

链接与行为伪类选择器链接与行为是第一批设计出来的伪类,也是最常用的一批。

:any-link 表示任意的链接,包括 a、area 和 link 标签都可能匹配到这个伪类。

:link 表示未访问过的链接,

:visited 表示已经访问过的链接。

:hover 表示鼠标悬停在上的元素。

:active 表示用户正在激活这个元素,如用户按下按钮,鼠标还未抬起时,这个按钮就处于激活状态。

:focus 表示焦点落在这个元素之上。

:target 用于选中浏览器 URL 的 hash 部分所指示的元素。在 Selector Level 4 草案中,还引入了 target-within、focus-within 等伪类,用于表示 target 或者 focus 的父容器。

目前兼容性达到可用的伪元素有以下几种。::first-line::first-letter::before::after下面我们就来分别讲讲它们。::first-line 和 ::first-letter 是比较类似的伪元素,其中一个表示元素的第一行,一个表示元素的第一个字母。

CSS 标准只要求 ::first-line 和 ::first-letter 实现有限的几个 CSS 属性,都是文本相关,这些属性是下面这些。

我们先来看下 animation 的示例,

通过示例来了解一下 animation 属性的基本用法:

@keyframes mykf
{ from {background: red;} 
 to {background: yellow;}
}
div{ animation:mykf 5s infinite;}

这里展示了 animation 的基本用法,实际上 animation 分成六个部分:

animation-name 动画的名称,这是一个 keyframes 类型的值(我们在第 9 讲“CSS 语法:除了属性和选择器,你还需要知道这些带 @的规则”讲到过,keyframes 产生一种数据,用于定义动画关键帧);

animation-duration 动画的时长;

animation-timing-function 动画的时间曲线;

animation-delay 动画开始前的延迟;

animation-iteration-count 动画的播放次数;

animation-direction 动画的方向。

接下来我们来介绍一下 transition。

transition 与 animation 相比来说,是简单得多的一个属性。

它有四个部分:

transition-property 要变换的属性;

transition-duration 变换的时长;

transition-timing-function 时间曲线;

transition-delay 延迟。

RGB 颜色

最常见的颜色表示法是 RGB 颜色,它符合光谱三原色理论:红、绿、蓝三种颜色的光可以构成所有的颜色

接下来我们讲一讲 RGBA,RGBA 是代表 Red(红色)、Green(绿色)、Blue(蓝色)和 Alpha 的色彩空间。RGBA 颜色被用来表示带透明度的颜色,实际上,Alpha 通道类似一种颜色值的保留字。在 CSS 中,Alpha 通道被用于透明度,所以我们的颜色表示被称作 RGBA,而不是 RGBO(Opacity)。

渐变在 CSS 中,background-image这样的属性,可以设为渐变。CSS 中支持两种渐变,一种是线性渐变,一种是放射性渐变,我们先了解一下它们的基本用法:线性渐变的写法是:linear-gradient(direction, color-stop1, color-stop2, ...);

实际上,对浏览器的实现者来说,他们做的事情,就是把一个 URL 变成一个屏幕上显示的网页。这个过程是这样的:(这个解释有点像服务端渲染)

  1. 浏览器首先使用 HTTP 协议或者 HTTPS 协议,向服务端请求页面;
  2. 把请求回来的 HTML 代码经过解析,构建成 DOM 树;
  3. 计算 DOM 树上的 CSS 属性;最后根据 CSS 属性对元素逐个进行渲染,得到内存中的位图;
  4. 一个可选的步骤是对位图进行合成,这会极大地增加后续绘制的速度;
  5. 合成之后,再绘制到界面上。

HTTP Method(方法)

我们首先来介绍一下 request line 里面的方法部分。这里的方法跟我们编程中的方法意义类似,表示我们此次 HTTP 请求希望执行的操作类型。方法有以下几种定义:GET POST HEAD PUT DELETE CONNECT OPTIONS TRACE

浏览器通过地址栏访问页面都是 GET 方法。表单提交产生 POST 方法。

HEAD 则是跟 GET 类似,只返回响应头,多数由 JavaScript 发起。

PUT 和 DELETE 分别表示添加资源和删除资源,但是实际上这只是语义上的一种约定,并没有强约束。

CONNECT 现在多用于 HTTPS 和 WebSocket。

OPTIONS 和 TRACE 一般用于调试,多数线上服务都不支持。

HTTP Status code(状态码)和 Status text(状态文本)接下来我们看看 response line 的状态码和状态文本。常见的状态码有以下几种。

1xx:临时回应,表示客户端请继续。

2xx:请求成功。200:请求成功。

3xx: 表示请求的目标有变化,希望客户端进一步处理。

301&302:永久性与临时性跳转。304:跟客户端缓存没有更新。

4xx:客户端请求错误。

403:无权限。404:表示请求的页面不存在。418:It’s a teapot. 这是一个彩蛋,来自 ietf 的一个愚人节玩笑。(超文本咖啡壶控制协议)

5xx:服务端请求错误。500:服务端错误。503:服务端暂时性错误,可以一会再试

3xx 系列比较复杂,301 和 302 两个状态表示当前资源已经被转移,只不过一个是永久性转移,一个是临时性转移。实际上 301 更接近于一种报错,提示客户端下次别来了。304 又是一个每个前端必知必会的状态,产生这个状态的前提是:客户端本地已经有缓存的版本,并且在 Request 中告诉了服务端,当服务端通过时间或者 tag,发现没有更新的时候,就会返回一个不含 body 的 304 状态。