江文艺

江文艺 查看完整档案

上海编辑长沙理工大学  |  软件工程 编辑上海善林金融服务有限公司  |  Web前端开发工程师 编辑 segmentfault.com/u/jiangwenyi/ 编辑
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 个人简介什么都没有

个人动态

江文艺 发布了文章 · 4月8日

前端那些事九(VUE)

https://appf96umjwe7950.pc.xiaoe-tech.com/detail/p_603eeeb8e4b087d11d4e47bc/6

  1. 谈谈你对MVVM的理解?

MVVM模式的作用:解决分层。

MVC:早期作用在后端,后端处理模板和数据再返回给浏览器,浏览器进行渲染。

model view controller

controller:处理业务逻辑(路由)

model:数据

view:渲染视图

MVP:

好处:隐藏controller,使用mvvm简化了数据到视图绑定的过程,可以自动监听变化

mvvm是模仿mvc模式在前端进行分层,手动获取数据操作视图,因为controller负载臃肿,更难维护,将数据自动映射到视图上,不需要经过controller处理。

解决了controller臃肿问题。

  1. 请说一下Vue2及Vue3响应式数据的理解

vue2使用Object.defineProperty把属性都劫持,重新定义,只能劫持已经存在的属性,

=> 数组:

对于多层对象, 需要递归并且重新定义,所以性能差,

vue2的问题 : 属性必须在对象里才能劫持

递归

vue3 不用重写get和set 在取值的时候判断是不是对象,是对象再代理

懒代理 默认不代理 只有取值的时候代理

vue3 data里是数据 希望哪些是响应式的 可以用对应api

响应式数据: 数据变了通知我。

双向数据绑定

  1. Vue中如何检测数组变化

更改数组本身

能改变数组,但是监控不到数组长度

函数劫持

  1. Vue中如何进行依赖收集?

  1. 如何理解Vue中模板编译原理

  1. Vue生命周期钩子是如何实现的

都是回调函数

把他放在一个数组里

合成整个数组 依次执行

  1. Vue的生命周期方法有哪些?一般在哪一步发送请求及原因

  2. Vue.mixin的使用场景和原理

vuex vue-router

  1. Vue组件data为什么必须是个函数?

唯一性 保证组件之间的数据不受影响

  1. nextTick在哪里使用?原理是?

保证在更新完毕后再获取内容,更新的策略是异步的

本身不代表异步,是异步的 但是是将内容维护到一个数组里,最终按照顺序执行,第一次会开启一个异步任务,后续更新是往数组里放,并不是又开启一个异步任务

为什么采用异步更新,希望都改完之后 执行

原理 promise => settimeout

  1. computed和watch区别

底层实现都靠watcher,功能项不一样

computed主要做缓存的,一个属性依赖的数据没有变,他就不会重新计算

watch是数据变了就执行回调

计算属性多了缓存,computed只有取值的时候才执行

initComputed,计算属性实际是个方法,核心object.defineProperty get函数 本身是属性,写成一个函数

计算属性watcher 加了懒加载属性lazy:true,默认第一次不执行

initWatch

vue里有三种watcher : 渲染watcher 计算属性watcher (lazy:true) 用户watcher

查看原文

赞 0 收藏 0 评论 0

江文艺 发布了文章 · 4月8日

前端那些事八(webpack)

参考视频 文章:

http://www.woc12138.com/article/45

https://segmentfault.com/a/1190000006178770

https://mp.weixin.qq.com/s?__...

https://www.jianshu.com/nb/45770544

  1. webpack

  2. 简介

webpack 是一种前端资源构建工具,一个静态模块打包器(module bundler)。

在webpack 看来, 前端的所有资源文件(js/json/css/img/less/...)都会作为模块处理。

它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)。

  1. 5个核心

  • Entry入口:指示 webpack 以哪个文件为入口起点开始打包,分析构建内部依赖图,trunk。

  • Output输出:指示 webpack 打包后的资源 bundles 输出到哪里去,以及如何命名。

  • 翻译:让 webpack 能够去处理那些非 JS 的文件,比如样式文件、图片文件(webpack 自身只理解JS)

  • Plugins插件:对象,

可以用于执行范围更广的任务。插件的范围包括从打包优化和压缩,一直到重新定义环境中的变量等,相当于钩子函数。

  • Mode模式:指示 webpack 使用相应模式的配置,development开发模式和production生产模式。

loader:函数,在构建过程中,文件转换器,文件转换的工作;a.less=>a.css

  1. webpack的安装

  2. webpack 打包原理

  3. 先递归识别依赖,构建依赖图谱

  4. 把代码转换成 AST 抽象语法树

  5. 在 AST 中去处理代码

  6. 将 AST 抽象语法树变成浏览器可以识别的代码并输出

https://github.com/bestCindy/mini-webpack/blob/main/README.md

  1. webpack打包过程

  2. 识别入口文件

  3. 通过逐层识别模块依赖。(Commonjs、amd或者es6的import,webpack都会对其进行分析。来获取代码的依赖)

  4. webpack做的就是分析代码。转换代码,编译代码,输出代码

  5. 最终形成打包后的代码

https://segmentfault.com/a/1190000020266246

(一)将代码转换成 AST 抽象语法树

利用 babel-parser 转换

代码在 convertToAST.js 文件中

(二)找到依赖关系

利用 traverse 遍历 AST 抽象语法树

找到文件的依赖关系

代码在 convertToDependency.js 里面

(三)将抽象语法树转换成浏览器可以运行的代码

代码在 convertToCode.js 里面

(四) 遍历 dependencies 找到所有的依赖获取依赖图谱

代码在 makeDependenciesGraph.js 里面

(五)生成代码

代码在 generateCode.js 里面

  1. webpack编译过程

https://www.jianshu.com/p/99ecc9209bfb

https://www.jianshu.com/p/01e9b0414553

  1. webpack生命周期

  1. 准备工作

  2. @babel/parser: 分析我们通过 fs.readFileSync 读取的文件内容,返回 AST (抽象语法树)

  3. @babel/traverse: 可以遍历 AST, 拿到必要的数据

  4. @babel/core: babel 核心模块,其有个transformFromAst方法,可以将 AST 转化为浏览器可以运行的代码

  5. @babel/preset-env: 将代码转化成 ES5 代码

ast抽象语法树:

https://juejin.cn/post/6844903727451602951

词法分析:将每项拆开。

语法分析:根据逻辑关系把token流合起来

Vue-loader 插件VueLoaderPlugin

vue2中的build 和config 文件夹用来配置webpack

loader plugin优化

是什么 有什么区别

手写loader

  1. babel

Babel 是什么:是一个 JavaScript 编译器

  • Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。

能做什么:

  • 语法转换

  • 通过 Polyfill 方式在目标环境中添加缺失的特性 (通过 @babel/polyfill 模块)

  • 源码转换 (codemods)

  1. babel-loader

babel-loader:加载babel的

babel-loader在执行的时候,可能会产生一些运行期间重复的公共文件,造成代码体积冗余,同时也会减慢编译效率。

https://huangxsu.com/2018/08/12/webpack-optimization/

限制范围:

  1. 限制 loader 只处理特定的目录, babel-loader,include

  2. noParse (该模块中不应该含有 import,require,define)

  3. 加快解析(resolve)速度,extensions不要加太多,常出现的放在前面

  1. babel-polyfill垫片

  1. tree shaking

作用: webpack2增加tree-shaking,tree shaking 摇晃 a module引入了Bmodule,将用不到的代码摇掉 不适用的代码 不打包进去

原理:消除无用的js代码,编译器可以判断某些代码不影响输出,是DCE的一种新的实现

在前端使用UglifyJS,核心是ES6 module嵌套引用关系

tree-shaking的消除原理利用ES6模块特性

ES6 modules去除掉多余代码

commonjs按需加载

webpack5

rollup babel+webpack打包

UglifyJS:代码压缩优化工具,是 tree shaking 删除代码的核心

Uglify没有完善的程序流分析

rollup有程序流分析

babel导致产生副作用代码

webpack:不支持导出ES模式

rollup:打包工具库 组件库 支持ES模块 问题:生态不行

manifestPlugin:判断文件入口

webpack的 plugin机制

拆包

不要改全局的东西

vue2 rollup

先打包后编译

  1. Dllplugin

  2. scope hoisting

实现原理: 分析出模块之间的依赖关系,尽可能的把打散的模块合并到一个函数中去,但前提是不能造成代码冗余。因此只有那些被引用了一次的模块才能被合并。

  1. code splitting拆分代码

code splitting作用: 拆分代码,优化相关配置

webpack优化,怎么做:

  1. Entry Points:多入口分开打包

  2. Prevent Duplication: 抽离第三方库vander,webpack去除重复引用是通过commonsChunkPlugin插件来实现

  3. 再抽离重复组件。

  4. Dynamic Imports:动态加载

commonsChunkPlugin在webpack4不使用了。

minchunks

自动化分离vender

code splitting 和 chunks

chunk:打包后的东西

拆分然后再重新放在一起

旧版的问题:没法区分父子级,找到对应关系

所以新的chunk图引入一个新对象 chunkGroups,一个chunkGroups包含多个chunk

新插件 SplitChunksPlugin

设置cacheDirectory为true

  1. HappyPack不更新了,thread-loader

HappyPack 可以让 Webpack 同一时间处理多个任务,发挥多核 CPU 的能力,将任务分解给多个子进程去并发的执行,子进程处理完后,再把结果发送给主进程。通过多进程模型,来加速代码构建。

  1. thread-loader

webpack4官方推荐

  1. webpack热更新

https://juejin.cn/post/6844904008432222215#heading-13

二、webpack的编译构建过程

  1. 实现原理

  2. webpack-dev-server启动本地服务
  3. 修改webpack.config.js的entry配置
  4. 监听webpack编译结束
  5. webpack监听文件变化
  6. 浏览器接收到热更新的通知
  7. HotModuleReplacementPlugin
  8. moudle.hot.check 开始热更新
  9. hotApply 热更新模块替换

①删除过期的模块,就是需要替换的模块

②将新的模块添加到 modules 中

③通过__webpack_require__执行相关模块的代码

  1. webpack性能优化的方式

  2. 缓存:

    
    1.  大部分babel-loader解决,在babel-loader中,可以通过设置 cacheDirectory 来开启缓存。
        
    2.  loader 不支持缓存,可以使用cache-loader
        
  3. 多核 / 多进程:

    
    1.  happypack 分解成多个子进程并发执行
        
    2.  一般都会提供 parallel 这样的配置项供你开启多核编译
        
  4. 抽离

    
    1.  一种是使用 webpack-dll-plugin 的方式,在首次构建时候就将这些静态依赖单独打包,后续只需要引用这个早就被打好的静态依赖包即可,有点类似“预编译”的概念;
        

问题:

  1. 另一种,也是业内常见的Externals的方式,我们将这些不需要打包的静态资源从构建逻辑中剔除出去,而使用 CDN 的方式,去引用它们。

  2. 拆分

    
    1.  docker,虚拟物理机
        
  3. 压缩代码

  1. 优化网站性能有哪些方法?

  2. 合并js,合并css,图片sprite,图片压缩

  3. 延迟加载内容:图片懒加载,数据懒加载

  4. 使用离线缓存,移动端可以把变动少的js,css存在本地

  5. css,js放置位置

  6. 减少http请求

  7. 骨架屏

首页加载性能优化,提升页面性能:

  • 减少包大小 :webpack打包优化,treeshaking uglify优化,按需加载。

  • 加快http请求速度:cdn :雪碧图, 大图, 第三方插件连接

  • 页面放置顺序:css,js

  • 减少页面重排重绘

  • 服务器端渲染,接口响应慢等问题

  • 延伸:骨架屏 预渲染  懒加载

打包优化:使用缓存,多线程打包,减少文件搜索范围,

  1. 从输入URL到页面呈现?

  2. DNS解析:

  3. TCP连接

  4. 发送HTTP请求

  5. 服务器响应:

  6. webpack优化: happypack,tree shaking

  7. 浏览器解析页面

  8. CDN

https://juejin.cn/post/6844903906296725518

内容分发网络,全国各地都有这个配置。类似菜鸟的仓配网络。

解决分布 带宽 分布的问题。预先做好分发

CDN : 缓存和回源

使用CDN镜像

多个服务器

使用CDN缓存,

CDN网络

修改DNS解析

全局负载均衡

DNS解析,得到

CDN关键技术:

  1. 缓存算法

  2. 分发能力

  3. 负载均衡(nginx),智能调用

  4. 基于DNS

  5. 支持协议,图片加速

访问量大的网络需要CDN,

缺点:

请求 CDN专用的DNS服务器

根据用户IP地址,

服务器节点:

边缘节点:

CND网络组成:中心节点、边缘节点

中心节点:总仓

边缘节点:异地分发节点,由负载均衡设备,

搭建CDN相关技术:

  1. 内容发布

  2. 内容存储

  3. 内容路由: 路由重定向,DNS机制

  4. 内容管理:

访问cdn和不通过cdn访问

cname过程

回源:

找自己的服务器

除了静态资源 api是否可以缓存

第三方库使用cdn加载

资源过期如何判断 cdn是如何更新数据的

