前端一些比较基础的理论知识,值的你掌握。

前言:

        回首刚进入前端领域时,自己寸步难行,遇到过很多很多的问题有简单的:如何实现前端导出,前端实现pdf下载,动态表格,配置环境变量,手写webpack打包文件,接口联调不通等等,困难的:如何从零到一开发项目,浏览器的同源策略,如何优化前端的整体性能,https,宏任务与微任务的应用等等,工作了几年学习新知识发现学习有时候力不从心,发现是很多基础的知识又忘记了,所以我又拿出了这些基础知识重温!

 一、浏览器

1、同源策略

什么是同源策略:

        同源指的是:协议、端口号、域名必须一致!

限制三个方面:

1.当前域下js 脚本不能够访问其他域下的 cookie、localStorage 和 indexDB!

2.当前域下 js 脚本不能够操作访问操作其他域下的 DOM!

3当前域下 ajax 无法发送跨域请求!

同源策略的目的:

       为了保证用户的信息安全,对 js 脚本的一种限制,并不是对浏览器的限制,对于一般的 img、或者script 脚本请求都不会有跨域的限制,是因为这些操作都不会通过响应结果来进行可能出现安全问题的操作!

2、跨域,如何预防xss攻击 

跨域与同源策略的关系:

        跨域问题其实就是浏览器的同源策略造成的!

如何解决跨域问题:

        JSONP 利用<script>标签没有跨域限制,通过<script>标签src属性,发送带有callback参数的GET请求,服务端将接口返回数据拼凑到callback函数中,返回给浏览器,浏览器解析执行,前端拿到callback函数返回的数据!

JSONP 缺点:

        1.具有局限性, 仅支持get方法!

        2.不安全,可能会遭受XSS攻击!

如何预防XSS攻击:

        1.从浏览器的执行来进行预防,一种是使用纯前端的方式,不用服务器端拼接后返回;

        2.对需要插入到 HTML 中的代码做好转义 对于 DOM 型的攻击,主要是前端脚本的不可靠而造成的,对于数据获取渲染 和 字符串拼接的时候 应该对可能出现的恶意代码情况进行判断;

        3.用CSP建立一个白名单,告诉浏览器哪些外部资源可以加载和执行,从而防止恶意代码的注入攻击;

        4.CSP 指的是内容安全策略,它的本质是建立一个白名单,告诉浏览器哪些外部资源可以加载和执行。我们只需要配置规则,如何拦截由浏览器自己来实现。通常有两种方式来开启 CSP,一种是设置 HTTP 首部中的 Content-Security-Policy,一种是设置 meta 标签的方式 <meta http-equiv="Content-Security-Policy">;

二、http头部和http响应码

1、http请求头部和响应头部

常见的Request headers:

请求头 含义
Accept 浏览器可接收的数据格式
Accept-Encoding 浏览器可以接收的算法,如gzip
Accept-Language 浏览器可接收的语言,如zh-CN
Connection keep-alive 一次TCP连接重复使用
cookie 客户端接收到的Cookie信息
Host 指定原始的 URL 中的主机和端口
User-Agent(简称UA) 浏览器内核信息
Content-type 发送数据的格式,如application/json

常见的Response headers:

响应头 含义
Content-type 返回数据的格式,如application/json
Content-length 返回数据的大小,多少字节
Content-Encoding 返回数据的压缩算法,如gzip
Set-Cookie 服务端向客户端设置cookie

 2、http响应码

数字开头分别代表什么:

1xx:表示目前是协议的中间状态,还需要后续请求!

2xx:表示请求成功!

3xx:表示重定向状态,需要重新请求!

4xx:表示请求报文错误!

5xx:服务器端错误  !

常用状态码:

101 切换请求协议,从 HTTP 切换到 WebSocket!

200 请求成功,有响应体,服务器成功返回网页或者数据!

301 永久重定向:会缓存!

302 临时重定向:不会缓存!

304 协商缓存命中!

400 请求错误!

401 没有权限!

403 服务器禁止访问!

404 资源未找到,请求的网页不存在!

500 服务器端错误!

503 服务器繁忙!

三、js中ES5与ES6,宏微任务 

1、set 和 map 的区别:

①.这两种方法具有极快的查找速度 运行时间少大大提高了性能;

②.初始化需要的值不一样,Map需要的是一个二维数组,而Set 需要的是一维 Array 数组;

③.Map 和 Set 都不允许键重复;

④.Map的键是不能修改,但是键对应的值是可以修改的;

