网星软件吧 关注:6贴子:149
  • 1回复贴,共1

Web前端体系

只看楼主收藏回复

eb前端技术由 html、css 和 javascript 三大部分构成,是一个庞大而复杂的技术体系,其复杂程度不低于任何一门后端语言。而我们在学习它的时候往往是先从某一个点切入,然后不断地接触和学习新的知识点,因此对于初学者很难理清楚整个体系的脉络结构。本文将对Web前端知识体系进行简单的梳理,对应的每个知识点点到为止,不作详细介绍。目的是帮助大家审查自己的知识结构是否完善,如有遗漏或不正确的地方,希望共勉。

一、JAVASCRIPT 篇0、基础语法
Javascript 基础语法包括:变量声明、数据类型、函数、控制语句、内置对象等。
在ES5 中,变量声明有两种方式,分别是 var 和 function ,var 用于声明普通的变量,接收任意类型,function用于声明函数。另外,ES6 新增了 let、const、import 和 class 等四个命令,分别用以声明 普通变量、静态变量、模块 和 类 。
JS数据类型共有六种,分别是 String、Number、Boolean、Null、Undefined 和 Object 等, 另外,ES6新增了 Symbol 类型。其中,Object 是引用类型,其他的都是原始类型(Primitive Type)。
原始类型也称为基本类型或简单类型,因为其占据空间固定,是简单的数据段,为了便于提升变量查询速度,将其存储在栈(stack)中(按值访问)。为了便于操作这类数据,ECMAScript 提供了 3 个基本包装类型:Boolean、Number 和 String 。基本包装类型是一种特殊的引用类型,每当读取一个基本类型值的时候,JS内部就会创建一个对应的包装对象,从而可以调用一些方法来操作这些数据。
引用类型由于其值的大小会改变,所以不能将其存放在栈中,否则会降低变量查询速度,因此其存储在堆(heap)中,存储在变量处的值是一个指针,指向存储对象的内存处(按址访问),对于引用类型的值,可以为其添加属性和方法,也可以改变和删除其属性和方法;但基本类型不可以添加属性和方法。
Javascript 可以通过 typeof 来判断原始数据类型,但不能判断引用类型,要知道引用类型的具体类型,需要通过 Object 原型上的 toString 方法来判断
JS中的函数存在着三种角色:普通函数、构造函数、对象方法。同一个函数,调用方式不同,函数的作用不一样,所扮演的角色也不一样。直接调用时就是普通函数,通过new创建对象时就是构造函数,通过对象调用时就是方法。