主动push 被动pull

从服务器主动往cdn推送数据

webpack 变量提升 缓存 强缓存 协商缓存

预加载 预渲染

  1. DNS域名解析,DNS预解析

www.sunhao.win.根域

权威域.顶级域.根域

  1. 根域名 www.sunhao.win.根域 根域不显示

dns主要通过

udp

  1. 顶级域和顶级服务器

win所在的位置就是顶级域

  1. 国家顶级域名

  2. 通用顶级域名

  3. xx

  4. 权威DNS和权威域名服务器

  5. 运营商DNS服务器和本地DNS服务器

递归查询:主机向本机服务器查询

迭代查询:

cname别名指向: 解析域名到域名

解决请求严重延时的现象,使用dns预解析。

des-prefetch,多页面重复DNS预解析会速度

浏览器缓存

DNS Prefetching 技术

DNS域名解析过程:

  1. 查找浏览器缓存

  2. 查找系统缓存

  3. 查找路由器缓存

  4. 查找ISP DNS缓存

  5. 递归搜索

DNS安全问题

  1. DNS欺骗:更改IP地址

  2. 拒绝服务攻击

  3. 分布式拒绝服务攻击

  4. 缓冲区漏洞溢出攻击

DNS网络性能优化

  1. 减少DNS查找,避免重定向

  2. DNS预解析
查看原文

赞 0 收藏 0 评论 0

江文艺 发布了文章 · 4月8日

前端面试手写题目汇总

  1. 手写new

  2. 创建一个空对象

  3. 连prototype

  4. 改变this指向

  5. 返回 看他在不在Object上

  6. setTimeout实现setInterval

  7. 每秒执行settimeout

  8. sleep()

  9. add

  10. 用array.from(argument) 将类数组对象转为数组

  11. 用push将其他项加进去,return新数组

  12. 数组求和,使用数组隐式转换

  • valueOf:数组运算,返回最适合该对象类型的原始值

  • toString:字符串运算,将该对象的原始值以字符串形式返回

  1. 深拷贝 浅拷贝

浅拷贝:

深拷贝:

判断返回类型是数组还是对象,克隆对象

  1. 手写apply call bind

相同:

  • call 和 apply 都是为了解决改变 this 的指向。作用都是相同的,只是传参的方式不同。

  • 他们第一个参数都是this的指向

区别:

  • apply 传入的是数组,返回原函数

  • call 传入的是参数列表,一次性传入,返回原函数

  • bind 传入也是参数列表,可以多次传入,返回新函数,并且我们可以通过 bind 实现柯里化,返回函数的拷贝值,但是带有绑定的上下文,它不会立即执行

  1. call

  2. apply

  3. bind:

https://juejin.im/post/6844903682455109640#heading-3

https://www.jianshu.com/p/db49179caca1

https://zhuanlan.zhihu.com/p/150721732

  1. 手写防抖和节流

https://juejin.cn/post/6844903669389885453

https://zhuanlan.zhihu.com/p/72923073

防抖:多少秒后执行一次

设置定时器,清除再设置1秒执行。

<!-- 防抖: 设置定时器,在几秒后改变函数的arguments(类数组对象),在执行前需要先clear清除定时器 -->

闭包

时间戳 闭包

节流:在规定时间内持续触发只会执行一次

<!-- 节流:在规定时间内持续触发只会执行一次,在防抖的基础上增加一个开关,通过一个开关,与定时器setTimeout结合完成 -->

设置标记,

  1. 手写实现repeat/复制字符串

  2. 手写实现trim/ 去除前后空格

  3. 手写实现instanceof

  4. 冒泡排序

比较相邻的两个数 小的放在前面

https://www.cnblogs.com/onepixel/articles/7674659.html

  1. 选择排序

遍历数组 然后选择一个最小数值标识位 放在最前面 依次排序

比较最小索引

  1. 手写promise

缺点: 一旦执行 不能更改

.then的链式调用

初始值pending

成功的值

失败的原因

一个存放成功的数组

一个存放失败的数组

当state的状态改变,resolve调用将状态转为成功并储存成功的值

查看原文

赞 0 收藏 0 评论 0

江文艺 发布了文章 · 4月8日

前端那些事七(数组)

  1. 数组构造器

  2. 数组的方法:

不改变原数组:

  1. concat(): 拼接数组,合并数组

  2. slice():slice(开始位置索引,结束位置索引):向数组中提取指定元素,包含开始,不包含结束

  3. map():做计算

会改变原数组:

  1. pop(): 删除数组最后一个元素,返回删除的元素值

  2. push(): 向数组末尾添加多个元素,并返回一个值(数组新长度)

  3. shift():与pop相反,删除数组第一个元素,返回删除的元素值

  4. unshift():与push相反,向数组开头添加多个新元素,并返回一个值(数组新长度)

  5. splice():splice(开始位置索引,删除的数量,传递新元素) : 添加元素,删除指定元素

  6. reverse() :倒序数组,会影响原数组

  7. join():数组转为字符串,返回字符串

遍历方法:

  1. forEach():循环

  2. every(): 每个元素都满足测试函数 返回true

  3. some(): 数组中至少有一个满足测试函数,返回true

  4. indexOf():

  5. findIndex():找到第一个满足测试函数的元素,返回具体索引

  6. find():找到第一个满足测试函数的元素,返回值

  7. filter():在所有过滤函数中返回true的数组元素放进一个新数组,返回数组

  8. includes():包括,返回布尔值

  9. reduce():数组求和

  10. sort():重新排序,会影响原数组,按Unicode排序

  1. 进阶的方法:

  2. flat():多维数组转一维数组

  3. flatMap() :

  4. Array.from():将类数组转为数组,

  5. Array.of() /fill() :将一组值转为数组

  6. 数组实例的 copyWithin()

  7. 数组去重

https://juejin.im/post/6844903881500016647

ES6:

  1. new set数组去重:(array.from 或者 扩展运算符)

  2. Array.from(new Set(arr))

  3. [...new Set(arr)]

  4. map数组去重

  5. reduce去重

  6. filter + indexOf去重:filter(x,index,self)

ES5:

  1. 双重for循环+splice去重

  2. indexOf去重

  3. includes去重

  4. 数组排序

  5. Array.prototype.sort() 的排序稳定性

  6. reverse() 倒序,sort()升序

  7. 数组遍历:

  8. for循环:for、forEach 、for...in、for...of(ES6) 迭代器Iterator

  9. map、forEach、reduce求和、filter过滤、【every、some区别】

  10. ES6: entries(),keys() 和 values()

  11. 数组求和,求平均数

  1. for循环优化版,最优:

  2. reduce

  3. for...of循环

  4. 尾递归

  5. 数组求最大最小值,并集,交集,差集

  6. 数组乱序

  7. 多维数组转一维数组,手写实现flat

  8. arr.toString().split(',') :只适用于数组内全部是数字

  9. arr.join().split(',')

  10. 二维转一维: [].concat(...arr)

手写实现flat:

查看原文

赞 0 收藏 0 评论 0

江文艺 发布了文章 · 4月8日

ES6-11区别汇总

问题汇总:

  1. var、let、const区别(延伸:变量提升、函数提升)

  2. let、const是ES6新增的命令,用于声明变量;

  3. let、const只在块级作用域生效,var声明变量是全局的;

  4. var存在变量提升,let、const不存在变量提升;romis

  5. var可以重复声明,let、const在同一块作用域内不能重复声明;

  6. let、const的区别:const不能更改存放在栈区里的基本数据类型和引用数据类型的指针,声明后不能再更改。

  7. 存在暂时性死区

  8. for、forEach 、for...in、for...of 循环的区别

相同点:都可以遍历数组;

区别:

  1. for:缺点:不能直接遍历对象。

  2. forEach():缺点:不能直接遍历对象,循环不能跳出。

  3. for...in:优点:可以直接遍历对象,循环原型链的所有对象,缺点:消耗性能;保存的是键名,返回序列号 0 1 2 3

  4. for...of【最优】:可遍历array,object,string,map,set等,可以跳出循环;保存的是键值,返回 arr1 arr2 arr3

缺点:不适用于处理原有的原生对象。

解决for、forEach、for...of不能直接遍历对象的问题:将对象转为数组;

参考:https://www.cnblogs.com/goule/p/13630915.html

  1. ES5和ES6的区别:

ECMAScript 是 JS 的核心,ES6 相对于 ES5 在向下兼容的基础上提供大量新特性,如:

  • 块级作用域

  • 关键字 let, 常量 const、

  • 箭头函数

  • promise

  • this指向问题

  • 类Class

  • 对象字面量的属性赋值简写、

  • 字符串模板、

  • Iterators(迭代器)、

  • Modules、

  • Proxies、

  • Map+Set+WeakMap+WeakSet 四种集合类型、

ES6文档:https://es6.ruanyifeng.com/#docs/let

ES版本更新:https://www.jianshu.com/p/824f255c2dd8

  1. 数据类型检测

  • typeof:检测基本数据类型,返回结果是字符串 typeof string

    
    *   缺点:不能细分对象,不能区别数组和对象
        
    *   原理:所存的值在内存都是按二进制储存
        
  • instanceof:检测是否是某个类的实例 arr instanceof Array

  • constructor:检测构造函数 arr.constructor === Array

  • Object.prototype.toString.call:检测数据类型是数组,对象,函数

Object.prototype.toString.call(obj)

  • Array.isArray:检测数组Array.isArray(arr)

  1. 如何区分是数组还是对象

  2. Array.isArray():ES6语法

  3. constructor:

  4. Object.prototype.toString.call():

  5. Object.prototype的toString():

  6. 基于Object.prototype.isPrototypeOf()

  7. 基于getPrototypeOf()

https://www.cnblogs.com/woniubushinide/p/11231646.html

  1. axios ajax fetch区别

  • axios是一种对ajax的封装,fetch是一种浏览器原生实现的请求方式,跟ajax对等

  • ajax:是对原生XHR的封装,增添了对JSONP的支持

    
    *   var ajax = new xmlHttpRequest
        
    *   ajax.readystatus === 2
        
  • fetch:ES6版本的ajax,基于标准 Promise 实现,支持 async/await。

  • Axios:是基于原生XHR, Promise封装、用于浏览器和 node.js 的HTTP客户端;

Axios:支持 http拦截器

  1. 创建对象的方法

  2. 通过字面量创建

  3. 通过object方式创建

  4. 使用工厂模式创建对象

  5. 使用构造函数模式创建对象

  6. 使用原型模式创建对象

https://m.html.cn/qa/javascript/11183.html

  1. 变量提升的题

  • 变量提升:带var会提前声明

  • 函数提升:(旧版IE10及以下)带function会提前声明和定义

(新版)块级作用域会提前声明,不定义

  • 函数声明会优先被提升

https://blog.csdn.net/qq_35895679/article/details/105904369

  1. OOP面向对象编程

  • 解释:面向对象的编程方法OOP是九十年代才流行的一种软件编程方法。它强调对象的“抽象”、“封装”、“继承”、“多态”。我们讲程序设计是由“数据结构”+“算法”组成的。从宏观的角度讲,OOP下的对象是以编程为中心的,是面向程序的对象。

  • 三大特点:封装 继承 多态

    
    *   封装:指能够把一个实体的信息、功能、响应都装入一个单独的对象中的特性。
        
    *   继承:优点:继承的方法允许在不改动原程序的基础上对其进行扩充,这样使得原功能得以保存,而新功能也得以扩展。这有利于减少重复编码,提高软件的开发效率。
        
  • 对象的产生有两种基本方式:

    
    *   一种是以原型(prototype)对象为基础产生新的对象。
        
    *   一种是以类(class)为基础产生新对象。
        
  • 类(class):

    
    *   1) 私有成员(private):缺省情况下,一个类中的所有成员都是私有的。私有成员只能被类本身的成员函数访问。能够被继承但是被继承的私有成员不能够使用。
        
    *   2) 公有成员(public):公有成员可以被类成员函数和外部函数使用。
        
    *   3) 保护成员(protected):类的保护成员能被类及其派生类的成员函数和友元函数使用,具有继承性。
        
  • 类(Class)用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。

https://www.jianshu.com/p/b2dcf206cf87

  1. ES5如何继承

  2. 原型链继承

  3. 借用构造函数继承

  4. 组合式继承

  5. 原型式继承

  6. 寄生式继承

  7. 寄生组合式继承

https://www.jianshu.com/p/c6f36b3a5408

  1. ES6 class(类)

  • 通过class关键字,可以定义类。

  • ES6 的类,可以看作构造函数的另一种写法。类的数据类型就是函数,类本身就指向构造函数。

  • 类必须使用new调用,否则会报错。这是它跟普通构造函数的一个主要区别,后者不用new也可以执行。

  • 类的内部所有定义的方法,都是不可枚举的(non-enumerable)。

https://es6.ruanyifeng.com/#docs/class

  1. 作用域,闭包,原型链

  2. 说一下三者的概念

作用域:ES5全局作用域,函数作用域,ES6块级作用域

闭包:指的是能够访问另一个函数作用域的变量的函数。

原型链:构造函数,原型prototype,constructor组成

  1. 原型链有什么用处

  2. 怎么实现原型链继承