⑤.Set不能通过迭代器来改变Set的值,因为Set的值就是键;

⑥.Map 是键值对的存在,值也不作为健;

⑦.Set 没有 value 只有 key,value 就是 key;

2、ES5 和 ES6 区别:

ES5 继承方式:

        1.原型链继承 通过原型链将子类的原型指向父类的实列;

        缺点:虽然父类的实列成为了子类的原型对象,子类可以共用到父类的方法和实列。但每次实列话子类用的都是一个父类实列。改变原型对象会改变父类实列的数据,从而导致两边的原型对象的数据都改变;

        2.借助构造函数实现继承 在子类的构造函数的内部调用父类的构造函数,利用apply()和call()方法改变this的指向;

        缺点:父类原型链上的方法没有被子类继承,因为只是调用了父类的构造函数,将属性赋值给子类的实例;

        3.组合 将原型链继承和借用构造函数继承两种方法结合到一起。用构造函数继承父类的属性用原型链继承父类的方法;

        缺点:在实例化一个子类时 父类的构造函数执行了两次;

ES6的继承方式:

        ES6的继承主要是通过class这样一个方法实现的!

        1、class 可以理解为function,由于class本质还是一个function,因此它也有一个的prototype属性,当new一个class时,会把class的porototype属性赋值给这个新对象的 __proto属性。

        2、constructor 方法是默认添加的方法,在new一个对象时,自动调用该方法,constructor里面定义自己的属性。

        3、继承extends和super,class 子类名 extends 父类名实现继承,当然还得在constructor里面写上super(父类的参数),意思就是在子类中获得父类的this指针

ES5 ES6 具体区别:

        ES5的继承是通过prototype或构造函数机制来实现 ES5的继承实质上是先创建子类的实例对象,然后再将父类的方法添加到this上(Parent.apply(this));

        ES6的继承机制实质上是先创建父类的实例对象this(所以必须先调用父类的super()方法), 然后再用子类的构造函数修改this;

        ES6通过class关键字定义类,里面有构造方法,类之间通过extends关键字实现继承。子类必须在constructor方法中调用super方法,否则新建实例报错。因为子类没有自己的this对象,而是继承了父类的this对象,然后对其调用。如果不调用super方法,子类得不到this对象 注意:super关键字指代父类的实例,即父类的this对象。在子类构造函数中,调用super后,才可使用this关键字,否则报错;

        ES6语法中定义的class类,不是function函数,不会被JavaScript程序与解析。所以class不能提前调用;

        function可以提前调用,但是提前调用时,只有属性没有方法;

3、js同步与异步,宏任务与微任务

js中的同步和异步的区别和理解:

        同步:按照一定的顺序去执行,执行完一个才能执行下一个 ;

        异步:执行顺序是不确定的,由触发条件决定,什么时间执行也是不确定的,异步处理可以同时执行多个;

同步任务:

        只有前一个任务执行完成后,才可执行下一个任务,在主线程中;

异步任务:

        这个队列的所有任务都是不进入主线程执行,进入任务队列,被浏览提供的线程执行,当执行完毕后就会产生一个回调函数,并且通知主线程,在主线程执行完当前所执行的任务后,就会调取最早通知自己的回调函数,使其进入主线程中执行,比如ajax请求,再主线程中呈现的就是请求结果;

js的执行机制:

         1、先判断是js代码是同步的还是异步的,同步的就是同步任务,直接进入主线程处理,异步的就进入任务列表 ;

        2、当任务列表内的异步处理达到了触发条件时候(点击事件被点击时),就进入任务队列 ;

        3、当所有的主线程的任务执行完毕之后,才会将任务队列里面的任务(回调函数)添加到主线程;

        简言之:JS代码是从上到下一行一行执行的 如果某一行报错,则停止执行下面的代码 先执行同步代码,再执行异步代码;

事件循环的执行过程:

        同步代码:调用栈执行后直接出栈;

        异步代码:放到Web API中,等待合适的时机放入回调队列,等到栈空时事件循环(EventLoop)开始工作,进行轮询;

        微任务比宏任务执行时机要早 微任务在DOM渲染前触发,宏任务在DOM渲染后触发

console.log(1);

setTimeout(()=>{ console.log(2); },0);

Promise.resolve().then(()=>{ console.log(3); })

console.log(4); 执行结果://1,4,3,2 

JS是单线程的,浏览器在执行JS代码时先执行同步代码,再执行异步代码;

