avatar

Catalog
Web的新发展

标准制定者

最开始,HTML标准是由W3C制定的,随着浏览器厂商和W3C矛盾的扩大,新的标准是是WHATWG制定的。浏览器厂商和W3C对于HTML的下一代标准厂商了矛盾,最终还是浏览器厂商胜利。因为他们才是最后实现标准,并掌握呈现给用户效果的人。

标准不单单是标准还牵涉到背后的利益,比如H5视频播放的格式,apple想要使用自己的私有格式作为标准,这造成了厂商之间的扯皮。在DVD时代,蓝光和HDDVD的格式之争使得流媒体超过了DVD,间接导致了行业的没落。从这来看历史还是不断重复自身。

以下是W3C和WHATWG达成的协议:

W3C 与 WHATWG 达成以下共识:
* W3C 与 WHATWG 在 WHATWG 的存储库中共同开发 HTML 和 DOM,以交付动态(现有和新增)标准和规范/审阅草案快照
* WHATWG 对 HTML 和 DOM 动态标准进行维护
* W3C 促进社区在 WHATWG 的存储库中直接参与相关工作(衔接社区、开发用例、提交问题、编写测试、协调解决方案)
* W3C 停止单独发布与 HTML 和 DOM 相关的特定规范列表,同时将 WHATWG 审阅草案纳入 W3C 标准流程

1200px-Valid_XHTML_1.0.svg.png

WHATWG中文名字网页超文本应用技术工作小组,是苹果、Mozilla、Opera、谷歌发起的组织,后来微软也加入了进来。相当于主流浏览器厂商的一个组织。它最开始成立就是因为不满W3C发展XHTML的策略(XHTML和XML一样要求严格闭合)。一方面是因为Web的历史包袱,网络中存在的大量不按规则的网页,另一方面HTML这么多年没有发展新技术,也造成了浏览器厂商的不满。于是自己成立了组织,发展HTML5。W3C失去了浏览器厂商的支持,所有制定的标准便得不到支持:)

什么是前端

前端(Front-End)也被认为用户端,一般是为网页编写CSS、JS和HTML代码。最开始制作的网页都是静态页面。如果在8~10年前可能只是个美工的工作。现在随着Web技术的发展可以说是所有需要页面展现的都是前端的范畴。

A history

从FrontPage说起

我接触网页的时代大概是在09年。那时候大家都喜欢考个级什么的。热度最高的是英语等级考试。我对英语没什么兴趣也不喜欢英语补习班,所以报了一个的计算机等级考试,初级。考试题目是有关office和网页制作的。(Ps:所以我很早接触了word当时还是Word2003最经典的版本)

当时已经有Dreamweaver,和Fireworks、Flash一起成为网页制作三剑客。但考试内容是Office中的一款软件:FrontPage。现在它已经小时在历史的长河中了,但是当时它的确很好用。它和Word PowerPoint界面很像,制作网页的时候只需要用鼠标拖拽图片和文本框,很方便,甚至我只是把Word经验套用进来。此时,我发现了一个新功能,超链接!一个新的想法产生了,能不能套用到其他软件。真的可以,PowerPoint就可以用这个功能。

后来Dw也用过,一开始最流行的是用表格来排版。当然也可以用拖的。我就喜欢这样。

frontpage

“动态页面”

老师说,我们做的页面都是静态的,到底什么是动态页面呢,我很好奇。我想:“动态页面就是那种会动的页面吧”。等我学到了Js,页面能动起来了,老师说这还不是动态页面。直到学了jsp我明白了,原来动态页面就是“动态渲染“的页面呢。此时的我还不知道有Ajax这个东西,更不知道SPA和前端渲染了。(后文会提到他们是什么)

做网页要从HTML学起,老师说,标签一定要注意闭合,因为不闭合浏览器也不会报错的。后来她讲了XML和XHTML。她说XHTML是下一代标准,因为XHTML是严格闭合的,所以XML也要严格闭合。此时,我学习的是还是用DW写网页,我不会想到,Dw其实已经过时,就在我学习HTML的同时H5已经在悄悄普及,XHTML失败,W3C交出了控制权。
xhtml.jpeg

网页的“灵魂”

异步非阻塞的JS

什么是异步非阻塞呢。举一个🌰。就像嗑瓜子,如果自己自己剥肯定太累。这时候就需要一个剥瓜子专人。此时有四种策略:
A:傻傻的等着看到瓜子剥好了就吃。(同步阻塞)
B:一边干别的事一边盯着瓜子好了就去吃。(同步非阻塞)
C:我太累了,瓜子剥好了叫我。(异步阻塞)
D:先干别的事,瓜子好了叫我。(异步非阻塞)

Js是单进程,因此异步非阻塞是最好的策略。这也间接产生一些奇怪的“现象”。
比如

javascript
1
2
3
4
5
for(var i=0;i<3;i++){

setTimeout(function(){console.info(i)},0)

}

这行代码执行后并不会打印0~2,而是会打印三个3。如下图
图片1.png

这是因为setTimeout是异步执行的,在for循环执行以后才会执行,此时i的值已经变成了3。

解决办法:

A: 闭包

javascript
1
2
3
4
5
6
7
8
9
10
for(i=0;i<3;i++){
(x=>{setTimeout(
function(){
console.info(x)

}

,0)})(i)

}

执行结果:
图片2.png

B:块级作用域

javascript
1
2
3
4
for(let i=0;i<3;i++){

setTimeout(function(){console.info(i)},0)
}