ES5: User.call(this, )改变this指向。

ES6: class extends

10.23-ES6~ES11

  1. 你项目中什么地方用到了闭包?为什么要用闭包?闭包的原理是什么?

  1. es6

  2. 项目中有用到哪些es6的特性

(他重点想让你说出箭头函数和promise,毫无疑问他还准备了this相关的问题)

  • 箭头函数,

  • promise

  • let,const,

  • class extends

  • 模块化

  1. 说下es5和es6箭头函数中this的指向

  • es5 this指向执行的上下文,apply、call、bind可以改变this指向。

  • es6箭头函数:this始终指向函数声明时所在作用域的this的值。

  1. 有哪些办法可以改变this

  • apply、call、bind可以改变this指向。

  • 使用 ES6 的箭头函数。

  1. promise怎么使用?它解决了什么问题?

  • Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。

  • promise.then

  • Promise.all

  1. 怎么中断promise?

(可以返回一个空的promise,既无resolve也没有reject)

  1. CommonJS 输出一组变量

  2. exports require

  3. [object Object]

  4. 调用Object.prototype的toString()方法,返回数据类型是Object;

  5. 关于this:

关于this: https://zhuanlan.zhihu.com/p/23804247

  1. this指向

  • 普通函数的this是调用的地方

  • 箭头函数的this是声明的地方

  1. call apply bind ,改变this指向

  • call、apply、bind这三个方法其实都是继承自Function.prototype中的,属于实例方法;

  • call、apply、bind的作用是改变函数运行时this的指向;

  • call()可以将实参在对象之后依次传递,apply()需要将实参封装到一个数组中统一传递

  • bind返回对应函数, 便于稍后调用; apply, call则是立即调用。

  • 在 ES6 的箭头函数下, call 和 apply 将失效

  1. this、super

  2. Object.setPrototypeOf

指定一个对象的原型:Object.setPrototypeOf(obj, prototype)

  1. this、global、globalThis

  • 在浏览器中,可以在程序的顶层使用this关键字来引用全局对象

  • 在Node.js中,可以使用global关键字访问全局对象

  • globalThis旨在通过定义一个标准的全局属性来整合日益分散的访问全局对象的方法
查看原文

赞 0 收藏 0 评论 0

江文艺 发布了文章 · 4月8日

前端那些事六(ES6-11)

ES6文档:https://es6.ruanyifeng.com/#docs/set-map

  1. ES6(2015年发布)

    ------------
    

版本变动最多,加入许多语法特性;

兼容性:label 可以把ES6编译成ES5。

ES6 声明变量的六种方法:

  • ES5 只有两种声明变量的方法:var命令和function命令。

  • ES6除了添加let和const命令,后面章节还会提到,

  • 另外两种声明变量的方法:import命令和class命令。所以,ES6 一共有6种声明变量的方法。

  1. let变量声明

  2. const声明常量,值不能修改

  3. 解构赋值:

解构赋值:ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值。

  1. 简化对象写法

  2. 箭头函数(=>)以及声明

箭头函数有几个使用注意点。

  1. 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

  2. 不可以当作构造函数,不具有prototype原型对象,不可以使用new命令,否则会抛出一个错误。

  3. 没有arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

  4. 不可以使用yield命令,因此箭头函数不能用作 Generator 函数

  5. 箭头函数都是匿名函数

  6. 箭头函数三种简化方式

  7. this的静态特性:

  8. 不能作为构造函数 实例化对象:

  9. 不能使用 arguments 变量:

  10. 简化实例:

  • 箭头函数适合与this无关的回调,比如:定时器 数组的方法回调

  • 箭头函数不适合与this有关的回调,比如:事件回调、对象的方法

  1. 允许给函数参数赋默认值

  2. rest参数

  3. 扩展运算符

  4. 扩展运算符

扩展运算符能将「数组」转换为逗号分隔的「参数序列」;

扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

  1. 扩展运算符的运用

  • 数组的合并:[...数组1, ...数组2]

  • 数组的克隆:[...数组]

  • 将伪数组转为真数组:

  1. 新数据类型Symbol

ES6引入一个新数据类型Symbol来标识独一无二的值,是一种类似于字符串的数据类型。

Symbol特点:

  1. Symbol的值是唯一的,用来解决命名冲突的问题

  2. Symbol值不能与其他数据进行运算

  3. Symbol定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名。

  4. 在for...in迭代中不可枚举,object.getOwnPropertyNames() 不会返回symbol对象的属性,可以通过object.getOwnPropertySymbols() 获取。

  5. Symbol创建

  6. 使用Symbol给对象添加属性或方法

  7. Symbol的内置属性

  8. 数组

  9. Map:映射 一对一

  10. reduce:汇总 一堆出来一个 算总数,平均数

  11. filter:过滤器

  12. forEach:循环遍历(迭代)

  13. 字符串

  14. 新方法 startsWith endsWith

  15. 字符串模板 ``(反引号)

  16. 面向对象

  17. class类

区别:

  1. 类不存在变量提升

  2. this 的指向

ES6的面向对象:

1、增加class关键字,构造器和类分开了

2、 class里面直接加方法

  1. class类的继承extends,super

super:超类 == 父类

  1. 面向对象 - 实例

模块化,组件化

JSX == babel ==browser.js

  1. JSON

  2. JSON对象

  • JSON.stringify():json转字符串

  • JSON.parse(): 字符串转json

  1. json的简写,方法简写

  • 名字和值(key和value)一样的时候,可以值保留一个。

  • 对象的简写

  1. promise

https://mp.weixin.qq.com/s?__...

特点:

  1. promise的状态一经改变就不能再更改,不允许返回。

  2. promise.all  全部成功才调用成功方法,有一个没成功就调用失败方法

  3. promise.race  竞赛,所有实例里第一个返回的状态,是成功就走成功

  4. promise.any 有一个成功就成功,全部失败才失败

  5. promise.allSettled  包装一组实例,记录所有状态返回。

  6. finally 所有状态都会走

  7. 实现retry https://blog.csdn.net/qq_40420294/article/details/101920789

  • 异步:操作之间没什么关系,可以同时进行多个操作 缺点 代码更复杂

  • 同步:操作直接是相关的 同时只能做一件事 代码更简单

  • ajax请求 异步

优点:

  • Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。

  • promise 消除异步操作 用同步一样的方式来书写异步

  • .then可以链式调用,解决回调地狱的问题,解决异步的问题,new了

缺点:

  • 不方便调用、一旦执行无法停止,状态改变后无法改变。

  • 不容易定位错误信息

  1. Promise.then()基本使用:

  2. Promise.all():解析多个请求

全部成功才调用成功方法,有一个没成功就调用失败方法

  1. Promise.race():解析多个请求

竞赛,所有实例里第一个返回的状态,是成功就走成功

  1. generator

  • generator是一个普通函数,两个特征:function和函数名之间有*,内部使用yield表达式。

  • generator函数和普通函数的区别:generator函数中途可以停止

  • yield:暂时放弃执行

  1. next()

  2. Proxy 拦截,代理器(vue3原理)

数组的key是他本身

重载(overload):用自己的定义覆盖了语言的原始定义

所要代理目标对象 , 配置对象

Proxy实例的方法:

  1. get():目标对象  拦截器  proxy本身

  2. set 目标对象 属性名 属性值 实例本身

  3. apply 目标对象 目标对象上下文  数组

  4. has 目标对象 属性名

  5. construst 拦截构造函数

  6. 迭代器(Iterator):自定义遍历数据

  7. 任何数据只要部署Iterator接口,就可以完成遍历操作,主要供for...of消费。

  8. Set

  9. WeakSet

WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。

  1. Map

ES6提供了Map数据结构,它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当做键。Map也实现了iterator接口,所以可以使用[扩展运算符]和[for ... of...]进行遍历。

Map的属性和方法:

  1. size 返回Map的元素个数

  2. set 增加一个新元素,返回当前Map

  3. get 返回键名对象的键值

  4. has 检测Map中是否包含某个元素,返回boolean值

  5. clear 清空集合,返回undefined

  6. ES7(2016年发布)

    ------------
    
    
  7. ES8(2017年发布)

    ------------
    
    
  8. async await

https://www.zhihu.com/question/39571954

  • 概念:async函数就是generator函数的语法糖。async函数,就是将generator函数的*换成async,将yield替换成await。

  • 异步编程的终极解决方案。

  • await后面的是同步任务,await下面的是微任务 ,.then是微任务

  • 函数执行时,一旦遇到await就会返回。等到触发的异步操作完成(并且调用栈清空),再接着执行函数体内后面的语句。

  • async/await是基于Promise实现的,async函数的返回值是promise对象

  • promise对象的结果由async函数执行的返回值决定。

优点:

  • async和await两种语法结合可以让异步代码像同步代码一样

  • 解决链式调用,不需要像Promise一样一直.then,不需要写匿名函数处理Promise的resolve值,也不需要定义多余的data变量,还避免了嵌套代码。

缺点:

  • 可能导致性能问题,因为await会阻塞代码

  1. async await和promis的区别:

相同点:都是优化异步编程体验的解决方案;

不同点:

  • promise是应用层的解决方案,它有一个规范,不同的语言也可以实现,它只能异步的处理错误,在js里本质是一个对象

  • async/await是语言层的解决方案,可以让用户像编写同步代码一样,通过try/catch可以同步地处理错误。

  • promise解决回调地狱的问题,async/await返回的是一个promise对象,解决promise里不停.then的问题

  1. ES9(2018年发布)

    ------------
    
  2. ES10(2019年发布)

    -------------
    
  3. ES11(2020年发布)

    -------------
查看原文

赞 0 收藏 0 评论 0

江文艺 发布了文章 · 4月2日

前端那些事五(JS2)

学习视频:https://www.bilibili.com/video/BV1YW411T7GX?p=16

参考文章:https://juejin.im/post/6844904160719011848#heading-39

  1. js基本简介

前期为了处理网页中前端验证,优化体验,将验证放在客户端。

  1. 组成部分:
  • 以JavaScript+JScript=>ECMAScript(ES核心)为标准文档,由浏览器厂商实现JS引擎
  • DOM 文本对象模型: 如何通过js操作网页
  • BOM浏览器对象模型:如何通过js操作浏览器
  1. JS特点:
  • 解释性语言,无需编译
  • 类似C和JAVA的语法结构
  • 动态语言
  • 基于原型的面向对象
  1. 字面量和变量

  • 字面量(常量):是不可改变的值
  • 变量:用于保存字面量,可以改变值。
  • 声明变量:使用var来声明一个变量,var a; 为变量赋值,b=123;
  • undefined:var a; 声明了一个变量,但是没有赋值。
  1. var let const的区别

  2. var:声明变量
  3. let:ES6新增的命令,也用于声明变量
  4. const:
  • 一旦声明必须赋值,不能使用null占位。
  • 声明后不能再修改
  • 如果声明的是复合类型数据,可以修改其属性

var(ES5)

let(ES6)

const(ES6)

变量提升

不存在变量提升

声明变量是全局的

仅在块级作用域内有效

可以重复声明

不能在同一块作用域内重复声明

let可以改属性

const不能改属性

参考: https://www.cnblogs.com/zhaoxiaoying/p/9031890.html

  1. 标识符

自主命名的都可以叫标识符(变量名,函数名,属性名)。

命名规则:

  • 可以含字母,数字,_,$
  • 不能以数字开头
  • 不能是ES的关键字,保留字
  • 驼峰命名

JS底层保存标识符时实际采用的Unicode(UTF-8)编码,所有的UTF-8都可以作为标识符。

  1. 数据类型(字面量的类型)

  1. String类型:字符串,对称引号引起来。

转义字符:常用" ' n

  1. Number类型:数值(Int整数和Float浮点数)
  • JS中可以表达的最大值用Number.MAX_VALUE,超过最大值Infinity(正无穷),最小值-Infinity(负无穷),typeof返回number,表示大于0的最小值用MIN_VALUE。
  • typeof类型检测:可以使用运算符typeof来检查一个变量的类型: typeof 变量
  • NaN:一个特殊数字,Not a number,typeof NaN 返回number
  • isNaN:判断b的值是否是NaN,所以可以用isNaN()函数来判断一个值是否是NaN

var b = NaN;

console.log(isNaN(b)); // 返回true

  • JS进行整数基本可以保证精确,计算浮点元素可能不精确,比如(0.1+0.2),计算钱的数字放在服务器计算。
  1. Boolean类型:布尔值(true/false),主要用来做逻辑判断。
  2. Null:空值,未开辟空间。
  • typeof null:返回object,机器码空指针,低三位000,也是js遗留的bug
  1. Undefined:开辟空间未赋值
  • typeof undefined:返回undefined
  1. Object:对象,引用数据类型,属于一种复合的数据类型,在对象中可以保存不同类型数据的属性。
  • 不足:基本数据类型都是单一的值,值之间没有关系。
  • 基本类型储存在栈中,对象储存在堆中,
  1. 强制类型转换

