页面
大纲:
+++ html+css
+++ 服务器渲染和客户端渲染
+++ 单页应用和多页应用
+++ 媒体查询
html+css
- div标签中的内容只要不遇到空格会一直显示 不管盒子div的宽度
服务器渲染和客户端渲染
https://www.cnblogs.com/muzishijie/p/11198315.html
-
服务端渲染:在早期的时候,由于页面比较简单,前后端分离还没有做的比较完善,所以当时一般页面渲染还是在服务端完成html文件的拼装,然后浏览器接收到这个文件,就可以直接解析展示。-----服务器端完成拼接,浏览器端只需要渲染出来
-
客户端渲染:如今前端页面的复杂性提高,前端已经不再仅仅是普通的页面展示了,现在前端页面功能更加完善,也更加复杂。同时伴随着ajax的兴起,使得现在越来越崇尚前后端分离的开发方式。
**后端不再提供完整的html页面,而是提供一些API使得前端可以获取需要的json数据,然后前端拿到数据后在前端完成html页面的拼装,然后展示在浏览器上,这就是客户端渲染。 **
-
各自的优缺点:
-
服务器端渲染的优缺点:
前端耗时少,因为浏览器只需要直接渲染就好,利于SEO,传输过程是html页面
缺点:不利于前后端分离,----前端工作写一个静态html文件,后端修改为模板(要调整,双方都得调整)
-
客户端渲染的优缺点
前后端分离,前端专注与ui设计,后端专注于api开发,体验更好(可以做成spa应用)
缺点: 前端响应慢,因为前端需要进行拼接字段
不利于SEO(因为爬虫是抓取html页面的多),
-
单页应用和多页应用的理解:
多页应用: 每次页面跳转后,都会访问一个新的HTML页面。------这时候路由是由后端来写,就是以前node和php中都是这样操作的
- 多页应用的优点:首屏时间快,SEO效果好----首屏只需要请求一个页面,就经历一个http请求,另外搜索引擎能识别html的内容,根据内容进行排名。
- 多页应用的缺点: **页面切换慢 **,每一次切换页面都需要发起一个HTTP请求,假设网络较慢就会出现卡顿情况。
单页应用:用vue写的项目是单页应用,刷新页面会请求一个HTML文件,切换页面的时候,并不会发起新的请求一个HTML文件,只是页面内容发生了变化
vue.js原理:JS感知URL变化,当URL发生变化后,使用JS动态把当前的页面内容清除掉,再把下一个页面的内容挂载到页面上。此时的路由就不是后端来做了,而是前端来做,判断页面到底显示哪一个组件,再把以前的组件清除掉使用新的组件。就不会每一次跳转都请求HTML文件。
- 单页应用的优点:
- 单页应用的缺点:首屏时间慢,要在一个页面上为用户提供产品的所有功能,在这个页面加载的时候,首先要加载大量的静态资源,这个加载时间相对比较长;
媒体查询
ES6
**大纲: **
+++ 常用js操作
+++ this详解+ new介绍(实现new)+执行上下文介绍
+++ 箭头函数与普通函数
+++ promise和async/await
+++ 事件循环机制和同步异步理解
+++ 服务器渲染和客户端渲染()
常用js操作:
-
数组降维方法Array.prototype. flat(n) —传参可降至指定维度
-
数组变成字符串情形+ 对象变成字符串
[1,2,3,4]+"" =====> "1,2,3,4" ['1','2','3','4']+“” ===> "1,2,3,4"
对象变成字符串
let obj={a:"da","fa":1} obj+'' ===> "[object Object]" ====》 得不到预期的结果 ,还是得用JSON.stringfy()
-
数组去重
Array.from(new Set(arr))
-
数组reduce方法:(previous,currentValue,currrentIndex,arr)可以做什么。previous表示上一次回调函数的返回值-----这也就是说算累和累乘方便。
-
取对象中某个属性。
const { obj } = { "obj":1} console.log(obj) ----结果就是1
this详解和new介绍
-
this介绍
详解this:https://www.cnblogs.com/echolun/p/11962610.html
主要分四种情况: 默认绑定(this主要指向window),隐式绑定(指向调用的对象),显示绑定(apply和call这种,指向指定的对象),
new绑定-----(构造函数中的this,new会有操作,apply他到一个新构建的对象上)
箭头函数中的this----(是定义箭头函数时其父执行上下文中的this)
-----箭头函数的this指向取决于外层作用域中的this,外层作用域或函数的this指向谁,箭头函数中的this便指向谁----
-
new介绍与实现
new一个函数 的步骤;大致分为三步:-----也讲清楚了原型中的方法是怎么加进来的
1.以构造器的prototype属性为原型,创建新对象;
2.将this(可以理解为上句创建的新对象)和调用参数传给构造器,执行;
3.如果构造器没有手动返回对象,则返回第一步创建的对象
// 构造器函数 let Parent = function (name, age) { this.name = name; this.age = age; }; Parent.prototype.sayName = function () { console.log(this.name); }; //自己定义的new方法 let newMethod = function (Parent, ...rest) { // 1.以构造器的prototype属性为原型,创建新对象; let child = Object.create(Parent.prototype); // 2.将this和调用参数传给构造器执行 let result = Parent.apply(child, rest); // 3.如果构造器没有手动返回对象,则返回第一步的对象 return typeof result === 'object' ? result : child; }; //创建实例,将构造函数Parent与形参作为参数传入 const child = newMethod(Parent, 'echo', 26); child.sayName() //'echo';
-
执行上下文介绍:
https://www.cnblogs.com/echolun/p/11438363.html
每当一个函数被调用时都会创建一个函数上下文
执行上下文 的创建过程:绑定this,创建词法环境组件,和变量环境组件。
箭头函数和普通函数的区别
-
箭头函数是匿名函数,不能作为构造函数使用;
-
箭头函数没有agruments。
+++ 普通函数: function haha(a){console.log(arguments)} function haha1(...c){ console.log(c)} haha(1,2,3,4,5,6,6) ====> 参数可以超过定义的个数 haha1(1,2,3,'4',5,6) ===> 输出的是一个数组 [1,2,3,'4',5,6] +++ 箭头函数:----用不了arguments,只能用扩展运算符 let C = (...c) => {console.log(c);} C(3,82,32,11323);
-
箭头函数中的this
由于箭头函数不绑定this, 它会捕获其所在(即定义的位置)上下文的this值, 作为自己的this值
箭头函数的this指向取决于外层作用域中的this,外层作用域或函数的this指向谁,箭头函数中的this便指向谁
-
箭头函数没有原型
-
箭头函数不能当做Generator函数,不能使用yield关键字
promise和async/await
-
promise介绍
使用的时候,一般都是将promise对象返回(封装ajax的时候)
const promiseClick =()=>{ console.log('点击方法被调用') let p = new Promise(function(resolve, reject){ //做一些异步操作 setTimeout(function(){ console.log('执行完成Promise'); resolve('要返回的数据可以任何数据例如接口返回数据'); }, 2000); }); return p }
new Promise(func)这是一个实例化的过程, func是这个Promise构造函数的参数,用来实例化的,内部都有异步方法。
实例化的过程:首先promise的状态设置为pending, 接着就会执行func这个函数,实例化过程的时候,会传入两个匿名函数去调用这个func的。
这两个匿名函数执行到它们的时候,他会分别更改我们的promise的状态。保存调用参数到promise对象上
func(function(){ this.status="resloved" },function(){ this.status="rejected" })
func接到匿名函数做参数,当执行到内部的resolve(params)的时候,更改状态到resolve,和保存参数 params下来。(所以声明func的reslove(params)很重要,决定了 保存了 什么数据到promise对象上,到时候 后面then会调用的)
then的使用
then(function resolve(params){},)----也是封装的,会根据promise的状态,reslove就调用前面的函数,用之前保存的params 来调用。
-
async/await
https://segmentfault.com/a/1190000015488033
- async 是定义在一个函数前的关键字。
-
功能:定义的函数返回一个Promise对象(如果指定的返回值不是Promise对象,也返回一个Promise,只不过立即
resolve
,处理方式同then
方法),因此async
函数通过return
返回的值,会成为then
方法中回调函数的参数 -
await 是叫等待
-
注意事项:await 必须出现在 async 函数内部,不能单独使用
-
功能: 如果await的是 promise对象会造成异步函数
停止
执行并且等待
promise 的解决,后面的也不执行,如果等的是正常的表达式则立即执行。 -
await 的结果是什么
如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。
如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。
个人理解,得到就是resolve状态中存到promise对象中的参数--------验证后发现只取resolve(param1,param2) 第一个参数(这点不重要)
后续的代码 对这个返回值进行处理操作, 就相当于是then的操作。
function sleep(second) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(' enough sleep~'); }, second); }) } function normalFunc() { console.log('normalFunc'); } async function awaitDemo() { await normalFunc(); console.log('something, ~~'); let result = await sleep(2000); // --------------------> 取到resolve步骤存起来的参数 console.log(result);// 两秒之后会被打印出来 ---------------> 相当于then-----对数据进行操作 } awaitDemo();
-
理论上await后面可以接所有的js表达式。但是接promise对象,这种异步的才有意义。
-
事件循环机制和同步异步理解
-
js的语言特点是单线程,也就说同一时间只能做一件事情,单线程意味着,所有任务都需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。于是就有一个概念,任务队列。
但是,如果只是因为cpu忙不过来,也就算了,但有些时候,明明cpu是闲着的,因为IO设备(比如ajax操作从网络读取数据),不得不等结果出来,再继续往下执行,意识到这样不好,于是把任务分成了两种:一种是同步任务,一种是异步任务
-
同步任务和异步任务
- 同步任务(synchronous):同步任务值得是,在主线程上排队执行的任务,只有前一个任务执行完成,才会执行后一个任务
- 异步任务(asynchronous):异步任务值得是不进入主线程,而进入“任务队列”的任务
-
事件循环机制(event looper)
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。 (2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。 (3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些任务。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。 (4)主线程不断重复上面的第三步。(循环体现)
-
任务队列的划分----宏任务和微任务
在同步任务执行完了以后,先将微任务清空(都执行完)再执行宏任务
微任务包括:Promise、MutaionObserver、process.nextTick
宏任务包括: script标签,定时器,读写I/O
-
代理 proxy
Generator函数,不能使用yield关键字
用{} 来import:
import A from ‘./A.js’ ----只有在如下A.js 中有默认导出的 export default 语法时才会生效
export default 42
import {A} from './A' -----只有在模块A.js 中有如下命名导出为A的export name 的代码,也就是:
export const A=42