执行结果:
图片3.png

ES–另一个名字

JavaScript原名LiveScipt改成JS是为了蹭Java的热度。但是Javascript是Sun公司的商标。网景公司将JavaScript提交给欧洲计算机制造商协会进行标准化,Ecma组织将其改名为EcmaScript。

ES6中新增了let、const、箭头函数等。

在上面的例子中i是var命令声明的,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变,而循环内被赋给setTimeout的函数内部的console.log(i),里面的i指向的就是全局的i。也就是说,每次遍历中setTimeout里面的i,指向的都是同一个i,导致运行时输出的是最后一轮的i的值,也就是3。

如果使用let,声明的变量仅在块级作用域内有效,最后输出的是1、2、3。

NodeJs

简单的说NodeJs就是运行在服务器的Js。普通用户是使用浏览器运行Js而NodeJs靠的是V8引擎。

Vue

Vue特别好的一点在于其响应式,在数据更改了以后网页上的显示内容会自动重新渲染。而且组件化的写法,增强了代码的服用性。

响应式

响应式编程有点类似函数式编程的思想,以前我们写Js时需要自己获取Dom节点,自己赋值。在Vue中则只需要关心数据的变化即可。

以嗑瓜子为例,一般人嗑瓜子是有几个动作

  • 寻找瓜子
  • 剥瓜子壳
  • 吃瓜子

如果使用函数式编程,那么我们需要三个函数,一个用来寻找(瓜子)返回值是找到的(瓜子),一个用来剥(瓜子)壳返回无壳的(瓜子),另一个用来吃(瓜子)。每个函数的输入和输出都是确定的,比如剥壳的函数输出的结果一定是无壳的(瓜子)。

带来的好处是代码的简化,只需要描述“东西”之间的对应关系,即对映射的描述。体现在Web上外部就是对外部操作到 GUI 之间的映射的描述,对应Web上就是响应式编程的思想。

在指令式编程里面,计算是一种瞬间的操作。而响应式编程,计算是相互相应的,相互之间都存在关系,某些变化了,相互之间的关系会使相应的值随之变化。响应式编程有2个典型的例子:Excel,当单元格变化了,相互之间的单元格也会立即变化。Autolayout,当父View变化了,根据相互之间的关系Constraint,子View的frame也会随之变化。

对于刚才的例子,当“瓜子”变成了“栗子”剥出来的果实也会变,吃的口感也会变。

在面向对象语言中也是可以实现响应式编程的,具体做法应该是,把关系抽象出来,然后把变化抽象出来,用关系把变化事件传递下去

那么在指令式编程里边,刚才例子就是

  • $(‘#瓜子id’)
  • 获取“瓜子节点”遍历,如果子节点的名字==‘瓜子皮’则去掉
  • 拿起瓜子仁放进嘴里,动嘴。

可以看到在指令式编程则需要用算法来明确的指出每一步该怎么做。而且如果把瓜子变成了栗子,也不是那么好套用以前的代码。我们之前的用Jq操作dom就是非响应式的编程。

声明式编程(Declarative Programming)是一种编程范性,与命令式编程相对立。它描述目标的性质,让电脑明白目标,而非流程。

MVVM

在后端我们有MVC的结构。MVVM和MVC的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel

mvvm

模板语法

我写过一个简单的模板引擎,使用正则表达式替换对应字符串来实现。这样以来就省得在Ajax中字符串拼接了,利于修改和检查。

javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
	String.prototype.temp = function(obj) {

return this.replace(/\%\w+\.?\w+?\.?\w+?\%/gi,function(matchs) {


var returns = obj[matchs.replace(/\%/g, "")]
if (matchs.indexOf("\.")>0){
matchs=matchs.replace(/\%/g, "")
arr=matchs.split("\.")
if(arr.length>2)
{
returns=obj[arr[0]][arr[1]][arr[2]]
}else{
returns=obj[arr[0]][arr[1]]
}
}
return (returns + "") == "undefined"? "": returns
})
}
html
1
2
3
4
5
6
7
8
<textarea id="recex" style="display:none">
<div class="chat-widget-left">
%message%
</div>
<div class="chat-widget-name-left">
<h4>%sender.userName%</h4>
</div>
</textarea>

在vue中这个功能当然更复杂也更好用。比如:

文本:

数据绑定最常见的形式就是使用 “Mustache” 语法(双大括号)的文本插值

html
1
2
3
4
<div>{{message}}</div>
<div>{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}</div>

HTML的属性

mustache 语法不能作用在 HTML 特性上,遇到这种情况应该使用v-bind指令

html
1
<div v-bind:id="dynamicId"></div>

参考

前端开发的历史和趋势 by 阮一峰
https://github.com/ruanyf/jstraining/blob/master/docs/history.md

W3C 与 WHATWG 就共同开发 HTML 与 DOM 规范达成协议 https://www.chinaw3c.org/archives/2353/

setTimeout循环传参数几种方式 https://www.cnblogs.com/feng18/p/9485249.html

有哪些函数式编程在前端的实践经验? https://www.zhihu.com/question/33652103

什么是函数式编程思维?https://www.zhihu.com/question/28292740?sort=created

lambda函数式编程详解
https://www.jianshu.com/p/0346e18b981d

Java 8 Lambda 和函数式编程
https://www.jianshu.com/p/8ef209391445

Author: Winter X
Link: https://xdeam.github.io/2020/06/01/front-end/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.

Comment
1