将一个数据类型强制转换成其他的数据类型

  1. 将其他类型转换成String类型
  • 方法一:调用被转换类型的toString()方法;
  • 该方法不会影响到原变量,它会将转换的结果返回。
  • 缺点:有局限性,null和undefined没有toString()方法。
  • 举例:var a = 123; //number a = a.toString(); //返回string类型“123”
  • 方法二:调用String()函数,并将被转换的函数作为参数传递给函数;
  • 与toString()方法的区别:String()函数会将null和undefined直接转换成字符串"null"和"undefined"
  • 举例:var b = 123; //number b = String(b); //返回string类型“123”
  • 方法三(隐式类型):任何字符的值和字符串做加法运算,都会先转为字符串,然后做拼串,所以可以给字符加上空字符串做拼串。
  • 举例:var c = 123; //number c = c + ""; //返回string类型“123”
  1. 将其他类型转换成Number类型
  • 方法一:调用Number()函数;
  • 缺点:有局限性,"123px"字符串无法转换。

  • 方法二:作用于字符串;
  • parseInt()函数和parseFloat()函数;
  • 举例:var b = "456px"; //string b = parseInt(b); //返回Number类型“456”
  • 如果对非String类型使用parseInt()函数,会将其先转为String后再操作。
  • 举例:var c = true //boolean

c = parseInt(c) =parseInt("true")=NaN; //返回Number类型NaN

  • 方法三(隐式类型):可以对一个其他数据类型使用 +,将其转换number,原理和Number()函数一样。
  • 举例:var a = "123"; //string a = +a; //返回number类型123

var b = true; //boolean b = +b; //返回number类型1

  1. 将其他类型转换成Boolean类型
  • 方法一:调用Boolean()函数;

除了undefined、null、false、''、0、NaN转换时false,其余都为true

  • 方法二(隐式类型):可以为任意类型进行两次非运算,即可转为布尔值。同Boolean函数()。
  • 举例:var a = "123"; //string a = !!a; //返回boolean类型true

对象类型转换: 默认调用{}的valueOf

  1. 运算符(也叫操作符)

可以对一个或多个值进行运算,并获取运算结果,都会返回结果,比如typeof就是运算符,可以来获得一个值的类型,它会将该值的数型以字符串的形式返回,number,。string,Boolean,undefined,object。

  1. 算数运算符

  • +:会拼串
    • :都会转成number
  • / :
  • %: 求模运算,取余数。

区别:任何值做- /运算时都会将值转换成number,可以利用这个特点做隐式的类型转换,-0 /1 1将其转换为number,原理和Number()函数一样,使用起来更简单。

  1. result = true + 1; // 返回2 ,对非number计算时,会将值先转为number再计算
  2. result = true + false;// 返回1
  3. result = 2 + NaN; // 返回NaN,任何数和NaN进行计算,都等于NaN
  4. result = "123"+"456" // 返回123456,两个字符串相加,会做拼串,长字符串可以采用这种方式做拼串。
  5. result = "123" + 2 // 返回1232,
  6. result = true + "123" // 返回true123,任何字符的值和字符串做运算,都会将其先转为字符串,再做拼串
  7. 一元运算符

  • :不会对数字产生影响
  • :负号对数字进行取反,对非number值会将其转为number再计算,

(隐式类型转换):可以对一个其他数据类型使用+,将其转换number,原理和Number()函数一样。

自增和自减:

  • 自增:在自身的基础上增加1,对于一个变量自增以后,原变量值会立即自增1,自增分为2种:后++(a++)和前++(++a),都会使原变量自增1。

区别:a++和++a的值不同,a++先赋值后运算,++a先运算后赋值。

旧值:a++等于原变量的值(自增前的值)

新值:++a的值等于新值(自增后的值)

  • 自减:自减分为2种:后--(a--)和前--(--a),都会使原变量自减1。
  1. 逻辑运算符

  • ! 非:取反
  1. 对布尔值进行取反;
  2. 对非布尔值取反,先转为布尔值再运算

var a = true; a = !a //返回false

var b = 10; b=!b //返回false

  1. (隐式类型转换):可以为任意类型进行两次非运算,即可转为布尔值。同Boolean函数()

var a = 10; a=!!a //返回true

  • && 与:两端都是true,则返回true,只要有一个false,则返回false。

js中的“与”属于短路的“与”,如果第一个值为false,则不会看第2个值。

result = false && true; // false

逻辑“与”和短路“与”

  • || 或:只要有一个true,则返回true。
  • && 和 || 非布尔值的情况

对于非布尔值进行与或运算时,则会将其转换为布尔值,然后再运算,并且返回原值。

var result = 1 && 2 //返回2 如果两个值都为true,返回后边的

如果两个值中有false,则返回靠前的false。

  1. 赋值运算符

  • = :可以将符号右侧的值赋值给符号左侧的值
  • +=: a+=5 等价 a = a+5
  • -=: a-=5 等价 a = a-5
  • =: a=5 等价 a = a*5
  • /=: a/=5 等价 a = a/5
  • %=: a%=5 等价 a = a%5
  1. 关系运算符

通过关系运算符可以比较两个值之间的大小关系,如果关系成立会返回true,如果关系不成立则返回false。

  • 大于号:判断符号左侧的值是否大于右侧的,如果关系成立返回true。
  • = 大于等于
  • < 小于
  • <= 小于等于
  • 非数值情况:对非数值进行比较时,会将其转换为数字再进行比较。
  • 任何值和NaN做任何比较都是false。

console.log(10 <= "hello"); //false

  • 如果符号两侧的值都是字符串时,不会将其转换为数字比较,而会比较字符串中字符的Unicode编码,比较字符编码时时一位一位进行比较,比较字符串的时候要进行转型,可以对英文进行排序。

console.log("11" < "5"); //true

console.log("a" < "b"); //true

  • 在字符串中使用转义字符输入Unicode编码: u四位编码 (这里编码十六进制)
  • 在网页中使用Unicode编码:编码;(这里编码是十进制)
  1. 相等运算符

使用相等运算符用来比较两个值是否相等,相等返回true。

  • == 相等:使用==比较两个值时,如果类型不同,则会自动进行类型转换,然后再进行比较,大部分时候转成number进行比较。

console.log(true == "1"); //true 转成number

  • undefined衍生自null,所以这两个值做相等判断时,会返回true。

console.log(undefined == null); //返回true

  • NaN不和任何值相等,包括他本身,所以用isNaN()

console.log(NaN == NaN); // 返回false

  • 判断b的值是否是NaN,所以可以用isNaN()函数来判断一个值是否是NaN

var b = NaN;

console.log(isNaN(b)); // 返回true

  • !=不相等:用来判断两个值是否不相等,不相等也会对变量进行类型转换。
  • ===全等:判断两个值是否全等,不会做类型转换。
  • !==不全等:用来判断两个值是否不全等,不会做自动类型转换。
  1. 条件运算符(三元运算符)

语法:条件表达式?语句1:语句2;

条件运算符在执行时,首先对条件表达式进行求值,

如果该值为true,则执行语句1,并返回执行结果

如果该值为false,则执行语句2,并返回执行结果

false?alert("语句1"):alert("语句2"): // 语句2

  1. ,运算符

, 运算符 :使用,可以分割多个语句,声明多个变量

var a = 1, b =2 , c= 3;

  1. 运算符的优先级

  • 运算符优先级表:(如果优先级相同,从左往右算。)

可以通过加()改变优先级。

  • 先乘除后加减
  • &&的优先级大于||

var result = 1 || 2 && 3 //返回

  • 如果||的优先级高,或者两个一样高,则应该返回3
  • 如果与的优先级高,则应该返回1
  1. 语句 代码块

语句是由上自下的顺序一条条执行,在js中可以使用{}来为语句进行分组。

同一个{}中的语句我们称为一组语句,要么都执行,要么都不执行。

一个{}中的语句我们也称为一个代码块,在代码块后面不用再编写;了。

js在的代码块只具有分组的作用,代码块的内容在外部都是完全可见的

  1. 流程控制语句:

通过流程控制语句可以控制执行流程,

语句的分类:

  1. 条件判断语句 (if语句)
  2. 条件分支语句 (switch语句)
  3. 循环语句
  4. 条件判断语句 if...else...

if语句:if语句在执行时,会先对条件表达式进行求值判断,如果表达式值为true,则执行if后的语句,if语句只能控制紧随其后的那个语句。

语法一:if语句

if(条件表达式) {

语句

}

语法二:if...else...语句

if(条件表达式) {

语句...

} else {

语句...

}

语法三: if...else if... else 语句

if(条件表达式) {

语句...

} else if(条件表达式){

语句...

} else if {

语句...

}

prompt()函数:可以弹出带文本框的提示框,用户输入的内容将会作为函数返回值返回,可以定义一个变量,返回值类型是string。

冒泡排序:

  1. 条件分支语句 switch...case...

switch语句:

执行流程:switch...case...语句在执行时会依次将case后的表达式的值和switch后的条件表达式的值进行全等比较,如果比较结果为true,则从当前case处进行执行代码,当前擦色后的代码都会执行,所以要加break,确保只执行当前case语句。

语法:

switch(条件表达式) {

case 表达式:

语句...

break;

default : // 同else

语句...

break;

}

  1. 循环语句 while/do...while.../if
  2. while循环:

执行流程:while语句在执行时,先对条件表达式进行求职判断,如果值为true,则执行循环体,值为true,则继续循环,以此类推,如果值为false,则终止循环。

语法: while(条件表达式) {

语句... //{}里的循环体

}

像这种条件表达式写死为true的循环叫死循环,除非浏览器关闭,死循环在开发中慎用,可以使用break来终止循环。

while(true) {

语句... //{}里的循环体

if(n == 10){

break; // 退出循环

}

}

创建一个循环需要三个步骤:

    1. 初始化一个变量 var i = 0;
    1. 在循环中设置一个条件表达式

while(i < 10){

alert(i);

//3. 定义一个更新表达式,每次更新初始化变量

i++;

}

  1. do... while... 循环

区别: do...while先执行后判断。while是先判断后执行。do...while可以保证循环体至少执行一次,while不能,日常中while用的更多。

语法: do {

语句... //{}里的循环体

} while (条件表达式)

  1. for 循环:

语法: for (①初始化表达式;②条件表达式;④更新表达式) {

③语句... //{}里的循环体

}

执行顺序:①②③④ ②③④ ②③④

  1. for、forEach 、for in、for of 循环的区别

相同点:都可以遍历数组;

区别:

  1. for:缺点:不能直接遍历对象。
  2. forEach():缺点:不能直接遍历对象,循环不能跳出。
  3. for...in:优点:可以直接遍历对象,缺点:消耗性能;保存的是键名,返回 0 1 2 3
  4. for...of【最优】:可遍历array,object,string,map,set等,可以跳出循环;保存的是键值,返回 arr1 arr2 arr3

缺点:不适用于处理原有的原生对象。

10.31-问题汇总

参考: https://blog.csdn.net/wjx666666/article/details/104940660

  1. break和continue

break:

  • break可以用来退出switch或循环语句,不能在if语句中使用break和continue
  • break默认只对离他最近的循环产生影响。
  • 可以为循环语句创建一个label,来标识当前的循环,break后加上label名称即可结束指定的循环,而不是默认的。

continue:

  • continue跳过当次循环,但是继续后面的循环。
  • continue默认只对离他最近的循环产生影响。

区别:

  • break终止整个循环(跳过整个循环);
  • continue用来跳过当次循环(只跳过一次);

优点:

优化性能,可以使用计时器console.time("test")和console.timeEnd("test");检测耗时。

质数练习题优化:

  1. 对象(引用数据类型)

基本数据类型的缺点:值和值之间没有任何联系。

对象:复合数据类型,在对象中可以保存多个不同数据类型的属性。(容器)

优点:关系明确,操作方便。

对象的分类:

  1. 内建对象

由ES标准中定义的对象,在任何的ES的实现中都可以使用

比如:Math String Number Boolean Function Object ...

  1. 宿主对象

由JS的运行环境提供的对象,目前主要指浏览器提供的对象。

比如:BOM DOM

比如:console.log(); document.write();

  1. 自定义对象

创建对象:使用new关键字调用的函数,是构造函数constructor,构造函数是专门用来创建对象的函数,赋值给obj。

使用typeof检查对象时返回object。

属性值:js对象的属性值,可以是任意的数据类型。

in运算符:通过该运算符可以检测一个对象中是否含有指定的属性。

语法:"属性名" in 对象

console.log("name" in obj) //返回true或false

  1. 基本数据类型和引用数据类型的区别:

  • js的变量都是保存在栈内存中的,基本类型的值直接在栈内存中存储,值与值之间是独立存在的,修改一个变量不会影响其他的变量
  • 对象储存在堆内存中,每创建一个新的对象,就会在堆内存中开辟一个新的空间,二变量保存的是对象的内存地址(对象的地址),如果两个变量保存的是同一个对象引用,当一个通过一个变量修改属性时,另一个也会受到影响。
  • 基本数据类型保存的是值,对象保存的是地址。
  • 当比较两个基本数据类型的值时,就是比较两个值。
  • 而比较两个引用类型时,它是比较两个对象的内存地址,就算两个对象是一模一样的,但是地址不同,他也会返回false。
  1. 对象字面量

  • 用构造函数创建一个对象:

var obj = new Object();

  • 用对象字面量来创建一个对象,本质相同。

var obj = {};

语法:{属性名:属性值,属性名:属性值...}

属性名的双引号可加可不加,如果使用一些特殊名称必须加引号。

属性名和属性值是一组组的名值对结构,名和值之间使用:连接,多个名值对之间用,隔开,如果一个属性之后没有其他属性,就不要写逗号。

  1. 函数

函数也是一个对象,函数中可以封装一些功能(代码),在需要时可以执行这些功能。

用typeof检测一个函数对象是,会返回function。

  1. 创建函数
  2. 使用构造函数来创建一个函数对象(基本不用)

创建一个函数对象,可以将要封装的函数以字符串的形式传递给构造函数,我们在实际开发中很少使用构造函数来创建一个函数对象

var fun = new Function ("string");

  1. 使用 函数声明 来创建一个函数
  • 封装到函数中的代码不会立即执行
  • 函数中的代码会在函数调用时执行
  • 调用函数语法: 函数对象()
  • 当调用函数时,函数中封装的代码会按照顺序执行

语法: function 函数名([形参1,形参2,形参3]){

语句...

}

  1. 使用 函数表达式 来创建函数

语法:var 函数名 = function (形参1,形参2,形参3) {

语句...

}

  1. 函数的参数(形参和实参)

定义一个用来求和的函数,可以在函数中的()中来指定一个或多个形参(形式参数),声明形参就相当于在函数内部声明了对应的变量,但是并不赋值。

调用函数时解析器不会检查实参类型,也不会检查实参数量,多余实参不会被复制,少于实参数量时,没有对应实参的形参将是undefined。

  1. 函数的返回值 return
  • return语法: return 值
  • return后的语句都不会执行,如果return后不跟值,返回undefined,不写return,也会返回undefined
  • 函数也可以是对象,将匿名函数做为实参传递给函数:
  • 返回值和函数对象:
  • // getArea() 调用函数 相当于使用的函数的返回值
  • // getArea 函数对象 相当于直接使用函数对象
  1. brack、continue和return的区别
  2. 立即执行函数

立即执行函数只会执行一次。

只调用一次,用()扩起来一个匿名函数标识他是一个整体,函数对象();

  1. 方法
  • 对象的属性值可以是任何数据类型,也可以是函数
  • 函数作为对象的属性时,我们称这个函数是这个对象的方法
  1. 枚举对象中的属性 for...in遍历
  • 对象中有几个属性,循环体就执行几次
  • 执行时会将对象的属性名赋值给变量
  1. 全局作用域/函数作用域

作用域指一个变量作用的范围

1. 全局作用域:

  • 直接写在script标签的都在全局作用域 。
  • 在页面打开时创建,在页面关闭时销毁。
  • 在全局作用域中有一个全局对象window,由浏览器创建,可以直接使用,创建的变量都会作为window对象的属性保存【var window.a = 10; window.alert(); 】;
  1. 变量提升

参考:https://www.w3school.com.cn/js/js_hoisting.asp

使用var关键字声明的变量,会在所有代码执行之前被声明,不用var时不会被声明提前。

  1. 函数提升
  • 函数提升:function 函数(){},最先被创建,可以提前
  • 函数表达式不提升:不能在声明前调用

2. 函数(局部)作用域:

  • 调用函数时创建函数作用域,函数执行完后作用域销毁。
  • 每调用一次创建一个新函数作用域,他们之间是互相独立的。
  • 局部可以访问到全局的变量,全局不能访问局部变量。
  • 局部会先在自身作用域寻找变量,就近原则。
  1. debug

  2. this

含义:解析器在调用函数时,每次都会向函数内部传递一个隐含的参数,这个隐含的参数就是this,this是浏览器传进来的参数,this指向的是一个对象,这个对象我们称为函数执行的上下文对象。

  • 普通函数中 this 的指向,是 this 执行时的上下文
  • 箭头函数中 this 的指向,是 this 定义时的上下文
  1. ES5三种函数调用方式:

  • fun(a,b);
  • obj.child.method(a,b);
  • fun.call(context,a,b); //指向context,默认undefined(指向window),
  1. this的5种绑定

  2. 默认绑定(非严格模式下this指向全局对象, 严格模式下this会绑定到undefined)
  3. 隐式绑定(当函数引用有上下文对象时, 如 obj.foo()的调用方式, foo内的this指向obj)
  4. 显示绑定(通过call()或者apply()方法直接指定this的绑定对象, 如foo.call(obj))
  5. new绑定
  6. 箭头函数绑定(this的指向由外层作用域决定的)

参考:

https://zhuanlan.zhihu.com/p/23804247

https://www.w3school.com.cn/js/js_this.asp

  1. 创建对象

  2. 使用工厂模式创建对象

  3. 使用构造函数创建对象

构造函数:

  • 创建一个构造函数,用来创建Person对象,首字母大写
  • 和普通函数的区别:普通函数直接调用,构造函数需要使用new关键字调用
  • 执行流程:
  1. 创建一个新对象
  2. 将新建的对象设置为函数中的this,在构造函数中实体this引用新对象
  3. 逐行执行函数中的代码
  4. 将新建对象作为返回值返回
  5. 原型对象

  6. 原型对象prototype

原型对象:prototype

隐含属性:__proto__

  • 当函数以构造函数的形式调用时,它所创建的实例对象都会有一个隐含的属性__proto__,指向该构造函数的原型对象,通过__proto__访问该属性;
  • 原型对象相当于一个公共区域,同一个类的实例都可以访问到这个原型,我们可以将对象公共内容统一设置到原型对象中;
  • 我们访问对象的一个属性或方法时,会先在自身找, 自身没有则访问原型对象;
  • 优点:不会污染全局作用域

  1. 向原型对象中添加方法

实例:

  1. 检查属性in和hasOwnProperty

  2. 原型的toString()方法

  3. 原型链

原型链是利用原型,让一个引用类型继承另一个 引用类型的属性和方法。

实例的contructor = 构造函数

  1. 垃圾回收(GC)

垃圾回收:

  • 当一个对象没有任何的变量或属性对它引用,我们无法操作该对象。
  • js具有自动垃圾回收机制,会自动将垃圾对象从内存中销毁。
  • 我们将不再使用的对象设置为null即可。

  1. 数组Array

  2. 数组简介

  • 数组也是一个对象,与普通对象功能类似,作用存值。
  • arr[index]:数组[索引],索引从0开始。
  • arr.length:数组.length可以获取数组的长度(元素的个数)。

    • 向数组最后一个位置添加元素:arr[arr.length] = 70; // 数组[数组.length] = 值
  1. 数组的常见方法(2)

  2. 数组遍历

  3. for循环遍历

实例:将年纪满18的提取出来

  1. forEach()遍历

回调函数: forEach()方法需要一个函数作为参数,像这种函数,由我们创建但不由我们调用的称为回调函数。

缺点:不兼容IE8及以下

  1. slice()

slice(开始位置索引,结束位置索引):slice从第a个截到第b个

  1. splice()

  • splice(开始位置索引,删除的数量,传递新元素) : splice从第a个删除b个;
  • splice还可以再添加元素
  1. splice数组去重

  2. call() 和 apply()

相同:

  • 都会调用函数执行
  • call()和apply()可以将一个对象指定为第一个参数
  • 此时这个对象将会成为函数执行时的this,参数是谁this就是谁
  • 可以修改上下文对象this

不同:

  • call()可以将实参在对象之后依次传递
  • apply()需要将实参封装到一个数组中统一传递

this:

  1. 以函数的形式调用,this指向window
  2. 以方法的形式调用,this是调用方法的对象
  3. 以构造函数的形式调用,this是新创建的对象
  4. 以call和apply调用,this是指定的对象
  5. arguments【类数组对象】

在调用函数时,浏览器每次都会传递进两个隐含的参数:

  1. 函数的上下文对象this
  2. 封装实参的对象arguments
  • arguments是一个类数组对象,也可以通过索引来操作数组
  1. Date【时间】

获取时间和获取时间戳:

  1. Math【数学运算】

参考:https://www.w3school.com.cn/js/js_math.asp

Math:属于工具类,封装了数学运算相关的属性和方法

  1. 包装类

包装类:可以临时将基本数据类型转为对象,浏览器底层自己用的

  1. 字符串相关方法

参考: https://www.w3school.com.cn/js/js_string_methods.asp

  1. 检索字符串
  2. 截取字符串
  3. 转为大小写
  4. DOM(文档对象模型)

  • Document Object Model:文档对象模型,用来操作网页的
  • Node:节点,构成网络的任何部分都是一个节点,类型不同。

    • 文档节点:<html></html>
    • 元素节点:<p></p>
    • 属性节点:id="box"
    • 文本节点:文字~
  • 获取元素节点:

    • getElementById():通过id获取一个元素节点对象
    • getElementsByTagName():通过标签名获取一组元素节点对象
    • getElementsByName():通过name属性获取一组元素节点对象,表单常用
  • 事件:用户和浏览器的交互行为,比如点击按钮、鼠标移动、关闭按钮;所有的操作都属于事件,处理事件:

Dom事件: https://www.w3school.com.cn/js/js_htmldom_events.asp

  1. 文档的加载 window.onload

  2. dom查询的其他方法

  3. dom增删改

dom方法: https://www.w3school.com.cn/htmldom/dom_methods.asp

增删改demo1:

增删改demo2:

  1. 修改class

  2. json

前端html写的 后端java写的

obj = {} : js对象 只有js认识

需要将js对象传给服务器 转为json

将json转为字符串 任何语言都认识

json的作用:交互传递数据,字符串,使不同语言都可以使用

json属性名必须加双引号。其他和js一致

json分类:

1. 对象: json对象

2. 数组: json数组

json只允许传递: 字符串,数值,布尔,null,普通对象,数组

键值对

json数组:保存多个json对象。

需要将字符串转为js对象

数据交换格式 轻量级数据格式

- JSON.parse():将json转为js对象

- JSON.stringify():将js对象转为json

IE7 JSON

兼容IE7以下,eval():可以用来执行一段字符串形式的js代码,并将返回,性能差不建议使用。

  1. 事件冒泡

  2. 事件冒泡(Bubble)

事件冒泡指事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发。

取消冒泡:将事件对象的cancelBubble设置为true。

  1. 事件委派

  2. js报错整理

https://blog.csdn.net/weixin_39843414/article/details/109108391

  1. Error:基本错误类型,一般是程序员抛出的异常

  1. SyntaxError :语法错误,解析错误

  1. TypeError :类型错误

  1. ReferenceError :引用错误

  1. RangeError :边界错误

  1. URIError:url错误
  2. 自定义异常
查看原文

赞 0 收藏 0 评论 0

江文艺 发布了文章 · 4月2日

前端那些事三(网络浏览器)

浏览器网络相关:

  1. OSI的七层模型、TCP/IP四层模型

    1. TCP的三次握手(为什么要三次握手,一次呢?四次挥手是什么?)
    2. 输入URL到页面加载完成需要哪几步?
    3. TCP和UDP的区别
  2. 报文
  3. HTTP的特点?(快速灵活,为什么用http不用其他的?)
  4. HTTP有哪些方法?常用有哪些?
  5. get和post的区别是什么?
  6. options的作用?
  7. HTTP状态码?
  8. http1和http2的区别?
  9. 讲出至少五种解决跨域的办法,jsonp(写一个简易jsonp),CORS
  10. jsonp的优缺点?
  11. http和https的区别
  12. http缓存都有哪些,强缓存和协商缓存有什么区别
  13. localStorage 与 sessionStorage 与cookie的区别总结
  14. 什么是同源策略,为什么出现跨域问题?请求方式,域名和端口不同
  15. 什么是事件委托,事件捕获
  16. DNS缓存,原理
  17. WebSocket属于什么(简单应用API),原理

  1. OSI的七层模型、TCP/IP四层模型

  • TCP的三次握手(为什么是三次握手,一次呢?四次挥手是什么?)
  • 输入URL到页面加载完成需要哪几步?
  • TCP和UDP的区别
  1. OSI的七层模型:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。
  2. TCP/IP:网络接口层/链路层、网络互联层、传输层、应用层。

1.1 TCP三次握手

https://www.jianshu.com/p/f1b3decb07f8

  • 客户端向服务器发送SYN包,等待服务器确认;
  • 服务器收到SYN包,需要确认后向客户端发起一个SYN包;
  • 客户端收到服务器的SYN+ACK包后则向服务器发起确认包,完成三次握手。

为什么不能一次或两次?

因为客户端和服务器都要做好发送数据的准备后,才能建立通信。防止了服务器端的一直等待而浪费资源。

tcp是一个全双工的协议,意思是客户端和服务端之间的通信可以同时来回流动,为了保证通信的可靠性以及确定对方能收到自己的请求,tcp采用半关闭原则,意思是在收到一个请求后必须发送回复请求,只通信一次或者两次无法确定对方是否收到请求

  1. 1.1 四次挥手其性质为终止协议
  • TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。
  • 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
  • 服务器关闭客户端的连接,发送一个FIN给客户端。
  • 客户端发回ACK报文确认,并将确认序号设置为收到序号加1。

