anqier 2019-06-30
前端基本功-常见概念(一) 点这里
前端基本功-常见概念(二) 点这里
前端基本功-常见概念(三) 点这里
当一个引用类型继承另一个引用类型的属性和方法时候就会产生一个原型链。(js高级程序设计)
__proto__
属性的隐式原型prototype
属性的显式原型__proto__
(即它构造函数的prototype
)中查找原型链 是针对构造函数的,比如我先创建了一个函数,然后通过一个变量new了这个函数,那么这个被new出来的函数就会继承创建出来的那个函数的属性,然后如果我访问new出来的这个函数的某个属性,但是我并没有在这个new出来的函数中定义这个变量,那么它就会往上(向创建出它的函数中)查找,这个查找的过程就叫做原型链。
有权访问另一个函数作用域中的变量函数。(js高级程序设计)
当一个函数存在对非自身作用域的变量的引用 就产生一个闭包
有权访问另一个作用域的函数就是闭包
闭包三点作用: 创建私有变量;延长变量生命周期;防止全局变量污染
就是函数和变量的可访问范围。
作用域 是针对变量的,特点是:先在自己的变量范围中查找,如果找不到,就会沿着作用域往上找。
只有函数作用域和全局作用域(貌似还有个eval作用域),ES6中新增块级作用域那是后话
函数外声明的变量为全局作用域,函数内可以使用
函数内声明的变量为函数作用域,函数外不可以使用
作用域链:一个自由变量一直往上寻找(定义时的)父级作用域内的变量的过程。
自由变量:当前作用域没有定义的变量
作用域什么时候生成的?
页面加载-->创建window全局对象,并生成全局作用域-->然后生成执行上下文,预解析变量(变量提升),生成全局变量对象;$scope
补充:花括号内声明的变量为块级作用域,只能内部使用,减少全局污染
JavaScript是静态作用域,在对变量进行查询时,变量值由函数定义时的位置决定,和执行时的所处的作用域无关。
在 JavaScript 中,用 new
关键字来调用的函数,称为构造函数。
ECMAscript开发的两种模式:
1.面向过程: 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了
2.面向对象(OOP): 面向对象是以功能来划分问题,而不是步骤
面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性的方法的对象。
但是ECMAscript中没有类的概念!prototype是javascript实现与管理继承的一种机制,也是面向对象的设计思想,可以借助prototype属性,可以访问原型内部的属性和方法。
通常使用构造函数,当构造函数被实列化后,所有的实例对象都可以访问构造函数的原型(prototype)成员,如果在原型中声明一个成员,所有的实列方法都可以共享它
面向对象编程的基本思想是使用对象,类,继承,封装等基本概念来进行程序设计,达到数据结构化,简单抽象的目的(为什么面向对象)
优点
采用面向对象思想设计的结构,可读性高,由于继承的存在,即使改变需求,那么维护也只是在局部模块,所以维护起来是非常方便和较低成本的 - 易扩展 开发工作的重用性、继承性高,降低重复工作量。 缩短了开发周期
面向对象的三大特性:继承(子类继承父类,提高复用减少冗余),封装(数据的权限和保密),多态(同一接口的不同实现)
面向对象离不开 类 和 实例 两个概念
响应式网站设计(Responsive Web design)是一个网站能够兼容多个终端,而不是为每一个终端做一个特定的版本。
基本原理:是通过媒体查询检测不同的设备屏幕尺寸做处理。
页面头部必须有meta声明的viewport。
<meta name=’viewport’ content=”width=device-width, initial-scale=1. maximum-scale=1,user-scalable=no”>
是指通过复合纯函数来构建软件的过程,它避免了共享的状态、易变的数据、以及副作用。函数式编程是声明式而不是命令式,并且应用程序状态通过纯函数流转。
盒模型 : margin、padding、border、content
width = content
对应css属性 box-sizing:content-box
width = content + padding + border
对应css属性 box-sizing:border-box
关于跨域,有两个误区:
✔ 跨域只存在于浏览器端,不存在于安卓/ios/Node.js/python/ java等其它环境
✔ 跨域请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了之所以会跨域,是因为受到了同源策略的限制,同源策略要求源相同才能正常进行通信,即协议、域名、端口号都完全一致。
但是script标签能够加载非同源的资源,不受同源策略的影响。
如下图所示:
只要浏览器检测到响应头带上了CORS,并且允许的源包括了本网站,那么就不会拦截请求响应。
CORS把请求分为两种,一种是简单请求,另一种是需要触发预检请求,这两者是相对的,怎样才算“不简单”?只要属于下面的其中一种就不是简单请求:
(1)使用了除GET/POST/HEAD之外的请求方式,如PUT/DELETE
(2)使用了除Content-Type/Accept等几个常用的http头这个时候就认为需要先发个预检请求,预检请求使用OPTIONS方式去检查当前请求是否安全
代码里面只发了一个请求,但在控制台看到了两个请求,第一个是OPTIONS,服务端返回:
详见阮一峰的跨域资源共享CORS详解
JSONP是利用了script标签能够跨域,如下代码所示:
function updateList (data) { console.log(data); } $body.append(‘<script src=“http://otherdomain.com/request?callback=updateList"></script>');
代码先定义一个全局函数,然后把这个函数名通过callback参数添加到script标签的src,script的src就是需要跨域的请求,然后这个请求返回可执行的JS文本:// script响应返回的js内容为
updateList([{ name: 'hello' }]);
由于它是一个js,并且已经定义了upldateList函数,所以能正常执行,并且跨域的数据通过传参得到。这就是JSONP的原理。
跨域分为两种,一种是跨域请求,另一种访问跨域的页面,跨域请求可以通过CORS/JSONP等方法进行访问,跨域的页面主要通过postMesssage的方式。由于跨域请求不但能发出去还能带上cookie,所以要规避跨站请求伪造攻击的风险,特别是涉及到钱的那种请求。
本节参考文章:我知道的跨域与安全
超文本传输协议(HTTP)是用于传输诸如HTML的超媒体文档的应用层协议。它被设计用于Web浏览器和Web服务器之间的通信,但它也可以用于其他目的。 HTTP遵循经典的客户端-服务端模型,客户端打开一个连接以发出请求,然后等待它收到服务器端响应。 HTTP是无状态协议,意味着服务器不会在两个请求之间保留任何数据(状态)。
HTTP是明文传输的,也就意味着,介于发送端、接收端中间的任意节点都可以知道你们传输的内容是什么。这些节点可能是路由器、代理等。
举个最常见的例子,用户登陆。用户输入账号,密码,采用HTTP的话,只要在代理服务器上做点手脚就可以拿到你的密码了。
用户登陆 --> 代理服务器(做手脚)--> 实际授权服务器
在发送端对密码进行加密?没用的,虽然别人不知道你原始密码是多少,但能够拿到加密后的账号密码,照样能登陆。
HTTP是应用层协议,位于HTTP协议之下是传输协议TCP。TCP负责传输,HTTP则定义了数据如何进行包装。
HTTPS相对于HTTP有哪些不同呢?其实就是在HTTP跟TCP中间加多了一层加密层TLS/SSL。
通俗的讲,TLS、SSL其实是类似的东西,SSL是个加密套件,负责对HTTP的数据进行加密。TLS是SSL的升级版。现在提到HTTPS,加密套件基本指的是TLS。
传输加密的流程
原先是应用层将数据直接给到TCP进行传输,现在改成应用层将数据给到TLS/SSL,将数据加密后,再给到TCP进行传输。
对安全或密码学基础有了解的同学,应该知道常见的加密手段。一般来说,加密分为对称加密、非对称加密(也叫公开密钥加密)
谷歌推行一种协议(HTTP 之下SSL之上[TCP]),可以算是HTTP2的前身,SPDY可以说是综合了HTTPS和HTTP两者优点于一体的传输协议,比如
SPDY构成图:
SPDY位于HTTP之下,TCP和SSL之上,这样可以轻松兼容老版本的HTTP协议(将HTTP1.x的内容封装成一种新的frame格式),同时可以使用已有的SSL功能。
HTTP2.0可以说是SPDY的升级版(其实原本也是基于SPDY设计的),但是,HTTP2.0 跟 SPDY 仍有不同的地方,主要是以下两点
http2 新特性
chrome=>Network=>Name栏右键=>√Protocol
本节参考文章:简单比较 http https http2、HTTPS科普扫盲帖
1.请求参数:get参数附在URL后面?隔开,POST参数放在包体中
2.大小限制:GET限制为2048字符,post无限制
3.安全问题:GET参数暴露在URL中,不如POST安全
4.浏览器历史记录:GET可以记录,POST无记录
5.缓存:GET可被缓存,post无
6.书签:GET可被收藏为书签,post不可
7.数据类型:GET只能ASCII码,post无限制
MVC是一种设计模式,它将应用划分为3个部分:数据(模型)、展示层(视图)和用户交互层。结合一下下图,更能理解三者之间的关系。
换句话说,一个事件的发生是这样的过程
MVVM是Model-View-ViewModel的缩写。mvvm是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
为了减小工作量,节约时间,一个更适合前端开发的架构模式就显得非常重要,这时候MVVM模式在前端中的应用就应运而生。
mvc和mvvm其实区别并不大。都是一种设计思想。主要就是mvc中Controller演变成mvvm中的viewModel。mvvm主要解决了mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。和当 Model 频繁发生变化,开发者需要主动更新到View 。
defineProperty(VUE),脏检查(angular),原生js实现(发布订阅者模式)
数据劫持
结合 发布者-订阅者模式
的方式,通过Object.defineProperty()
来劫持各个属性的setter
,getter
,在数据变动时发布消息给订阅者,触发相应的监听回调。本节参考文章:MVC/MVVM
本节参考文章:axios优点
class Animal { constructor(){ this.type = 'animal' } says(say) { setTimeout(function () { console.log(this.type + 'says' + say) },1000) } } var animal = new Animal() animal.says('hi') // undefined says hi
我们再来看看=>的情况
class Animal() { constructor() { this.type = 'animal' } says(say) { setTimeout(() => { console.log(this.type + ' says ' + say) }, 1000) } } var animal = new Animal() animal.says('hi') // animal says hi
本节参考文章:前端面试之ES6篇