微任务和宏任务的根本区别:

        宏任务:由浏览器规定的 setTimeout setInterval Ajax DOM事件;

        微任务:由ES6语法规定的 Promise async await;

        总结:js的异步处理是和浏览器一起作用的,js是单线程的,但是浏览器是多线程的。浏览器可以同时处理多个异步任务。但是这些异步任务中的回调函数还是在js的主线程中一个一个执行的;

四、vue的for...in 和 for...of区别,路由模式

1、for...in 和 for...of有什么区别

for...in 遍历得到 key;

for...of 遍历得到 value;

二者适用于不同的数据类型:

遍历对象:for...in可以,for...of 不可以;

遍历Map Set: for..of 可以,for..in 不可以;

遍历 generator:for...of 可以,for...in 不可以;

for...in:

可以用在可枚举的数据 对象 数组 字符串;

for...of:

for...of用于可迭代的数据 数组 字符串 Map Set;

2、vue路由模式 

前端路由解决啥问题:

        解决单页面网站 通过切换浏览器地址url路径 匹配相对应的页面组件 在单页面应用中 大部分页面结构不变 只改变部分内容时使用当浏览器地址变化时,切换页面点击浏览器 后退、前进 按钮,网页内容跟随变化刷新浏览器,网页加载当前路由对应内容;

项目中如何选择路由:

        vue中路由模式分为哈希(hash)模式和历史记录(history)模式,如果在路由中没有指定路由模式则默认开启hash模式;

        history模式的时候路径会随着http请求发给服务器,项目打包部署时,如果后端没做配置,页面刷新,前端路径就会被当成资源去请求服务器,资源找不到就会报错404,而hash模式下,#后面的路径在网络请求时不会发送给服务器;

hash history 各有哪些优缺点:

hash模式

        优点:

        实现简单,兼容性好(兼容到ie8);

        绝大多数前端框架均提供了给予hash的路由实现;

        不需要服务器端进行任何设置和开发;

        除了资源加载和ajax请求以外,不会发起其他请求;

        缺点:

        对于部分需要重定向的操作,后端无法获取hash部分内容,导致后台无法取得url中的数据;

        服务器端无法准确跟踪前端路由信息;

        对于需要锚点功能的需求会与目前路由机制冲突;

history模式

        优点:

        对于重定向过程中不会丢失url中的参数。

        后端可以拿到这部分数据后端可以准确跟踪路由信息。

        可以使用history.state来获取当前url对应的状态信息。

        缺点:

        兼容性不如hash路由。

        需要后端支持。

        应用部署上线时需要后端人员支持,解决刷新页面服务器404的问题。

五、TS好处,泛型,声明类型

1、基础类型

基础类型: number string boolen array object

2、ts的好处有哪些

①.ts是js的加强版 ts给js添加了可选的静态类型 和 基于类的面向对象编程,它拓展了JavaScript的语法。所以ts的功能比js只多不少;

②.ts是面向对象的编程语言,包含类和接口的概念;

③.ts在开发时候可以给出编译错误 但是js的错误则是在运行的时候才会暴露出;

3、type 和 interface的不同

type是描述类型 interface是描述数据结构的

两者都可以描述一个对象 或者 函数

interface User { name: string age: number }

interface SetUser { (name: string, age: number): void; }

type User = { name: string age: number };

type SetUser = (name: string, age: number)=> void;

4、type可以声明基本类型别名,联合类型,元组等类型

// 基本类型别名

type Name = string

// 联合类型

interface Dog {
    wong();
}
interface Cat {
    miao();
}

type Pet = Dog | Cat

// 具体定义数组每个位置的类型

type PetList = [Dog, Pet]

// 当你想获取一个变量的类型时,使用 typeof

let div = document.createElement('div');
type B = typeof div

 5、什么是泛型 具体使用

泛型是指在定义函数、接口或类的时候,不会先指定具体的类型,使用时再去指定类型的一种特性。

可以理解为代表类型的参数:

interface Test<T = any> {
    userId: T;
}

type TestA = Test<string>;
type TestB = Test<number>;

const a: TestA = {
    userId: '111',
};

const b: TestB = {
    userId: 2222,
};

         好了以上就是前端的一些基础的知识,总结的并不全只是在开发中可能会遇到问题的相关基础知识,方便了解它的运行机制及其原理,希望大家都能够在这个不稳定的大环境里稳定下来,也祝愿没找到工作的程序猿们早日找到心仪的工作并稳定下来!

猜你喜欢

转载自blog.csdn.net/qq_66180056/article/details/131186600
今日推荐