保证数据接收完整。

1.2 输入URL到页面加载完成需要哪几步?

  1. 输入网址URL
  2. 是url还是字符串 搜索引擎
  3. 缓存机制,判断本地是否有缓存,
  4. 没有缓存,DNS解析(解析得到IP),https建立TLS连接
  5. 解析的时候,服务器负载均衡
  6. TCP连接(三次握手)
  7. 发送http请求(请求方法,get、post)
  8. 接受响应,判断状态码选择处理方式(返回http状态码)
  9. 判断缓存
  10. 解码
  11. 渲染
  12. 连接结束(四次挥手)
  13. 下载html dom树,下载css OM树,结合rander树

参考:https://zhuanlan.zhihu.com/p/34288735

https://mp.weixin.qq.com/s?__...

1.3 TCP和UDP的区别

  • TCP:一对一;面向连接;面向字节流;传输大量数据;速度慢;(web开发,http)
  • 优点:可靠,通过TCP连接传输的数据无差错、不丢失、不重复,并且能够按序到达。
  • UDP:一对多;面向非连接(发送数据前不需要建立连接);面向报文;传输少量数据,速度快;(应用:直播,视频,应用程序)
  • 缺点:不保证交付可靠,丢包。

  1. 报文

1. 请求报文(发送请求的报文):

  1. 请求头Request Headers:
  • Accept :请求报文可通过一个“Accept”报文头属性告诉服务端 客户端接受什么类型的响应。
  • Cookie :客户端的Cookie就是通过这个报文头属性传给服务端的哦!
  • Referer :表示这个请求是从哪个URL过来的
  • Cache-Control :对缓存进行控制,如一个请求希望响应返回的内容在客户端要被缓存一年,或不希望被缓存就可以通过这个报文头达到目的。
  1. 请求行:
  • HTTP方法,get/post请求
  • HTTP协议
  1. 请求体:

2. 响应报文(服务端相应的报文)

状态行,响应首部,内容实体,

  1. HTTP协议的主要特点?(快速灵活,为什么用http不用其他的?)

http是超文本传输协议,应用层协议的一种,应用层协议:DNS、FTP、SMTP、HTTP、SNMP、Telnet。

特点:简单快速灵活,属于应用层的面向对象的协议,基于TCP的可靠传输。

http是不保存状态的协议(无状态协议)

  1. HTTP有哪些方法?常用有哪些?

  2. GET(获取)
  3. POST(传输)
  4. PUT(更新)
  5. DELETE(删除)
  6. HEAD(获取报文首部)
  7. OPTIONS(询问)
  8. CONNECT
  9. get和post的区别是什么?

  • 数据类型:get只接受ASCII字符,而post没有限制,允许二进制。
  • 前进/后退:get在浏览器回退/刷新时是无害的,而post会再次提交请求。
  • 请求长度:get长度取决于浏览器窗口的长度,post长度不限制
  • 缓存:get能被缓存,post不能。
  • 请求次数:get请求一次(请求头请求体一起发送),post请求两次(先发送请求头,等100 continue,然后再发送请求体,连着发送)。
  • 安全性:post比get 更安全,因为GET参数直接暴露在URL上,POST参数在HTTP消https息主体中,而且不会被保存在浏览器历史或 web 服务器日志中,。
  • 编码格式:post支持多种编码格式 gbk utf-8
  • GET产生一个TCP数据包,浏览器会把http header 和 data 一并发送
  • POST产生两个TCP数据包(除了FireFox)先发送header,浏览器响应100 continue,浏览器再发送data

specification : 相关的RFC,

  1. options的作用?

  2. 检测服务器所支持的请求方法
  3. CORS中的预检请求(检测某个接口是否支持跨域)
  4. HTTP状态码,http响应,信息响应?

  • 1开头:接受继续处理,(100 continue)
  • 2开头:表示成功 (200成功并返回 201已创建 202接收 203成功未授权 204成功无内容)
  • 3开头:重定向(301永久重定向,302临时重定向,304有缓存不用更新)
  • 4开头:客户端错误(400语法错误,403禁止被访问,没有权限,404资源页面不存在)
  • 5开头:服务端错误(500后端服务器挂了,501服务器不支持无法处理,502网关错误,后台建立连接超时,503服务器内部错误,504后台未建立连接超时,505不支持http协议版本)

https://mp.weixin.qq.com/s?__...

  1. URI 一个资源文件的不同辨表示方法

  • URI:统一资源标识符
  • URL:统一资源定位符
  • URN:统一资源名称
  1. 串行连接 持久连接 管道化持久连接 HTTP2.0多路复用

  • 串行连接: http1.0版本,每次发请求都要建立新的TCP连接,每次通信后都要断开TCP连接。
  • 持久连接:http1.1,连段没有提出断开连接,则保持持久TCP连接。
  • 管道化持久连接: 不用等待响应返回而发送下个请求并按数据返回响应。
  • HTTP2.0多路复用:http2.0
  • websocket: HTML5,客户端主动向服务器发请求,建立连接后。
  1. http1和http2的区别? 超文本传输协议

影响一个 HTTP 网络请求的因素主要有两个:带宽和延迟。

浏览器为每个域名最多同时维护6条TCP持久连接。

影响http1.1效率的因素是TCP启动慢,多条TCP竞争带宽,出现队头阻塞的问题,为了解决这个问题,http2采用通过引进二进制分帧层,多路复用,服务器推送,头部压缩。

1)在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。

2)在HTTP 1.1中则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。采用了keep-alive。

  1. http1的主要问题:

  2. 第一个原因,TCP 的慢启动,因为三次握手。
  3. 第二个原因,同时开启了多条 TCP 连接,那么这些连接会相互竞争固定的带宽。
  4. 第三个原因,HTTP/1.1 队头阻塞的问题,只有一个TCP管道。
  5. http1.1:

增加了持久连接;

浏览器每个域名同时维护6个TCP持久连接。

缺点:对带宽的利用率不强,(每秒最大发送接收的字节数)

  1. http2:

  2. 解决方案:要解决一个域名只使用一个TCP 长连接和消除队头阻塞问题。
  3. 优点:可以设置请求的优先级,支持服务器推送,大幅度的提升了 web 性能。
  4. 问题:队头阻塞无法解决,丢包率增加()
  5. 区别:http2采用通过引入二进制分帧层,

  • 多路复用机制(MultiPlexing):在TLS层,增加一个二进制分帧层,

TLS协议是会话层的安全传输协议,

即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。

  • 新的二进制格式(Binary Format),将请求分帧传输,可以进行二进制分帧层,HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。

二进制分帧层:分段带ID传输。

  • 头部压缩,对请求头和响应头进行压缩,减小体积。
  • 服务器推送(server push),同SPDY一样,HTTP2.0也具有server push功能。
  • 设置请求的优先级:
  1. HTTP2的持久连接和管线化:
  2. http3:

HTTP3:基于UDP协议推出一个QUIC协议,

在UDP基础上新增多路复用,0-RTT,使用TLS1.3加密,流量控制,有序交付,重传等。

  • 避免包阻塞:
  • 快速重启会话:
  1. 什么是浏览器同源策略?为什么会出现跨域问题?(请求方式,域名和端口不同)

  • 一种安全策略,保护本地数据,为了防止XSS、CSFR等攻击。
  • 同源的定义:协议(请求方式)、域名、端口相同。因为存在浏览器同源策略,所以才会有跨域问题。
  • 同源策略分为两种:

DOM 同源策略:禁止对不同源页面 DOM 进行操作。这里主要场景是 iframe 跨域的情况,不同域名的 iframe 是限制互相访问的。

XMLHttpRequest 同源策略:禁止使用 XHR 对象向不同源的服务器地址发起 HTTP 请求。

浏览器同源策略:https://www.cnblogs.com/laixiangran/p/9064769.html

了解预检请求嘛?

  • 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源
  • 防止XSS、CSFR等攻击, 协议+域名+端口不同
  • jsonp; 跨域资源共享(CORS)(Access control); 服务器正向代理等

预检请求: 需预检的请求要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响

  1. 代理服务器

代理服务器:客户端和服务端之间的中间商,可以作为缓存服务器。

  • 正向代理:
  • 反向代理:
  • 反向代理解决跨域问题:两个服务器之间通信。

本地服务器在浏览器向本地服务发起请求》本地代理转发》目标服务器》响应数据后通过代理伪装成本地服务器请求的返回值》浏览器接收到目标服务器的数据

  • vue的proxyTable的作用,解决跨域问题。怎么实现。

与服务器联调的时候 vue.config.js, proxy设置请求反向代理

缓存服务器:频繁访问网络内容。提高访问速度。浏览器和原服务器之间的中间服务器。

  1. 解决跨域的办法,常用:

  2. jsonp 跨域:

jsonp 跨域通过script的src获取callback请求资源进行文件的传输,然后返回一个函数调用;

  1. 优点:兼容性好(兼容IE)
  2. 缺点:只支持get一种请求,不是官方API,容易受到xss攻击。
  3. 原理:script的src属性默认支持跨域
  4. 跨域资源共享(CORS):修改响应头

  • 跨域资源共享(CORS)允许浏览器跨源服务器,需要浏览器和服务器同时支持,需要在服务器上配置Access-Control-Allow-Origon。

*不能带cookie

  • 简单请求:请求方式:get、post、head
  • 非简单请求:先发一次预检请求(options):put、delete

options是预检请求,在真正的请求发送出去之前,浏览器会先发送一个options请求向服务询问此接口是否允许我访问

浏览器在当前真实请求是非简单请求且跨域的情况下会发起options预检请求

与JSONP相比:

  • JSONP只支持get请求,cors支持所有请求(get、post);
  • JSONP支持性好,兼容老版本浏览器。

参考:http://www.ruanyifeng.com/blog/2016/04/cors.html

  1. hash: window.location

hash:location.hash + iframe;

  1. postMessage:

postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。

Awindow.postMessage(data,origin)

A窗口向B窗口发送请求:Awindow.postMessage('data','http://B.com')

  1. WebSocket协议跨域:

WebSocket协议跨域:HTML5一种新的持久化协议,用于H5聊天,即时线上跨域。

实时聊天,基于TCP协议,短轮询,浪费带宽,

长轮询,

http单向数据流,websocket链接客户端和服务器,在ws里

scoket.io

WebSocket心跳检测

不常用:

  1. nginx反向代理接口跨域:

同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题

  1. document.domain + iframe跨域:

两个页面都通过js强制设置document.domain为基础主域,就实现了同域.但是仅限主域相同,子域不同的跨域应用场景

  1. http和https的区别

http:因为http是无状态,明文传输的,容易造成中间人攻击,所以在http协议中加入安全层,加入SSL/TLS安全层,增加加密/解密的方式,相比http协议更安全。

SSL/TLS安全层:对发起 HTTP 请求的数据进行加密操作和对接收到HTTP 的内容进行解密操作。

TLS/SSL 的功能实现主要依赖于三类基本算法:散列函数 、对称加密和非对称加密散列函数 ,散列算法,MD5

RSA算法

https:安全,请求时间长,加载慢,花钱,证书

https安全性:

  1. 对称加密:加密和解密使用的密钥是相同的
  • 传输方式:

浏览器:发送加密套件列表和一个随机数 client-random,

服务器:从加密套件列表中选取一个加密套件,还会生成一个随机数 service-random,并将service-random 和加密套件列表返回给浏览器。最后浏览器和服务器分别返回确认消息。

  • 缺点:容易被破解

  1. 非对称加密:A、B两把密钥,公钥,私钥

缺点:效率低,影响速度,无法保证服务器到浏览器的安全

  1. 对称加密+非对称加密:用非对称加密的方式 传输 对称加密里的密钥,

非对称加密使用时,生成pre-master(两个随机数计算)。

优点:速度快+安全。

  1. 添加数字证书(消费):向CA证书机构申请数字证书,包含数字签名,非对称加密的公钥和个人信息。

证书的作用:一个是通过数字证书向浏览器证明服务器的身份,另一个是数字证书里面包含了服务器公钥。

证书也有公钥和私钥。证书加密一次,

CA证书用公钥,hash值,。

加密套件列表:客户端支持的加密和非对称加密的方式

  1. 浏览器如何验证数字证书
  • 有了 CA 签名过的数字证书,当浏览器向服务器发出请求时,服务器会返回数字证书给浏览器。浏览器接收到数字证书之后,会对数字证书进行验证。
  • 首先浏览器读取证书中相关的明文信息,采用 CA 签名时相同的 Hash 函数来计算并得到信息摘要 A;然后再利用对应 CA 的公钥解密签名数据,得到信息摘要 B;对比信息摘要 A 和信息摘要 B,如果一致,则可以确认证书是合法的,
  • 即证明了这个服务器是极客时间的;同时浏览器还会验证证书相关的域名信息、有效时间等信息。
  1. 区别:
  • HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头
  • HTTP 是不安全的,而 HTTPS 是安全的
  • HTTP 标准端口是80 ,而 HTTPS 的标准端口是443
  • 在OSI 网络模型中,HTTP工作于应用层,而HTTPS 的安全传输机制工作在传输层
  • HTTP 无法加密,而HTTPS 对传输的数据进行加密
  • HTTP无需证书,而HTTPS 需要CA机构wosign的颁发的SSL证书
  1. https是如何加密的?

  2. 密钥传输的过程,服务器做了什么事?浏览器做了什么事?密钥怎么传的?对称加密要怎么传?数字证书怎么校验?

  3. 常见加密算法有哪些?

  4. 浏览器缓存,强缓存和协商缓存有什么区别