IP属地:四川1楼2018-01-24 15:11回复
    JS常用的内置对象有window、Date、Array、JSON、RegExp 等,window是浏览器在执行脚本时创建的一个全局对象,主要描述浏览器窗口相关的属性和状态,这个后面会讲到,Date 和 Array 使用场景最多,JSON主要用于对象的序列化和反序列化,还有一个作用就是实现对象的深拷贝。RegExp 即正则表达式,是处理字符串的利器。
    1、函数原型链
    JS是一种基于对象的语言,但在ES6 之前是不支持继承的,为了具备继承的能力,Javascript 在函数对象上建立了原型对象 prototype,并以函数对象为主线,从上至下,在JS内部构建了一条原型链。原型链把一个个独立的对象联系在一起,Object 则是所有对象的祖宗, 任何对象所建立的原型链最终都指向了Object,并以 Object 终结。
    简单来说,就是建立了变量查找机制,当访问一个对象的属性时,先查找对象本身是否存在,如果不存在就去该对象所在的原型连上去找,直到 Object 对象为止,如果都没有找到该属性才会返回 undefined。因此,我们可以通过原型链来实现继承机制。
    2、函数作用域
    函数作用域就是变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。通俗来讲就是,在一个函数里,有些变量可以访问,有些不可以访问。那些能访问的变量所形成的范围,就是这个函数的作用域。
    在 JavaScript 中,没有块级作用域,只有函数作用域,也就是说 if、while、for 语句不会形成独立的作用域。但有一个特殊情况,即 with 语句和 catch 语句会形成临时作用域,语句执行结束后,该作用域就会被释放。
    3、this 指针
    this 指针存在于函数中,用以标识函数运行时所处的上下文。函数的类型不同,this 指向规则也不一样:对于普通函数,this 始终指向全局对象window;对于构造函数,this则指向新创建的对象;对于方法,this指向调用该方法的对象。另外,Function对象也提供了call、apply 和 bind 等方法来改变函数的 this 指向,其中,call 和 apply 主动执行函数,bind一般在事件回调中使用,而 call 和 apply 的区别只是参数的传递方式不同。
    如果往深的去理解,无论什么函数,this 是否被改变, 本质上,this 均指向触发函数运行时的那个对象。而在函数运行时,this 的值是不能被改变的。
    4、new 操作符
    函数的创建有三种方式,即 显式声明、匿名定义 和 new Function() 。前面提到,JS 中的函数即可以是函数,也可以是方法,还可以是构造函数。
    当使用new来创建对象时,该函数就是构造函数,JS 将新对象的原型链指向了构造函数的原型对象,于是就在新对象和函数对象之间建立了一条原型链,通过新对象可以访问到函数对象原型 prototype 中的方法和属性。
    5、闭包
    闭包不是一个孤立的概念,需要从函数作用域的角度来理解。
    每个函数都有自己的作用域,如果在一个函数里定义了另一个函数,那么对应的就有两个作用域,这两个作用域就会形成一个链条,俗称作用域链。本质上讲,作用域链是一个自上而下的链表, 链表的最顶端是内部函数作用域,链表的最底端是全局作用域。内部函数有权访问整个作用域链上的变量。正常情况下,每当一个函数执行完毕,对应的作用域就会从该链表上移除,然后销毁。
    但如果函数 A 把函数 B 作为返回值返回时,情况又不一样。
    首先,函数 A 返回的是函数 B 的引用,也就是说,B 可能会在其他地方被调用。上面提到,函数 B 的定义是位于函数 A 内部,因此 A 和 B 会形成一条作用域链,函数 B 有可能会读取 A 中的变量 。为了保证函数 B 能够在其他地方正确执行,函数 B 所在的这条作用域链就不能被破坏。所以,即使函数 A 执行返回后,A 的作用域也不能释放,需要一直保存在内存中,以确保函数 B 能够正常读取里面的变量。函数 B 具有永久访问 A 作用域的特权,确切说,函数 B 就是闭包 。
    6、单线程与事件循环
    Javascript 是单线程语言。在浏览器中,当JS代码被加载时,浏览器会为其分配一个主线程来执行任务,主线程会在栈中创建一个全局执行环境 (全局作用域)。每当有一个函数进入执行流时,就会形成一个对应的执行环境(函数作用域),并将该执行环境压入栈中。每当一个函数执行完毕以后,对应的执行环境就会从栈中弹出,然后被销毁。这就是执行环境栈,执行环境栈的作用就是保证所有的函数能按照正确的顺序被执行。
    但在浏览器中,有一些任务是非常耗时的,比如 ajax请求、定时器、事件等。为了保证主线程任务不受影响,Javascript 内部维护了一个任务队列, 当这些耗时任务结束时(Ajax 请求返回、定时器超时、事件被触发),就将对应的回调函数插入队列中进行等待。这些任务的执行时机并不确定,只有当所有同步任务执行完毕后,执行环境栈被清空(栈底的全局执行环境会一直存在,直到进程退出)以后,然后再从任务队列中依次读取回调函数,并将其压入执行环境栈中。于是,主线程开始执行新的同步任务,执行完毕后再从栈中弹出,栈被清空。
    主线程从任务队列中读取任务是不断循环的,每当栈被清空后,主线程就会从任务队列中读取新的任务并执行,如果没有新的任务,就会一直等待,直到有新的任务。JavaScript 的这种执行机制就叫做任务循环。因为每个任务都由一个事件所触发,所以也叫事件循环。
    7、异步通信 Ajax技术
    Ajax是浏览器专门用来和服务器进行交互的异步通讯技术,其核心对象是 XMLHttpRequest,通过该对象可以创建一个 Ajax 请求。Ajax 请求是一个耗时的异步操作,当请求发出以后,Ajax 提供了两个状态位来描述请求在不同阶段的状态,这两个状态位分别是 readyState 和 status ,readyState 通过 5个状态码来描述一个请求的 5 个阶段:
    0 - 请求未发送,初始化阶段
    1 - 请求发送中,服务器还未收到请求
    2 - 请求发送成功,服务器已收到请求
    3 - 服务器处理完成,开始响应请求,传输数据
    4 - 客户端收到请求,并完成了数据下载,生成了响应对象
    status 用于描述服务端对请求处理的情况,200 表示正确响应了请求,404 表示服务器找不到资源,500 代表服务器内部异常等等。
    Ajax 对象还可以设置一个 timeout 值,代表超时时间。切记:timeout 只会影响 readyState,而不会影响 status,因为超时只会中断数据传输,但不会影响服务器的处理结果。 如果 timeout 设置的不合理,就会导致响应码 status 是 200,但 response里却没有数据,这种情况就是服务器正确响应了请求,但数据的下载被超时中断了。
    为了保证用户信息的安全,浏览器引入了同源策略,对脚本请求做了限制,不允许 Ajax 跨域请求服务器 ,只允许请求和当前地址同域的服务器资源。但不限制 HTML 标签发送跨域请求,比如 script、img、a 标签等,因此可以利用标签跨域能力来实现跨域请求,这就是 JSONP 能够跨域的原理。
    JSONP 虽然可以解决跨域问题,但只能发送 GET 请求,并且没有有效的错误捕获机制 。为了解决这个问题,W3C 在 XMLHttpRequest Level2 中提出了 CORS 规范,即 跨域资源共享。它不是一个新的 API,而是一个标准规范 。当浏览器发现该请求需要跨域时,就会自动在头信息中添加一个 Origin 字段,用以说明本次请求来自哪个源。服务器根据这个值,决定是否同意这次请求。
    随着移动端的快速发展,Web 技术的应用场景正在变得越来越复杂,关注点分离原则在系统设计层面就显得越来越重要,而 XMLHttpRequest 是 Ajax 最古老的一个接口,因而不太符合现代化的系统设计理念。因此,浏览器提供了一个新的 Ajax 接口,即 Fetch,Fetch 是基于 ES6 的 Promise 思想设计的,更符合关注点分离原则。
    8、模块化
    历史上,Javascript 规范一直没有模块(module)体系,即无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。在 ES6 之前,为了实现 JS 模块化编程,社区制定了一些模块加载方案,最主要有 CMD 和 AMD 两种,分别以 commonjs 和 requirejs 为代表。ES6 在语言标准的层面上,实现了模块化编程,其设计思想是,尽量静态化,使得编译时就能确定模块的依赖关系,即编译时加载,而 CMD 和 AMD 是在运行时确定依赖关系,即运行时加载。


    IP属地:四川2楼2018-01-24 15:12
    回复