https://mp.weixin.qq.com/s/Wvc0lkLpgyEW_u7bbMdvpQ

  1. 缓存位置:

    1. service worker:浏览器背后的独立线程,一般缓存
    2. memory chache:内存中的缓存,计算机内存
    3. Disk Cache:硬盘中的内存,速度慢
    4. Push Cache:推送缓存,http2,只在session中存在
  2. 缓存过程:

  1. 缓存机制:
  2. 缓存机制分为:强缓存和协商缓存
  3. 区别:是否发送请求,强缓存不发送请求,协商缓存至少发送一次请求。
  • 优先级: Cache-Control > expires > Etag > Last-Modified
  • 强缓存(本地缓存):不用跟服务器进行通信

    • 缓存字段:Expires和Cache-Control
    • Expires:绝对时间,资源失效的时间,
    • Cache-Control:相对时间,资源缓存的最大有效时间
    • Cache-Control的 max-age 优先级高于 Expires
  • 协商缓存:由服务器来决定是否使用缓存,至少和服务器有一次通信

    • 缓存字段:Last-Modified和ETag发送到服务器,确认资源是否更新。
    • Last-Modified 表示本地文件最后修改日期
    • ETag 是个标识,修没修改
    • 判断是否过期,先走etags(http1生成的),再走Last-Modified。 ETag 优先级比 Last-Modified 高。

页面怎么进行强缓存和协商缓存?

如果缓存过期了,我们就可以使用协商缓存来解决问题。协商缓存需要请求,如果缓存有效会返回 304。

协商缓存需要客户端和服务端共同实现,和强缓存一样,也有两种实现方式。

Last-Modified 和 If-Modified-Since

If-Modified-Since 会将 Last-Modified 的值发送给服务器,询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来。

参考:https://zhuanlan.zhihu.com/p/64635421

如果浏览器命中强缓存,则不需要给服务器发请求;而协商缓存最终由服务器来决定是否使用缓存,即客户端与服务器之间存在一次通信。

在 chrome 中强缓存(虽然没有发出真实的 http 请求)的请求状态码返回是 200 (from cache);而协商缓存如果命中走缓存的话,请求的状态码是 304 (not modified)。 不同浏览器的策略不同,在 Fire Fox中,from cache 状态码是 304.

浏览器会获取该缓存资源的 header 中的信息,根据 response header 中的 expires 和 cache-control 来判断是否命中强缓存,如果命中则直接从缓存中获取资源。

如果没有命中强缓存,浏览器就会发送请求到服务器,这次请求会带上 IF-Modified-Since 或者 IF-None-Match, 它们的值分别是第一次请求返回 Last-Modified或者 Etag,由服务器来对比这一对字段来判断是否命中。IF-None-Match是false时 ,则服务器返回 304 状态码,

IF-None-Match是true时,走200

并且不会返回资源内容,浏览器会直接从缓存获取;否则服务器最终会返回资源的实际内容,并更新 header 中的相关缓存字段。

  1. keep-alive:HTTP 长连接

  • 是客户端和服务端的一个约定,如果开启 keep-alive,则服务端在返回 response 后不关闭 TCP 连接;同样的,在接收完响应报文后,客户端也不关闭连接,发送下一个 HTTP 请求时会重用该连接。
  • http1.0默认关闭的,需要在http头加入"Connection: Keep-Alive”,才能启用Keep-Alive
  • http1.0默认开启keep-alive。
  • 浏览器默认开启keep-alive,
  1. http缓存都有哪些,

https://juejin.im/post/68449036824551096[](https://juejin.im/post/684490...

#heading-38

  1. http缓存、websql、indexDB、cookie、localstorage、sessionstorage、application cache、cacheStorage、flash缓存
  2. localStorage 与 sessionStorage 与cookie补充:

https://mp.weixin.qq.com/s?__...

https://zhuanlan.zhihu.com/p/159268611

cookie

localStorage

sessionStorage

存储大小

一般不超过4K

一般为5M

一般为5M

数据有效期

可设置失效时间,默认关闭浏览器失效

永久有效,除了手动清除

关闭页面失效

作用域

所有同源窗口共享

所有同源窗口共享

只在同浏览器共享

易用性

需要自己封装,原生的cookie接口不友好

原生接口可以接受,可以封装来对Object和Array有更好的支持

与服务端通信

每次会随http协议头带过去,cookie保存太多数据会带来性能问题

在请求时使用数据,不参与服务器通信

储存类型string

(补充:cookie通过http协议头带过去的)

indexDB存储大小无上限 储存类型键值对, 不能跨域 时效性

  1. CSRF攻击 跨站请求伪造

https://mp.weixin.qq.com/s?__...

跨站伪造请求

  • 概念:攻击者盗用你的身份,以你的名义发送恶意请求,比如:通过陌生连接,诱导用户点击。
  • CSRF如何产生的?

    • 用户信息存在cookie中,黑客通过储存token
  • 如何防止CSRF攻击?
  1. 在服务端做处理,尽量使用post请求,加入验证码,验证Referer
  2. 使用Cookie的SameSite属性:strict、lax(相对宽松)、none
  3. 验证来源地址:origin(不包含路径信息)和refer
  4. 加入CSRF token:
  5. 判断请求的来源:检测Referer(并不安全,Referer可以被更改)
  • CSRF自动防御策略:同源检测(Origin 和 Referer 验证)。
  • CSRF主动防御措施:Token验证 或者 双重Cookie验证 以及配合Samesite Cookie。
  • 保证页面的幂等性,后端接口不要在GET页面中做用户操作。

判断origin,没有再判断验证refer字段,请求。

Origin Header

Referer Header

但是Origin在以下两种情况下并不存在:

IE11同源策略: 302重定向:

  1. XSS攻击 跨站脚本攻击

XSS(Cross-Site Scripting,跨站脚本攻击)是一种代码注入攻击。攻击者在目标网站上注入恶意代码,当被攻击者登陆网站时就会执行这些恶意代码,这些脚本可以读取 cookie,session tokens,或者其它敏感的网站信息,对用户进行钓鱼欺诈,甚至发起蠕虫攻击等。

XSS 的本质是:恶意代码未经过滤,与网站正常的代码混在一起;浏览器无法分辨哪些脚本是可信的,导致恶意脚本被执行。由于直接在用户的终端执行,恶意代码能够直接获取用户的信息,利用这些信息冒充用户向网站发起攻击者定义的请求。

类型:

  • 反射型XSS:通过 URL 传递参数,当用户点击一个恶意链接,或者提交一个表单,或者进入一个恶意网站时,注入脚本进入被攻击者的网站。Web服务器将注入脚本,比如一个错误信息,搜索结果等,未进行过滤直接返回到用户的浏览器上。
  • 如何防御:转义对url的查询参数进行转义后再输出到页面。
  • DOM 型 XSS:html,前端代码不规范。
  • 如何防御:转义图片链接。
  • 存储型XSS:数据库,将恶意代码提交到目标网站的数据库中。
  • 如何防御:服务器接收到数据,在存储到数据库之前,进行转义/过滤、
  • SQL 注入:

如何让预防xss攻击?

  1. 服务端过滤做验证,在服务端使用 HTTP的 Content-Security-Policy 头部来指定策略,或者在前端设置 meta 标签;
  2. 服务端设置 CSP:开启白名单
  3. 后端设置HttpOnly:HttpOnly解决的是XSS后的Cookie劫持攻击,只能降低受损范围
  4. 对输入的内容和长度做限制:只能增加 XSS 攻击的难度。

jsonp过滤同域的代码有漏洞

  1. 点击劫持

点击劫持:攻击者将需要攻击的网站通过iframe嵌入自己的网页中,诱导用户点击,隐藏了一个透明的iframe,用外层假页面诱导用户点击。

防御办法:

  1. deny
  2. frame busting
  3. 使用X-Frame-Options协议头:微软提供,用来防御利用iframe嵌套的点击劫持攻击
  4. same origin:同源下的iframe
  5. allow-from-origin:
  6. 中间人攻击

https对称加密,非对称加密,混合加密,证书最为有效防止中间人攻击。

https://blog.csdn.net/oZhuZhiYuan/article/details/106650944

  1. cookie session token,为什么能通过cookie攻击,不能通过token攻击

https://mp.weixin.qq.com/s/diaE6WkB_UJxjuhLS9E20Q

  • cookie存在浏览器 session存在服务器 token明文传输,没有固定存放的地方
  • cookie不是很安全,session更安全。cookie容易被攻击。
  • 设置cookie时间过期,使用session-destory销毁对话。
  • 发送请求时会带cookie,不会自动带token
  • token存储在cookie中,token可以防御 csrf攻击
  • xss攻击

  • token如何进行加密?

  1. 垃圾回收

V8 实现了准确式 GC,GC 算法采用了分代式垃圾回收机制。因此,V8 将内存(堆)分为新生代和老生代两部分。

  1. 新生代:

    1. 存活时间短,使用 Scavenge GC 算法
    2. 内存空间:from空间和to空间。
    3. 三次折叠继续使用的放在老生代里
    4. 清理的过程:对象区域和空闲区域进行翻转。
    5. 新声明放在对象区,使用频率比较低的放在空闲区
  2. 老生代:

    1. 存活时间长且数量多,使用:标记清除算法和标记压缩算法。
    2. to空间(占比大小超过25%),标记整理算法。
    3. 对象树形结构,根据引用指向 被调用的对象 没有被标记的会被清除。
    4. 空间不连续的会整合。
  3. 怎么解决全停顿?

    1. 垃圾清理走的主线程,清理垃圾会造成卡顿,为了防止卡顿,会将垃圾分为很多份清理。逐渐插在主线程内。

为了降低老生代的垃圾回收而造成的卡顿,V8 将标记过程分为一个个的子标记过程,同时

让垃圾回收标记和 JavaScript 应用逻辑交替进行,直到标记阶段完成,我们把这个算法称

为增量标记(Incremental Marking)算法。

  1. 跨标签页通讯

  1. 内存泄漏

1.全局变量引起

2.闭包

3.dom清空,事件没有清除

4.子元素存在引用

子元素还存在引用时,先把子元素释放再释放父元素,否则父元素无法释放。

被遗忘的计时器

如何避免内存泄漏

1.ESLint 检测代码检查非期望的全局变量。

2.使用闭包的时候,得知道闭包了什么对象,还有引用闭包的对象何时清除闭包。最好可以避免写出复杂的闭包,因为复杂的闭包引起的内存泄漏,如果没有打印内存快照的话,是很难看出来的。

3.绑定事件的时候,一定得在恰当的时候清除事件。在编写一个类的时候,推荐使用 init 函数对类的事件监听进行绑定和资源申请,然后 destroy 函数对事件和占用资源进行释放。

全局变量 没有被声明

无法被回收 属于内存泄漏

没有释放的内存

  1. 事件冒泡、事件捕获、事件委托: https://www.jianshu.com/p/9c279d7330c6
查看原文

赞 0 收藏 0 评论 0

江文艺 发布了文章 · 4月2日

前端那些事二(CSS)

  1. Flex布局(弹性布局,默认主轴,交叉轴,讲下flex: 1)

  2. flex布局是一种弹性布局,将容器设置为flex布局后,float,clear,vertical-align将会失效,容器默认有两个轴(主轴,垂直交叉轴),默认沿主轴排列。
  3. 说下flex有哪些属性

外层容器属性:

flex-direction:控制主副轴 【轴向】

flex-wrap:控制换行(默认不换行)

flex-flow:是上两个的结合,简写

justify-content:主轴对齐方式 【对齐】

align-items:交叉轴对齐方式

align-content:多个轴线对齐

flex: 【弹性】

flex-direction: row | row-reverse | column | column-reverse;

flex-wrap: nowrap | wrap | wrap-reverse;

flex-flow: <flex-direction> <flex-wrap>;

justify-content: flex-start | flex-end | center | space-between | space-around;

align-items: flex-start | flex-end | center | baseline | stretch;

align-content: flex-start | flex-end | center | space-between | space-around | stretch;

子项目属性:

order:0 越小越靠前。

flex-grow:1 等分空间

flex-shrink:1 缩小比例

flex-basis: auto

flex 上面三个的缩写

align-self 对齐方式

  1. 使用flex实现垂直居中

  2. justify-content:center+align-items:center实现水平垂直居中排列
  3. flex: 1

  4. flex: 1是flex-grow、flex-shrink、flex-basis的缩写,等分大小
  5. 使用flex实现九宫格

  6. 响应式布局

  7. 你知道哪几种响应式布局的方式

  • 媒体查询
  • 百分百
  • rem
  • UI框架
  1. 块元素有哪些

  2. 说下块元素和行内元素的区别和特点

  • 块级元素会独占一行,默认情况下,其宽度自动填满其父元素宽度
  • 行内元素不会独占一行,相邻的行内元素会排列在同一行里
  1. 知道哪些空元素 (类似于img这样的单标签元素)

br、meta、hr、link、input、img

  1. css中有哪些属性是可以继承的

  • 不可继承的:display、baimargin、border、padding、background、height、min-height、max- height、width、min-width、max-width、overflow、position、left、right、top、 bottom、z-index、float、clear、table-layout、vertical-align、page-break-after、 page-bread-before和unicode-bidi。
  • 所有元素可继承:visibility和cursor。
  • 内联元素可继承:letter-spacing、word-spacing、white-space、line-height、color、font、 font-family、font-size、font-style、font-variant、font-weight、text- decoration、text-transform、direction。
  • 块状元素可继承:text-indent和text-align。
  • 列表元素可继承:list-style、list-style-type、list-style-position、list-style-image。
  • 表格元素可继承:border-collapse。
  1. 了解css的动画吗?说下transform

  • 2D:translate(x,y)平移,scale(x[,y]?)缩放,rotate(angle)旋转
  • 3D:translate3d(x,y,z),scale3d(x,y,z),rotate3d(x,y,z,angle)
  1. CSS3新特性,伪类,伪元素,锚伪类

  2. 增加很多选择器:(E:nth-child(n),E:last-child:,E:disabled,E:checked)
  3. CSS3动画相关:Transition过渡,Transform变换(3D旋转)和Animation动画
  4. 边框,阴影,圆角,背景(background-size)
  5. 文字效果(word-wrap,多行显示省略号)
  6. 渐变(linear-gradient,radial-gradient)
  7. 盒模型

常见伪类::focus、:hover、:link、visited、:first-child等;单冒号;伪类的概念

常见伪元素:::after、::before等(单冒号为了兼容IE,是CSS2的语法)。双冒号;用于创建不存在的DOM树元素。

锚伪类:用来表示链接的状态,顺序:a:link - a:visited - a:hover - a:actived。

  1. css垂直居中的n种方法

  • 宽高不定,水平垂直居中:

    • 绝对定位+transform:

position: absolute;left: 50%;top: 50%;transform: translate(-50%,-50%);

  • flex布局:(主轴居中,交叉轴居中)

display: flex;justify-content:center;align-items:center;

  • 父元素设置display: table-cell+vertical-align: middle实现
  • 宽高固定:

    • 绝对定位+margin:auto

position: absolute; left: 0; right: 0; bottom: 0; top: 0; margin: auto;

  • 绝对定位+margin负间距水平垂直居中

position: absolute; left: 50%; top: 50%; margin-left: -50px; margin-right: -50px;

  • line-height:针对单行文本
  1. 盒模型哪两种模式?什么区别?如何设置

  • 标准模式: box-sizing: content-box; 宽高不包括内边距和边框
  • 怪异模式: box-sizing: border-box(IE)
  1. 请谈谈对px、em、rem、vh、wh等单位的理解。你还用过哪些单位

  • px,如果显示器屏幕分辨率相同则可看做是绝对单位,如果显示器屏幕分辨率不同则相对于显示器屏幕分辨率。
  • em,相对于该元素font-size属性值,由于font-size是可继承属性,因此如果该元素未被显式设置font-size属性值,则会继承该元素的父元素的font-size值,如果该元素的父元素也未显式设置font-size属性值… …最终继承自根元素(HTML元素),如果根元素也没有被显示设置font-size属性值,则使用用户代理默认的font-size属性值。
  • rem,root em, 是CSS3新增的一个相对单位,与em的区别在于:使用rem为元素设置font-size属性值时,仅相对于根元素(HTML元素)。
  • vh,viewpoint height,视窗高度,1vh等于视窗高度的1%。
  • vw,viewpoint width,视窗宽度,1vw等于视窗宽度的1%。
  • in,pt
  1. 说下rem,em,px的区别

  • rem相对于根元素(html)
  • em相对于最近一个设置字体大小的父元素
  • px绝对单位,相对于显示器分辨率
  1. 说下rem的实现

  • rem相对于根元素(html),移动端设置html的font-size: calc(100vw / 7.5);
  1. 如何解决不同浏览器的样式兼容性问题?

  • 在确定问题原因和有问题的浏览器后,使用单独的样式表,仅供出现问题的浏览器加载。这种方法需要使用服务器端渲染。
  • 使用已经处理好此类问题的库,比如 Bootstrap。
  • 使用 autoprefixer 自动生成 CSS 属性前缀。
  • 使用 Reset CSS 或 Normalize.css。
  1. display: none与 visibility:hidden的区别:

  2. display: none与 visibility:hidden虽然都是隐藏元素。但前者是使元素从dom结构中消失,后者是dom中依然存在只是不在界面显示。因此前者为回流(需要改变dom结构),后者为重绘。
  3. CSS优先级

  • !improtant的优先级最高
  • 行内样式
  • id>class
  • 优先级相同时,选择写在后面的样式
  • 总结:!important > 行内样式>ID选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性

improtant影响哪些,权重值

  • 元素选择符: 1 div{ }
  • class选择符: 10 .class{ }
  • id选择符:100 #id{ }
  • 内联样式:1000 style="..."
  • !important声明的样式优先级最高,该样式声明会覆盖CSS中任何其他的声明,使用 !important 不是一个好习惯,因为它改变了你样式表本来的级联规则,从而难以调试。要优化考虑使用样式规则的优先级来解决问题而不是 !important。
  1. base64图,优缺点

base64编码可以将图片添加到css中,实现css请求下载图片。

优点:减少图片请求,(雪碧图也可以减少请求)

缺点:图片的加载会影响css文件大小比源文件大1/3,且IE8以下不兼容。

  1. 性能优化:骨架屏

骨架屏可以理解为是当数据还未加载进来前,页面的一个空白版本,在页面完全渲染完成之前,用户会看到一个样式简单,描绘了当前页面的大致框架的骨架屏页面,然后骨架屏中各个占位部分被实际资源完全替换,这个过程中用户会觉得内容正在逐渐加载即将呈现,降低了用户的焦躁情绪,使得加载过程主观上变得流畅。

骨架屏实现原理很简单,就是通过占位线框元素,渐进式加载数据。

骨架屏是结合了懒加载功能,在页面没有加载完成之前,先呈现页面基本结构。

  1. 什么是 FOUC(无样式内容闪烁)?你如何来避免 FOUC?

FOUC - Flash Of Unstyled Content 文档样式闪烁

<style type="text/css" media="all">@import "../fouc.css";</style>

而引用CSS文件的@import就是造成这个问题的罪魁祸首。

IE会先加载整个HTML文档的DOM,然后再去导入外部的CSS文件,因此,在页面DOM加载完成到CSS导入完成中间会有一段时间页面上的内容是没有样式的,这段时间的长短跟网速,电脑速度都有关系。

解决方法:只要在<head>之间加入一个<link>或者<script>元素就可以了。

  1. 什么是bfc,如何创建bfc?那些可以创建BFC?

BFC(Block formatting context)直译为"块级格式化上下文"。

  1. 创建BFC来避免垂直外边距叠加,边界崩塌
  2. 创建BFC来清除浮动
  3. 创建BFC来实现自适应布局

absolute fixed inline-block table overflow

  1. 回流和重绘(为什么要尽量减少),页面渲染

  • 回流:影响页面布局时会发生回流
  • 重绘:不影响页面布局,
  • 回流:DOM结构的增删改
  • 重绘: 颜色,背景, 字体等视觉上页面的改变

为什么要减少:

回流一定会触发重绘,重绘不一定触发回流,当页面很大的时候,回流时会重新加载页面。


css3新特性:https://juejin.im/entry/6844903486618861575

查看原文

赞 2 收藏 2 评论 0

江文艺 发布了文章 · 3月23日

前端那些事一(HTML)

  1. HTML5或者css3的新特性

  2. 你有用到哪些新标签

html:header,nav,section,aside,footer,video,audio

css:transform,translate,animation

  1. 新特性主要包括哪几大块?你项目中有用到哪些?

html: 语义化标签,增强型表单,多媒体标签,图形标签

css: 选择器,动画,边框阴影渐变,盒模型,伪类,伪元素

  1. canvas有用过吗

通过JS和HTML的<canvas>元素来绘制图形的方式

  1. HTML5语义化(Html5有哪些新特性)

什么是语义化?就是用合理、正确的标签来展示内容,比如h1~h6定义标题。

  • 易于用户阅读,样式丢失的时候能让页面呈现清晰的结构。
  • 有利于SEO,搜索引擎根据标签来确定上下文和各个关键字的权重。
  • 方便其他设备解析,如盲人阅读器根据语义渲染网页
  • 有利于开发和维护,语义化更具可读性,代码更好维护,与CSS3关系更和谐。

语义化标签:

<header>:定义页眉

<nav>:定义导航

<section>:定义文档中的区段

<time>:定义日期和时间

<article>:定义文章

<aside>:定义文章的侧边栏

<figure>:定义一组媒体对象以及文字

<figcaption>:定义figure的标题

<footer>:定义页脚

  1. 关于meta viewport, 属性

将视口大小设置为可视区域的大小。

通过meta设置视口大小(保证在移动端不自动缩放网页的尺寸):

meta标签的属性:

  1. Html5有哪些新特性

  • 增加了语义标签(header,nav,section,aside,footer等)
  • 增强型表单,新增input类型和属性
  • 类型type:email,number,date,range,color
  • 属性:placeholder,min,max,readonly,disabled
  • doctype和字符编码的声明,默认UTF-8。
  • 新的多媒体标签:视频、音频
  • 新的图形标签:svg,canvas绘图
  • 废弃了一些标签(font,center,big,dir)
  1. 浏览器的标准模式和怪异模式

  • 根据document.compatMode属性判断,“CSS1Compat”是标准模式,“BackCompat”是怪异模式。
  • 标准模式:浏览器按W3C标准解析执行代码;一般用<!doctype html>声明,盒模型box-sizing:content-box(没有把padding,border算进去)。
  • 怪异模式:使用浏览器自己的方式解析执行代码,盒模型box-sizing: border-box,怪异模式为了兼容旧版本浏览器,IE低版本获取不到document.doucumentElement.clientWidth。
  1. xhtml和html的区别

  • xhtml的语法更严谨,要求标签小写,正确嵌套,顺序正确,属性使用双引号,不允许使用target="_blank"。
  1. 使用data-的好处

  • 是H5新增的自定义属性,通过jQuery的data(' ')获取,能被js很好的操作,方便数据绑定
  1. canvas

  • 通过JS和HTML的<canvas>元素来绘制图形的方式
  1. css js放置位置和原因

  • css的<link>标签放在head标签之间,js的<script>放在</body>前;
  • 原因:<link>里面的href表示超文本引用,浏览器能识别css文档不会停止加载,防止出现样式问题;<script>使用src引用,浏览器解析时会停止对文档的渲染直到该资源加载完成,
  • 性能优化:当把js放在头部时,为了解决阻塞问题,可以在<script>里添加defer(延迟)和async(异步);

    • 遇到网络请求
    • 当使用defer时,js和html并行下载,不会阻塞dom树的创建,当dom树创建完成时才会执行js
    • 当使用async时,js和html并行下载,当下载完会立即执行js,执行期间会阻塞html的解析

  • 延伸问题:href和src的区别

    • href表示超文本引用,用在link、a等元素上,href识别css文件,不影响加载
    • src表示引用资源,浏览器解析src,会暂停其他资源,直到将该资源加载编译完成,也是将js脚本放在底部的原因。
  1. 什么是渐进式渲染,渐进增强,优雅降级

  • 作用:提升性能,加载速度更快;
  • 懒加载:
  • 优先级:
  • 异步加载:

渐进增强,优雅降级

  • 渐进增强(Progressive Enhancement):一开始就针对低版本浏览器进行构建页面,完成基本的功能,然后再针对高级浏览器进行效果、交互、追加功能达到更好的体验。
  • 优雅降级(Graceful Degradation):一开始就构建站点的完整功能,然后针对浏览器测试和修复。比如一开始使用 CSS3 的特性构建了一个应用,然后逐步针对各大浏览器进行 hack 使其可以在低版本浏览器上正常浏览。

渐进增强相当于向上兼容,而优雅降级相当于向下兼容。绝大多数更采用渐进增强的方式。

  1. 懒加载的原理?

  2. 解释:延时加载,通过用户滚动页面,自动获取更多的数据,而新得到的数据不会影响原有数据的显示,最大程度上减少服务器端的资源耗用。

原理:将img标签中的src链接设为同一张图片(空白图片),将其真正的图片地址存储在img标签的自定义属性中(比如data-src)。当js监听到该图片元素进入可视窗口时,即将自定义属性中的地址存储到src属性中,达到懒加载的效果。

参考:

html面试题: https://juejin.im/post/6844904176837722120#heading-1

前端面试题: https://mp.weixin.qq.com/s/BCpIttqUQ__eOMr5w6X2Vw

查看原文

赞 0 收藏 0 评论 0

认证与成就

  • 获得 235 次点赞
  • 获得 6 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 6 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2017-05-10
个人主页被 1.8k 人浏览