杂碎知识点集合
for in和正常for循环的区别
在遍历数组时,正常的 for
循环通常比 for...in
循环更适合。虽然 for...in
循环可以用于遍历数组,但它有一些潜在的问题和限制。
下面是一些使用 for
循环相对于 for...in
循环的优势:
- 顺序遍历:
for
循环可以按照数组元素的顺序进行迭代。而for...in
循环在遍历数组时,并不能保证按照特定顺序遍历,因为它遍历的是对象的属性。 - 不包含原型链上的属性:
for
循环仅遍历数组自身的索引,不包括原型链上的属性。而for...in
循环会遍历对象的所有可枚举属性,包括原型链上的属性,这可能会导致意外的行为。 - 性能优化:
for
循环通常比for...in
循环具有更好的性能。因为for
循环只需要维护一个迭代变量,并直接通过索引访问数组元素,而for...in
循环需要处理对象的所有属性。
建议使用for循环!!!
async
async是异步的意思,await则可以理解为async wait ,所以可以立即async就是用来声明一个异步方法,而await是用来等待异步方法执行的。
扩展:
JSONPlaceholder 是一个免费的在线 REST API,用于开发和测试前端应用程序。它提供了一组模拟的 HTTP 接口,可以进行常见的 CRUD(创建、读取、更新、删除)操作,如获取用户信息、文章、评论等。这样,开发人员可以在不使用真实后端服务的情况下,通过 JSONPlaceholder 来模拟和测试前端应用程序的数据交互。
javascript
function f() { return Promise.resolve('TEST'); }
async function asyncF() { return 'TEST'; }
这两种写法都是等效的,第一种使用传统的Promise去创建,第二种使用了语法糖。
Promise.resolve()
可以创建一个返回给定值的 Promise 对象,这里返回的是字符串 'TEST'
用async声明的函数会被自动封装为一个 resolved 状态的 Promise 对象。
javascript
async function fn1() {
console.log(1)
await fn2()
console.log(2) // 阻塞
}
async function fn2() {
console.log('fn2')
}
fn1()
console.log(3);
await 会阻塞下面的代码(即加入微任务队列),先执行 async外面的同步代码,同步代码执行完,再回到 async 函数中,再执行之前阻塞的代码
所以上述输出结果为:1,fn2,3,2
fetch网络请求接口
fetch
方法已经内置在 JavaScript 中,因此通常不需要安装额外的插件或库就可以使用它。
注意事项:
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它使 JavaScript 可以在服务器端运行。VS Code 是一个代码编辑器,它本身并不是 Node.js 环境,但是可以用于开发 Node.js 应用程序。 也就是说在兼容旧版浏览器或在 Node.js 环境中使用 fetch
,则可能需要考虑使用相关的 polyfill 或库来提供 fetch
功能。
transition
在css3中,为了添加某种效果可以从一种样式转变到另一个的时候,无需使用Flash动画或者javascript. 直接使用transition
transition控制的是属性值的过渡效果,而不是特定的属性
cursor: pointer; 鼠标放上去会变成手性指示
数据加密
加密方式:对称加密,非堆成加密,哈希算法。
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Symmetric Encryption Example</title>
</head>
<body>
<h1>Symmetric Encryption Example</h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<script>
// 定义一个密钥(需要确保密钥的安全性)
const key = "mySecretKey123";
// 待加密的数据
const data = "Hello, this is a secret message.";
// 加密函数
function encryptData(data, key) {
const encryptedData = CryptoJS.AES.encrypt(data, key).toString();
return encryptedData;
}
// 解密函数
function decryptData(encryptedData, key) {
const decryptedData = CryptoJS.AES.decrypt(encryptedData, key).toString(CryptoJS.enc.Utf8);
return decryptedData;
}
// 加密数据
const encryptedData = encryptData(data, key);
console.log("Encrypted Data:", encryptedData);
// 解密数据
const decryptedData = decryptData(encryptedData, key);
console.log("Decrypted Data:", decryptedData);
</script>
</body>
</html>
以上是使用对称加密中的AES加密的过程。
8中数据类型
- 在JS中,我们已知有5种基本数据类型:String、Number、Boolean、Undefined、Null。
- 一种引用数据类型:Object 包含(Function, Array)
Symbol、BigInt
es6的时候新增Symbol数据类型,每个通过Symbol()创建的对象属性值都是独一无二的,避免了重复。
ini
// 创建一个 Symbol 值
const mySymbol = Symbol('description');
// 使用 Symbol 作为对象的属性名
const obj = {
[mySymbol]: 'Hello, Symbol!'
};
console.log(obj[mySymbol]); // 输出: Hello, Symbol!
在 JavaScript 中,普通的 Number 类型使用双精度浮点数表示,其最大安全整数是 2^53 - 1,es10中新增BigInt,它可以表示任意精度的整数,取决于计算机内存的大小
BigInt 类型的字面量以 "n" 结尾,用来区分普通的 Number 类型
定位
-
position属性取值:static(默认)、relative、absolute、fixed、inherit、sticky。
-
float属性取值:none(默认)、left、right、inherit。
-
display属性取值:none、inline、inline-block、block、table相关属性值、inherit。
多做案例!!!
POST和GET请求的区别
1.针对数据操作的类型不同.GET对数据进行查询,POST主要对数据进行增删改!简单说,GET是只读,POST是写。
2.参数大小不同. GET请求在URL中传送的参数是有长度的限制,而POST没有限制
3.安全性不同. GET参数通过URL传递,会暴露,不安全;POST放在Request Body中,相对更安全
4.浏览器回退表现不同 GET在浏览器回退时是无害的,GET 请求可能会比较宽松地进行重试,而 POST 请求则会更加谨慎,避免自动重复发起请求,以确保数据提交的准确性和安全性。
5.浏览器对请求地址的处理不同 GET请求地址会被浏览器主动缓存,而POST不会,除非手动设置
6.浏览器对响应的处理不同GET请求参数会被完整的保留在浏览器历史记录里,而POST中的参数不会被保留
var和let\const
ES6之前创建变量用的是var,之后创建变量用的是let/const
var 存在变量提升,且可以重复定义(不会报错
),而const和let不存在变量提升;
let 不能重复定义(因为它申明的变量是块级作用域的)
; 允许值的修改;
const 不能重复定义 ; 不允许值的修改;
box-sizing
box-sizing
属性确实有三个可能的属性值,它们分别是:
content-box
:默认值,元素的宽度和高度仅包括内容框(content box),不包括padding
和border
。padding-box
:这个值在一些旧的草案中出现过,但在最终的 CSS 规范中被移除了,因此实际上并不在标准中使用。border-box
:元素的宽度和高度包括内容框(content box)、padding
和border
的尺寸。
WebStock
javascript
// 创建 WebSocket 连接
const socket = new WebSocket('wss://echo.websocket.org');
// 连接建立时的回调函数
socket.onopen = function (event) {
console.log('WebSocket 连接已建立');
// 发送消息给服务器
socket.send('Hello, Server!');
};
// 接收到消息时的回调函数
socket.onmessage = function (event) {
console.log('收到服务器消息:', event.data);
};
// 连接关闭时的回调函数
socket.onclose = function (event) {
console.log('WebSocket 连接已关闭');
};
// 发生错误时的回调函数
socket.onerror = function (error) {
console.error('WebSocket 出现错误:', error);
};
实现原理: 实现了客户端与服务端的双向通信,只需要连接一次,就可以相互传输数据,很适合实时通讯、数据实时更新等场景。
Websocket 协议与 HTTP 协议没有关系 ,它是一个建立在 TCP 协议上的全新协议,为了兼容 HTTP 握手规范,在握手阶段依然使用 HTTP 协议,握手完成之后,数据通过 TCP 通道进行传输。
Websoket 数据传输是通过 frame 形式,一个消息可以分成几个片段传输。这样大数据可以分成一些小片段进行传输,不用考虑由于数据量大导致标志位不够的情况。也可以边生成数据边传递消息,提高传输效率。
优点
: 双向通信。客户端和服务端双方 都可以主动发起通讯。 没有同源限制。客户端可以与任意服务端通信,不存在跨域问题。 数据量轻。第一次连接时需要携带请求头,后面数据通信都不需要带请求头,减少了请求头的负荷。 传输效率高。因为只需要一次连接,所以数据传输效率高。
缺点
: 长连接需要后端处理业务的代码更稳定,推送消息相对复杂; 兼容性,WebSocket 只支持 IE10 及其以上版本。 服务器长期维护长连接需要一定的成本,各个浏览器支持程度不一; 【需要后端代码稳定,受网络限制大,兼容性差,维护成本高,生态圈小】
作者:LeetCode 链接:leetcode.cn/leetbook/re... 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
BFC
overflow: hidden;的使用,当我们使用float浮动时,会影响后面的布局,给父元素加该属性即可。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BFC Example</title>
<style>
.container {
/* overflow: hidden; */
/* 创建 BFC */
}
.box {
margin: 20px;
background-color: lightblue;
}
</style>
</head>
<body>
<div class="container">
<div class="box">Box 1</div>
</div>
<div class="box">Box 2</div>
</body>
</html>
以上代码是防止外边距合并的案例,在代码中如果一个父元素div里的子元素div需要和父元素一样等级的div一起做操作,子元素div的外边距下和另一个div的外边距上会合并。 这是和可使用overflow:hidden来解决。
clear: both;
是一个用于清除浮动元素的 CSS 属性。当子元素设置了浮动(例如 float: left;
或 float: right;
)时,父元素的高度可能无法正确被撑开,导致布局混乱。在这种情况下,可以使用 clear: both;
来清除浮动,并确保父元素能够正确地包裹其内部的浮动子元素
要创建一个BFC(块格式化上下文),可以通过以下几种方式来实现:
-
使用
overflow
属性:将容器元素的overflow
属性设置为除visible
以外的值(如auto
、hidden
、scroll
),即可创建一个新的 BFC。 -
使用
float
属性:浮动元素会创建一个 BFC。在父容器中设置浮动元素,也会导致该父容器成为一个 BFC。 -
使用
display: inline-block
:将元素的display
属性设置为inline-block
也会创建一个 BFC。 -
使用绝对定位:如果一个元素的
position
属性被设置为absolute
或fixed
,它也会创建一个 BFC。
数据类型判断 instanceof 和 typeof 的区别
1.typeof
优点:能够快速区分基本数据类型
缺点:不能将Object、Array和Null区分,都返回object
2.instanceof
优点:能够区分Array、Object和Function,适合用于判断自定义的类实例对象
缺点:Number,Boolean,String基本数据类型不能判断
3.Object.prototype.toString.call()
javascript
var toString = Object.prototype.toString;
console.log(toString.call(1)); //[object Number]
console.log(toString.call(true)); //[object Boolean]
console.log(toString.call('mc')); //[object String]
console.log(toString.call([])); //[object Array]
console.log(toString.call({})); //[object Object]
console.log(toString.call(function(){})); //[object Function]
console.log(toString.call(undefined)); //[object Undefined]
console.log(toString.call(null)); //[object Null]
优点:精准判断数据类型
缺点:写法繁琐不容易记,推荐进行封装后使用
隐藏页面元素的方法
1.opacity:0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定 一些事件,如click 事件,那么点击该区域,也能触发点击事件的
2.visibility:hidden,该元素隐藏起来了,但不会改变页面布局,但是不会触发该元素已 经绑定的事件 ,隐藏对应元素,在文档布局中仍保留原来的空间(重绘)
3.display:none,把元素隐藏起来,并且会改变页面布局,可以理解成在页面中把该元素。 不显示对应的元素,在文档布局中不再分配空间(回流+重绘)
**回流(reflow)** :指的是当页面的布局发生变化,需要重新计算元素的位置和大小,然后重新绘制整个页面的过程。当隐藏一个元素(比如使用 display: none;)导致布局发生变化时,就会触发回流。
- **重绘(repaint)** :指的是当页面的外观发生变化,但不影响布局时,浏览器只需要重新绘制受影响的部分而不需要重新计算元素的位置和大小。隐藏一个元素(比如修改颜色、背景等)通常会引起重绘。
回流和重绘是浏览器渲染页面时的重要概念,虽然它们可能不直接影响到页面的显示,但是在性能优化方面却非常重要。当页面中的元素频繁地触发回流和重绘时,会导致页面性能下降,出现卡顿等问题。
DNS协议是什么
mp.weixin.qq.com/s?__biz=Mzg...
深拷贝和浅拷贝的区别
浅拷贝: 如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址。即浅拷贝是拷贝一层,深层次的引用类型则共享内存地址
Object.assign
ini
// 创建一个原始对象
const originalObject = { a: 1, b: 2 };
// 使用 Object.assign 进行浅拷贝
const shallowCopy = Object.assign({}, originalObject);
// 修改浅拷贝后的对象,不会影响原始对象
shallowCopy.a = 3;
console.log(originalObject); // 输出: { a: 1, b: 2 }
console.log(shallowCopy); // 输出: { a: 3, b: 2 }
Array.prototype.slice()
ini
// 创建一个原始数组
const originalArray = [1, 2, 3, 4, 5];
// 使用 slice 进行浅拷贝
const shallowCopy = originalArray.slice();
// 修改浅拷贝后的数组,不会影响原始数组
shallowCopy[0] = 6;
console.log(originalArray); // 输出: [1, 2, 3, 4, 5]
console.log(shallowCopy); // 输出: [6, 2, 3, 4, 5]
Array.prototype.concat()
ini
// 创建一个原始数组
const originalArray = [1, 2, 3, 4, 5];
// 使用 concat 进行浅拷贝
const shallowCopy = originalArray.concat();
// 修改浅拷贝后的数组,不会影响原始数组
shallowCopy[0] = 6;
console.log(originalArray); // 输出: [1, 2, 3, 4, 5]
console.log(shallowCopy); // 输出: [6, 2, 3, 4, 5]
使用拓展运算符实现的复制 const shallowCopy = { ...originalObject };
深拷贝: 深拷贝开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性
常见的深拷贝方式有:
_.cloneDeep()
ini
// 引入 lodash 库
const _ = require('lodash');
// 创建一个原始对象
const originalObject = { a: 1, b: { c: 2 } };
// 使用 _.cloneDeep() 进行深拷贝
const deepCopy = _.cloneDeep(originalObject);
// 修改深拷贝后的对象,不会影响原始对象
deepCopy.b.c = 3;
console.log(originalObject); // 输出: { a: 1, b: { c: 2 } }
console.log(deepCopy); // 输出: { a: 1, b: { c: 3 } }
jQuery.extend()
javascript
// 引入 jQuery 库
const $ = require('jquery');
// 创建一个原始对象
const originalObject = { a: 1, b: { c: 2 } };
// 使用 jQuery.extend() 进行深拷贝
const deepCopy = $.extend(true, {}, originalObject);
// 修改深拷贝后的对象,不会影响原始对象
deepCopy.b.c = 3;
console.log(originalObject); // 输出: { a: 1, b: { c: 2 } }
console.log(deepCopy); // 输出: { a: 1, b: { c: 3 } }
JSON.stringify()
css
// 创建一个原始对象
const originalObject = { a: 1, b: { c: 2 } };
// 使用 JSON.stringify() 和 JSON.parse() 实现深拷贝
const deepCopy = JSON.parse(JSON.stringify(originalObject));
// 修改深拷贝后的对象,不会影响原始对象
deepCopy.b.c = 3;
console.log(originalObject); // 输出: { a: 1, b: { c: 2 } }
console.log(deepCopy); // 输出: { a: 1, b: { c: 3 } }
手写循环递归
Flex 布局
Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。指定容器 display: flex 即可。 简单的分为容器属性和元素属性。
容器的属性:
flex-direction:决定主轴的方向(即子 item 的排列方法)flex-direction: row | row-reverse | column | column-reverse;
flex-wrap:决定换行规则 flex-wrap: nowrap | wrap | wrap-reverse;
flex-flow: .box { flex-flow: || ; }
justify-content:对其方式,水平主轴对齐方式
align-items:对齐方式,竖直轴线方向
align-content
项目的属性(元素的属性):
order 属性:定义项目的排列顺序,顺序越小,排列越靠前,默认为 0
flex-grow 属性:定义项目的放大比例,即使存在空间,也不会放大
flex-shrink 属性:定义了项目的缩小比例,当空间不足的情况下会等比例的缩小,如果 定义个 item 的 flow-shrink 为 0,则为不缩小
flex-basis 属性:定义了在分配多余的空间,项目占据的空间。
flex:是 flex-grow 和 flex-shrink、flex-basis 的简写,默认值为 0 1 auto。
align-self:允许单个项目与其他项目不一样的对齐方式,可以覆盖
align-items,默认属 性为 auto,表示继承父元素的 align-items 比如说,用 flex 实现圣杯布局
闭包
关于这块还是不太懂,刷课.
scss
function createCounter() {
let count = 0;
function increment() {
count++;
console.log("当前计数值:", count);
}
return increment;
}
// 创建一个计数器
const counter = createCounter();
// 每次调用 counter 函数,计数器值会增加
counter(); // 输出: 当前计数值: 1
counter(); // 输出: 当前计数值: 2
counter(); // 输出: 当前计数值: 3
Rem布局
Rem是相对于html的font-size大小来计算的,如果font-size:10px;那么1rem=10px; 优点:可以快速使用鱼移动端布局,字体,图片高度. 缺点: ①目前 ie 不支持,对 pc 页面来讲使用次数不多;
②数据量大:所有的图片,盒子都需要我们去给一个准确的值;才能保证不同机型的适配;
③在响应式布局中,必须通过 js 来动态控制根元素 font-size 的大小。也就是说 css 样式和 js 代码有一定的耦合性。且必须将改变 font-size 的代码放在 css 样式之前。
知识扩展:媒体查询
浏览器如何渲染UI的
1.解析html 2.解析css 3.合并两者 4.布局 5.绘制:根据计算出的位置和大小绘制 6.触发交互
DOM树的构建过程:
当浏览器接收到二进制数据后,首先会按照指定的编码格式将其转化为HTML字符串。然后,浏览器开始解析这个HTML字符串,将其转换成一系列的标记(Tokens)。接下来,浏览器会根据这些标记构建出相应的节点(Nodes),并为每个节点添加特定的属性,同时通过指针确定节点之间的父子关系、兄弟关系以及所属的树形结构(treeScope)。最终,通过这些节点之间的指针关系,浏览器构建出完整的DOM树。
重绘和回流
回流:
有些人也会把回流称为重排.
1、布局引擎会根据各种样式计算每个盒子在页面上的大小与位置。
2、改变元素的位置和尺寸大小都会引发回流
重绘(Repaint): 当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。表现为某些元素的外观被改变。
注意: **回流一定会引起重绘,但重绘不一定会引起回流.**
如何避免重排和重绘 1.提升为合成层 will-change: transform;
2.集中改变样式
,不要一条一条地修改 DOM 的样式。
- 不要把 DOM 结点的属性值放在循环里当成循环里的变量。
- 尽量只修改
position:absolute
或fixed
元素,对其他元素影响不大(absolute和fixed将元素移出文档流,使其成为一个独立的图层,如果需要重排重绘也不会影响到后面元素的位置变化)
百分比布局的优缺点
优点:
- 响应式布局设计
- 灵活性
- 相对定位:百分比可以实现相对定位,是的元素的位置相对余父元素进行调整
缺点: 复杂性:在处理多层嵌套布局时,非常复杂. 限制:百分比布局幼时会受到父元素尺寸的限制 性能:相对鱼固定像素值而言,百分比布局对性能有一定影响,浏览器需要在调整窗口大小时重新渲染页面.
空元素:br hr img input link meta
当你的子元素中使用了浮动,记得用<div style="clear: both;"></div>清楚,如果不写后期可能会导致高度塌陷问题,建议都写上.
当元素浮动了起来之后,它有着块级元素的一些性质例如可以设置宽高等
当元素浮动时,它会脱离常规文档流并且不再占据原本的空间,这就是所谓的"脱标"(out of flow)。父级元素没有包含浮动元素,因此在正常情况下,父级元素的高度会根据其内容的高度来自动调整,但是因为浮动元素脱离了文档流,父级元素无法正确计算其高度,导致父级元素出现高度塌陷的情况。
高度塌陷的表现通常是父级元素无法正确包裹内部的浮动元素,使得父级元素的高度变为0或者很小。这样可能会导致页面布局混乱,影响设计和排版效果。
为了避免高度塌陷问题,可以使用清除浮动的方法,其中包括添加一个空的 div
元素,并设置 clear: both;
样式来清除浮动效果。这样可以确保父级元素正确包裹内部的浮动元素,保持布局的稳定性
cookie和sessionStorage和localStorage的关系
相同点:
存储在客户端
不同点:
cookie数据大小不能超过4k;sessionStorage和localStorage的存储比cookie大得多,可以达到5M+
cookie设置的过期时间之前一直有效;localStorage永久存储,浏览器关闭后数据不丢失除非主动删除数据;sessionStorage数据在当前浏览器窗口关闭后自动删除
cookie的数据会自动的传递到服务器;sessionStorage和localStorage数据保存在本地
重点理解:
当在浏览器中打开一个新的标签页时,新的标签页会复制父级标签页的 sessionStorage
数据,类似于进行了一次深拷贝操作。这意味着新标签页会获取到与父级标签页相同的 sessionStorage
数据副本,但之后它们之间的 sessionStorage
数据就不再同步了。换句话说,在这种情况下,如果你在其中一个标签页中修改了 sessionStorage
的数据,这些修改不会自动同步到其他标签页。
另外,即使是打开多个拥有相同 URL 的标签页,它们之间的 sessionStorage
也不会同步,因为它们并不属于同一个会话(session)。每个标签页都会维护自己独立的 sessionStorage
数据,互相之间不会共享数据。这种设计可以确保在不同标签页之间能够保持数据的隔离性和独立性。
给我背下来:
*生命周期不同:cookie:可以设置失效时间;如果没有设置失效时间,浏览器关闭后数据会失效;localStorage:数据会永久保存,除非手动清除;sessionStorage:会话当前数据有效就是在浏览器窗口关闭之前有效,浏览器关闭后数据会被清除
体积大小:cookie:传递少量数据,4KB左右。每次http请求都会携带cookie,所以适合存储很小的数据。localStorage、sessionStorage:保存大量数据,5MB左右
http请求不同:cookie:每次http请求都会携带cookie,请求过多保存过多的数据会带来性能问题,web Storage(localStorage和sessionStorage):只在客户端保存,不参与服务器的交互。*
js获取DOM元素的几种方法
dart
1、根据id获取元素
document.getElementById("id属性的值")
2、根据标签名字获取元素
document.getElementsByTagName("标签的名字");
3、根据name属性的值获取元素
document.getElementsByName("name属性的值");
4、根据类样式的名字获取元素
document.getElementsByClassName("类样式的名字");
5、根据选择器获取元素
document.querySelector("选择器");
它会返回与指定 CSS 选择器匹配的文档中第一个元素,如果没有匹配的元素,则返回 `null`
document.querySelectorAll("选择器");
它会返回一个 `NodeList` 对象,其中包含了文档中所有与指定 CSS 选择器匹配的元素列表。
WEB攻击(背下来)
XSS(跨站脚本攻击)是一种代码注入攻击。攻击者在目标网站上注入恶意代码,当用户登陆网站时就会执行这些恶意代码,这些脚本可以读取 cookie,session tokens,或者其它敏感的网站信息
CSRF(跨站请求伪造:攻击者诱导用户进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用用户在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。
Sql 注入攻击,是通过将恶意的 Sql查询或添加语句插入到应用的输入参数中,再在后台 Sql服务器上解析执行进行的攻击
XSS避免方式:
1、url参数使用encodeURIComponent方法转义
2、尽量不是有InnerHtml插入HTML内容
3、使用特殊符号、标签转义符。
CSRF避免方式:
1、添加验证码
2、使用token
服务端给用户生成一个token,加密后传递给用户 用户在提交请求时,需要携带这个token 服务端验证token是否正确 DDoS又叫分布式拒绝服务,其原理就是利用大量的请求造成资源过载,导致服务不可用。
DDos 避免方式:
1、限制单IP请求频率。
2、防火墙等防护设置禁止ICMP包等
3、检查特权端口的开放
输入URL回车后发生了什么?(背下来)
1 面试套话: "检查缓存、先解析URL、然后DNS域名解析、再发起HTTP请求建立TCP连接、服务端响应返回页面资源进行渲染、然后断开TCP连接"
2 详细过程: 1、(找)DNS解析 -> 寻找哪台机器上有你需要资源 根据网址找IP
2、TCP连接 -> 客户端和服务器,TCP作为其传输层协议
3、发送HTTP请求 -> HTTP报文是包裹在TCP报文中发送的 请求行,请求报头,请求正文
4、服务器处理请求并返回HTTP报文 -> 状态码,响应报头和响应报文。
5、浏览器解析渲染页面 -> 浏览器在收到HTML,CSS,JS文件后依次渲染
6、连接结束 -> 断开TCP连接 四次挥手
html中dom 的event事件(背下来)
- onblur:失去焦点
- onfocus:元素获得焦点。
- 加载事件:
- onload:一张页面或一幅图像完成加载。
-
- 鼠标事件:
- onmousedown 鼠标按钮被按下。
- onmouseup 鼠标按键被松开。
- onmousemove 鼠标被移动。
- onmouseover 鼠标移到某元素之上。
- onmouseout 鼠标从某元素移开。
-
- 键盘事件:
- onkeydown 某个键盘按键被按下。
- onkeyup 某个键盘按键被松开。
- onkeypress 某个键盘按键被按下并松开。
-
- 选择和改变
- onchange 域的内容被改变。
- onselect 文本被选中。
-
- 表单事件:
- onsubmit 确认按钮被点击。
- onreset 重置按钮被点击。
清除浮动的几个方式
1.给父元素末尾添加一个空元素,并设置成清除浮动,即:
优点:通俗易懂,易于掌握
缺点:添加了无意义标签,不易于后期维护,违背了结构和表现分离的标准
2.给父元素添加 overflow:auto;
3.让父元素也浮动
缺点:影响整体页面布局,若父元素也有父元素呢?总不能一直浮动到body吧?
4.使用after伪元素
css
.clearfix::after {
content: "";
display: table;
clear: both;
}
- 在伪元素中,使用
content: "";
可以确保伪元素有内容可以插入,即使是空内容。这是因为伪元素默认是没有内容的,如果不指定content
属性,伪元素是不会显示的。 - 添加
display: table;
主要是为了解决一些浏览器对空内容的伪元素可能不渲染的问题。将display
设置为table
或其他类似值,可以强制让伪元素生成一个框,确保它在页面上占据空间。
给父元素添加一个类,来添加一个看不见的块元素,以实现清除浮动。
5.最优解
首先我们说一个CSS的概念------BFC块级格式上下文,简单来说就是只要样式或方法触发了BFC就可以防止高度塌陷.
AJAXX原理
异步的javaScript和XML,可以在不重新加载整个页面的情况下,与服务器交换数据,并更新部分网页.
- 创建 XMLHttpRequest 对象:这是Ajax的核心对象,用于在后台与服务器交换数据而不必重新加载整个页面。
- 通过 XMLHttpRequest 的 open() 方法建立与服务器的连接,并指定请求的类型(GET、POST等)和URL。
- 构建请求所需的数据内容,可以是参数或者请求体。然后使用 XMLHttpRequest 的 send() 方法将请求发送给服务器。
- 监听 XMLHttpRequest 的 onreadystatechange 事件,以便在通信状态发生改变时进行处理。通常会检查 readyState 和 status 属性来确定请求的状态。
- 当 readyState 为 4 且 status 为 200 时,表示请求成功,可以从 XMLHttpRequest 对象的 responseText 或 responseXML 属性中获取服务器返回的数据结果。
- 使用获取到的数据结果,通过JavaScript操作DOM来更新页面的特定部分。
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ajax Example</title>
<script>
// 创建一个新的 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
// 当 readyState 改变时执行的函数
xhr.onreadystatechange = function () {
// 确保请求已完成,并且响应状态为 200(即成功)
if (xhr.readyState === 4 && xhr.status === 200) {
// 获取响应数据
var response = xhr.responseText;
// 将响应数据显示在 id 为 "output" 的元素中
document.getElementById("output").innerHTML = response;
}
};
// 打开一个新的 GET 请求
xhr.open("GET", "https://jsonplaceholder.typicode.com/posts/1", true);
// 发送请求
xhr.send();
</script>
</head>
<body>
<!-- 用于显示响应数据的 div 元素 -->
<div id="output">Loading...</div>
</body>
</html>
JS中this的情况
- 普通函数调用:通过函数名调用,this指向window(注意let定义的变量不是window属性,即let a="aa";this.a是undefined)
csharp
// 普通函数调用
let a = 'aaa';
function regularFunction() {
// console.log(this.a); // 输出:undefined
// console.log(a);
}
regularFunction();
- 构造函数调用:用new关键字调用:this指向new出来的对象
//
function ConstructorFunction() {
this.b = 'bbb';
console.log(this.b);
}
let obj = new ConstructorFunction(); // 输出:'bbb'
// 当构造函数new之后,里面的this指向新对象,此时你在外部使用this.b是undefind,要使用obj.b
- 对象函数调用:一个对象里面有函数,this指向该对象
javascript
// 对象函数调用
let obj2 = {
c: 'ccc',
objectFunction: function () {
console.log(this.c); // 输出:'ccc'
}
};
obj2.objectFunction();
- 箭头函数调用:箭头函数没有this
javascript
// 箭头函数调用
let arrowFunction = () => {
console.log(this.a); // 输出:'aaa'
};
arrowFunction();
- apply和call调用:函数体内的this指向方法的第一个参数,若是空默认是全局对象window
//
function applyAndCallFunction() {
console.log(this.x);
}
let context = { x: 'context' };
applyAndCallFunction.call(context); // 输出:'context'
applyAndCallFunction.apply(context); // 输出:'context'
- 函数作为数组的一个元素:this指向该数组
javascript
// 函数作为数组的一个元素调用
let array = [1, 2, function () {
console.log(this);
}];
array[2](); // 输出:[1, 2, [Function]]
- 函数做为window内置函数的回调函数调用时,this指向window
javascript
// 内置函数回调函数调用
function intervalCallback() {
console.log(this); // 打印当前的 this 值
}
// 使用 setInterval 调用 intervalCallback 函数,时间间隔为 1000 毫秒
// 在这种情况下,intervalCallback 函数被作为全局函数调用,因此 this 指向全局对象 Window
setInterval(intervalCallback, 1000); // 输出:Window
// 使用 setTimeout 调用一个匿名函数,时间间隔为 1000 毫秒
// 匿名函数中的 this 也指向全局对象 Window,因为在该情况下 this 会默认指向全局对象
setTimeout(function () {
console.log(this); // 打印当前的 this 值
}, 1000); // 输出:Window
箭头函数是 ES6 新增的一种函数定义方式。在这个箭头函数中,只有一行代码用来打印 this.a
的值。箭头函数没有自己的 this
,它会捕获所在上下文的 this
值,因此在这个箭头函数中,this
将指向上一层作用域的 this
什么是CSS预处理器?
CSS预处理器是一种语言用来为CSS增加一些变成的特性,无需考虑浏览器兼容问题,例如你可以在CSS中使用变量,简单的程序逻辑、函数等在编程语言中的一些基本技巧,可以让CSS更加简洁,适应性更强,代码更直观等诸多好处
Sass、Less 和 Stylus 都是流行的 CSS 预处理器,它们在书写样式表时提供了一些便利和功能,使得 CSS 更易于维护和扩展。
基本语法区别
Sass是以.sass为扩展名,Less是以.less为扩展名,Stylus是以.styl为扩展名
变量的区别
Sass 变量必须是以 <math xmlns="http://www.w3.org/1998/Math/MathML"> 开头的,然后变量和值之间使用冒号(:)隔开,和 c s s 属性是一样的。 L e s s 变量是以 @ 开头的,其余 s a s s 都是一样的。 S t y l u s 对变量是没有任何设定的,可以是以 开头的,然后变量和值之间使用冒号(:)隔开,和css属性是一样的。 Less 变量是以@开头的,其余sass都是一样的。 Stylus 对变量是没有任何设定的,可以是以 </math>开头的,然后变量和值之间使用冒号(:)隔开,和css属性是一样的。Less变量是以@开头的,其余sass都是一样的。Stylus对变量是没有任何设定的,可以是以开头或者任意字符,而且变量之间可以冒号,空格隔开,但是在stylus中不能用@开头 Sass
less
// 定义变量
$primary-color: #333;
// 定义 Mixin
@mixin center {
display: flex;
justify-content: center;
align-items: center;
}
// 使用 Mixin
.container {
@include center;
background-color: $primary-color;
}
Less
//
@primary-color: #333;
// 定义 Mixin
.center() {
display: flex;
justify-content: center;
align-items: center;
}
// 使用 Mixin
.container {
.center;
background-color: @primary-color;
}
Stylus
scss
// 定义变量
primary-color = #333
// 定义 Mixin
center()
display: flex
justify-content: center
align-items: center
// 使用 Mixin
.container
center()
background-color primary-color
前端性能优化(背)
1、减少http请求数;2、图片优化;3、使用CDN;4、开启GZIP;5、构建优化;
- 减少http请求数
1)合并图片。当图片较多时,可以合并为一张大图,从而减少http请求数。
2)合并压缩css样式表和js脚本。
一般我们会把css样式表文件放到文件的头部。比如,放到标签中,这样可以让CSS样式表尽早地完成下载。对应js脚本文件,一般我们把他放到页面的尾部。
3)充分利用缓存。
- 图片优化
1)尽可能的使用PNG格式的图片,它相对来说体积较小。
2)图片的延迟加载,也叫做懒加载。
- 使用CDN
CDN即内容分发网络,可以使用户就近取得所需内容,解决网络拥挤的状况,提高用户访问网站的响应速度。
- 开启GZIP
GZIP即数据压缩,用于压缩使用Internet传输的所有文本资源。开启GZIP的方法很简单,到对应的web服务配置文件中设置一下即可。以Apache为例,在配置文件httpd.conf中添加。
- 构建优化
使用 Tree-shaking、Scope hoisting、Code-splitting
Tree-shaking是一种在构建过程中清除无用代码的技术。使用Tree-shaking可以减少构建后文件的体积。
call和apply以及bind三者的区别
相同点:
- 都是改变this指向的
- 第一个参数都是this的指向对象
- 都可以用来后续传参
不同点:
- call和bind的依次传参,apply的第二个参数为数组
- call和apply都是对函数直接调用,而bind方法返回一个仍是函数,我们需要调用该函数.
javascript
const obj = {
name: 'Alice',
greet: function() {
console.log(`Hello, ${this.name}!`);
}
};
const anotherObj = {
name: 'Bob'
};
// 使用 bind 方法将 obj.greet 函数的 this 指向 anotherObj
const boundGreet = obj.greet.bind(anotherObj);
// 调用 boundGreet,此时函数内部的 this 指向了 anotherObj
boundGreet(); // 输出:Hello, Bob!
元素水平居中
仅居中元素定宽高适用
absolute + 负margin
absolute + margin auto
absolute + calc
居中元素不定宽高
absolute + transform
lineheight
writing-mode
table
css-table
flex
grid
PC端有兼容性要求,宽高固定,推荐absolute + 负margin
PC端有兼容要求,宽高不固定,推荐css-table
PC端无兼容性要求,推荐flex
移动端推荐使用flex
如何理解CDN?实现原理?(背)
内容分发网络:
CDN(内容分发网络)是一种通过位于世界各地的服务器来加速互联网内容传输的技术架构。它通过将内容缓存在离用户更近的位置,以降低用户对原始服务器的访问次数,从而提高内容的传输速度和性能
当你使用 CDN(内容分发网络)时,通常会将你的域名指向 CDN 提供的服务器,以便加速内容的传输和提高网站性能。在这种情况下,DNS 解析的结果可能不再是直接的 IP 地址,而是一个 CNAME 记录,它是 Canonical Name 的缩写
伪类和伪元素的区别
伪类(pseudo-class)和伪元素(pseudo-element)是 CSS 中常用的概念,它们用于向选择器添加特殊的效果或样式,但在功能和用法上有一些区别
伪元素案例:
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pseudo-element Example</title>
<style>
.button::before {
content: "Click me!";
/* 添加要显示的内容 */
background-color: #3498db;
/* 背景颜色 */
color: white;
/* 文字颜色 */
padding: 5px 10px;
/* 内边距 */
border-radius: 3px;
/* 边框圆角 */
margin-right: 10px;
/* 右侧间距 */
}
.button {
display: inline-block;
background-color: #2ecc71;
color: white;
padding: 10px 20px;
text-decoration: none;
border-radius: 5px;
}
</style>
</head>
<body>
<a href="#" class="button">Button</a>
</body>
</html>
-
伪类是用于向选择器指定特殊状态的关键词,如
:hover
、:active
、:first-child
等。 -
伪元素是用于向选择器添加生成的内容的关键词,如
::before
、::after
、::first-line
等。伪元素表示的是元素的特定部分或位置,允许开发者在指定元素的前后、内部的第一行等位置插入虚拟的元素。
总结: 伪类是以冒号作为前缀,被添加到了一个选择器末尾的关键字,当你希望在特定状态才被呈现到指定的元素时,你可以添加伪类.
伪元素用于创建一些不再文档书中的元素,并为其添加样式,虽然用户可以看见文本,但文本不在文档树中.
区别:他们是否创建了新元素
- 伪类是通过元素选择器加入伪类改变元素状态
- 伪元素通过元素的操作进行元素的改变
跨越(还没练习)
跨域访问的限制并不是浏览器限制发送请求,而是浏览器阻止了请求后数据的加载渲染
一、定义:
跨域:是由浏览器的同源策略造成的。 同源策略,是浏览器对 JavaScript 实施的安全限制,只要协议、域名、端口有任何一个不同,都被当作是不同的域。 跨域原理,即是通过各种方式,避开浏览器的安全限制。
解决方案:
1.最初做项目的时候,使用的是 jsonp(一种利用 JSON 格式进行跨域数据传输的解决方案),但存在一些问题,使用 get 请求不安全,携带数据较小
ajax 请求受同源策略影响,不允许进行跨域请求,而 script 标签 src 属性
中的链接却可以访问跨域的 js 脚本,利用这个特性,服务端不再返回 JSON 格式的数据,而是 返回一段调用某个函数的 js 代码,在 src 中进行了调用,这样实现了跨域。 步骤:
- ① 去创建一个 script
- ② script 的 src 属性设置接口地址
- ③ 接口参数,必须要带一个自定义函数名,要不然后台无法返回数据
- ④ 通过定义函数名去接受返回的数据
javascript
//动态创建 script
var script = document.createElement('script');
// 设置回调函数
function getData(data) {
console.log(data);
}
//设置 script 的 src 属性,并设置请求地址
script.src = 'http://localhost:3000/?callback=getData';
// 让 script 生效
document.body.appendChild(script);
- 缺点:
JSON 只支持 get,因为 script 标签只能使用 get 请求; JSONP 需要后端配合返回指定格式的数据。
- CORS(跨源资源共享)是一种机制,允许网页应用从不同的源(域、协议或端口)请求资源。当浏览器发起跨域请求时,目标服务器需要设置适当的响应头来指示浏览器该请求是被允许的。
具体来说,服务器通过在 HTTP 响应头中设置 Access-Control-Allow-Origin
来允许特定源的请求访问资源。例如,如果服务器设置了 Access-Control-Allow-Origin: https://example.com
,那么来自 https://example.com
的请求就会被允许访问该资源。
简而言之,CORS 允许服务器在响应中告诉浏览器哪些源是被允许访问资源的,从而确保安全地进行跨域请求。这个机制有助于防止恶意网站对其他网站的资源进行未经授权的访问。
3.最方便的跨域方案 proxy代理+ Nginx
方法有很多,遇到的时候再去一一尝试即可.
Event Loop 的执行顺序
常见宏任务:setTimeout setInterval setImmediate i/o script UI rendering 常见微任务:Promise MutationObserver Node.js:process.nextTick
- 检查微任务队列:首先,Event Loop 会检查微任务队列。如果微任务队列中有任务,Event Loop 会顺序执行所有微任务,直到微任务队列为空。
- 执行一个宏任务:如果微任务队列为空,Event Loop 会从宏任务队列中选择一个任务来执行。通常情况下,会选择最先进入宏任务队列的任务进行执行。
- 更新渲染:在浏览器环境中,当执行完一个宏任务后,浏览器会根据需要对页面进行重新渲染,以确保用户界面的响应性。
- 等待新任务:执行完一个宏任务后,Event Loop 会再次检查微任务队列。如果有新的微任务加入,那么这些新的微任务会被立即执行。然后继续执行下一个宏任务,如此循环。
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pseudo-element Example</title>
</head>
<body>
<a href="#" class="button">Button</a>
</body>
<script>
console.log('Start');
setTimeout(() => {
console.log('Timeout 1');
Promise.resolve().then(() => console.log('Promise 1'));
}, 0);
Promise.resolve().then(() => {
console.log('Timeout 2');
setTimeout(() => console.log('Promise 2'), 0);
});
console.log('End');
</script>
</html>
输出结果: Start End Timeout 2 Timeout 1 Promise 1 Promise 2
渐进增强与优雅降级的理解及区别
-
渐进增强(Progressive Enhancement) :这种策略是从最基本的功能开始构建网页或应用,然后逐步添加更先进的功能和样式。首先确保基本内容和功能在所有设备和浏览器中都能正常展示和运行,然后针对支持更多特性的现代浏览器逐步增加交互和样式的改进。这种方式保证了所有用户都能访问到基本的内容和功能,而对于支持更多特性的设备则提供了更丰富的体验。
-
优雅降级(Graceful Degradation) :相比之下,优雅降级是先针对现代浏览器和设备构建功能丰富的网页或应用,然后再逐步向后兼容到旧版浏览器和设备。如果某些功能在旧版浏览器或设备中无法正常工作,系统会进行降级处理,以确保它们仍然能够正常使用。这种方式侧重于提供尽可能丰富的体验,但会在旧版设备上出现一定程度的功能降级。
区别:
- 渐进增强是从基本功能开始,逐步增加到更先进的功能,确保所有设备都有基本的可访问性,然后针对更先进的设备提供更丰富的体验。
- 优雅降级是先构建丰富的功能,然后向后兼容到旧版设备,以确保即使在旧版设备上也能提供较为完整的体验,但可能会有一定程度的功能降级。
总的来说,渐进增强注重从基础向上构建,而优雅降级注重从高级功能向下兼容。选择哪种策略取决于您的产品目标、受众群体和技术需求。
CSS hack(做了解)
CSS hack 是指在编写 CSS 时,根据不同的浏览器或特定条件来应用不同的 CSS 样式的技术。这些技术可以分为条件 hack、属性级 hack 和选择符级 hack。
-
条件 hack:条件 hack 是指根据不同浏览器或浏览器版本来引入不同的 CSS 样式表。通过使用条件注释或条件规则,可以针对特定的浏览器或浏览器版本加载不同的样式表。例如,针对 IE6 的样式可以使用如下条件注释:
xmlcssCopy Code <!--[if IE 6]> <link rel="stylesheet" type="text/css" href="ie6.css"> <![endif]-->
这样就可以在 IE6 下加载名为 "ie6.css" 的特定样式表。
-
属性级 hack:属性级 hack 是指根据不同浏览器支持的 CSS 属性来应用不同的样式。由于不同浏览器对一些 CSS 属性的支持情况不同,可以利用这一特点来针对特定浏览器应用不同的样式。例如,可以使用以下方式来应用只在 IE 浏览器下生效的样式:
csscssCopy Code .example { color: blue; /* 所有浏览器都支持的属性 */ *color: green; /* 只在 IE7 及以下生效的属性 */ _color: yellow; /* 只在 IE6 生效的属性 */ }
-
选择符级 hack:选择符级 hack 是根据不同浏览器的 CSS 选择符支持情况来应用不同的样式。通过使用特定的选择符或选择符组合,可以使得某些样式只在特定浏览器中生效。例如,可以使用如下选择符来应用只在 IE 浏览器下生效的样式:
csscssCopy Code .example { color: red; /* 所有浏览器都支持的属性 */ } * html .example { color: blue; /* 只在 IE6 生效的样式 */ }
需要注意的是,CSS hack 在实际应用中可能会导致代码的可读性和维护性变差,因此在可能的情况下,**建议尽量避免使用 hack,
**而是采用更现代化的 CSS 解决方案,比如使用特定浏览器的前缀或流行的 CSS 预处理器来处理浏览器兼容性问题。
浏览器私有属性
常用的前缀有:firefox浏览器 :-moz-, chrome、safari :-webkit-, IE浏览器 :-ms-(目前只有 IE 8+支持)
列举ES6的新特性
-
let和const
-
Promise
-
Class类
-
箭头函数
-
函数参数默认值
-
模板字符串
-
解构赋值--let [a, b] = [1, 2];
-
展开语法
构造数组,调用函数时,讲数组表达式或String在语法层里面展开
-
对象属性缩写
-
键名和键值相同
-
函数省略function
-
模块化
常见的兼容性问题
不同的浏览器默认的margin和padding不一样 IE6双边距bug:块属性标签float后,又有恒星的margin情况下,在Ie6显示margin比设置的大,将它转成行内块元素即可 设置较小高度标签(一般小于10px),zai IE6,IE7中高度超出最近设置高度,给超出高度的标签设置overflow:hidden; 或者设置行高 line-height 小于你设置的高度。 Chrome中文界面下默认会将小于12px的文本强制按照12px显示,可通过css属性 -webkit-text-size-adjust:none;解决 超链接访问过和hover样式就不出现了,被点击的超链接样式不再举有hover和active了,解决办法时改变css顺序的排列:LVHA ,a:link{} a:visited{} a:hover{} a:active{}
GC 垃圾回收机制(被阐述)
项目中,如果存在大量不被释放的内存(堆/栈/上下文),页面性能会变得很慢。造成内存泄漏。我们尽可能减少使用闭包,因为它会消耗内存。常见的内存泄露:全局变量、闭包、DOM 元素的引用、定时器。
Javascript 具有自动垃圾回收机制 (GC:Garbage Collecation),垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。
- 标记清除:当变量进入执行环境时,被标记为"进入环境",当变量离开执行环境时,会被标记为"离开环境"。垃圾回收器会销毁那些带标记的值并回收它们所占用的内存空间。
- 谷歌浏览器:"查找引用",浏览器不定时去查找当前内存的引用,如果没有被占用了,浏览器会回收它;如果被占用,就不能回收。
- IE 浏览器:"引用计数法",当前内存被占用一次,计数累加1次,移除占用就减1,减到0时,浏览器就回收它。
对比各种继承
原型链继承 -> 子类原型指向父类实例
javascript
function Parent() {}
function Child() {}
Child.prototype = new Parent()
const child = new Child()
好处:
子类可以访问到父类新增原型方法和属性 坏处:
无法实现多继承 创建实例不能传递参数
构造函数
javascript
function Parent() {}
function Child(...args) {
Parent.call(this, ...args) // Parent.apply(this, args)
}
const child = new Child(1)
好处:
可以实现多继承 创建实例可以传递参数
坏处:
实例并不是父类的实例,只是子类的实例 不能继承父类原型上的方法
组合继承
javascript
function Parent() {}
function Child(...args) {
Parent.call(this, ...args)
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child
const child = new Child(1)
好处:
- 属性和原型链上的方法都可以继承
- 创建实例可以传递参数
对象继承
javascript
// Object.create
const Parent = { property: 'value', method() {} }
const Child = Object.create(Parent)
// create
const Parent = { property: 'value', method() {} }
function create(obj) {
function F() {}
F.prototype = obj
return new F()
}
const child = create(Parent)
好处:
- 可以继承属性和方法
坏处:
- 创建实例无法传递参数
- 传入对象的属性有引用类型,所有类型都会共享相应的值
寄生组合继承(这个会看不会写)
javascript
function Parent() {}
function Child(...args) {
Parent.call(this, args)
}
function create(obj) {
function F() {}
F.prototype = obj
return F
}
function extend(Child, Parent) {
const clone = create(Parent.prototype)
clone.constructor = Child
Child.prototype = clone
}
extend(Child, Parent)
const child = new Child(1)
ES6继承
scala
class Parent {
constructor(property) {
this.property = property;
}
method() {
console.log('This is a method in the parent class');
}
}
class Child extends Parent {
constructor(property) {
super(property);
}
}
原型原型链
js是一种基于原型的语言,每一个函数对象都有自己的prototype属性,这个属性指向函数的原型对象。
原型关系: 每个class都有显示原型的prototype 每个实例都有隐式原型proto 实例的proto指向对应的class的prototype 这块听着有点绕绕的,多刷个视频
当试图访问一个对象的属性时,他不仅仅在该对象上搜索,还有找该对象的原型的原型,依次层层往上搜索,直到找到匹配的属性 或者到达原型链末尾。
作用域和作用域链
简单来说作用域就是函数和变量的可访问范围,全局作用域:代码在程序的任何地方都能被访问,window对象的内置对象属性都是拥有全局作用域。 函数作用域:在固定代码片段才能被访问的
好处:隔离变量,不同作用域下同名的变量不会有冲突
作用域链:就是查询的一个过程,一般情况下,变量到创建该变量的函数作用域中取值,如果当前作用域没有,就会向上级作用域查询。
注意: es6新增的let具有块级作用域,只能在当前的代码块就生效,如果想在局部作用域访问它,可利用作用域链。
javascript
javascriptCopy Code
let globalVar = 'I am a global variable';
function getGlobalVar() {
console.log(globalVar); // 在函数内部访问全局变量
}
父元素塌陷问题解决
什么是父元素塌陷 当一个父元素中包含N个浮动元素时,父元素未设置宽高,这时候内容浮动,则不会把父元素撑起来,导致了塌陷。 解决方法: 1.给父元素 overflow:hidden; 2.子元素末尾另外加一个div,添加样式clear:both; 3.给子元素添加伪类:
css
.clearfix::after {
content: "";
display: table;
clear: both;
}
4.让父元素也浮动(不建议)
影响页面布局,如果父元素也有父元素呢,总不能一直浮动到body吧
webpack中loader和plugin的区别(背)
- loader
- 在打包前或期间调用
- 根据不同匹配条件处理资源
- 调用顺序与书写顺序相反
- 写在前面的接收,写在后面的返回值作为输入值
- plugin
- 基于Tapable实现
- 事件触发调用,监听webpack广播的事件
- 不同生命周期改变输出结果
元素水平居中的几种方式?(背)
1.Flex布局
css
.parent {
display: flex;
justify-content: center;
}
给父元素加上即可。
2.Grid属性(好好看一下这个属性)
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>元素水平居中 - Grid</title>
<style>
.container {
display: grid;
place-items: center;
height: 100vh;
}
.centered {
background-color: lightblue;
padding: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="centered">这是要水平居中的内容</div>
</div>
</body>
</html>
3.margin :0 auto;
这使用需要注意,必须给出固定高度才会生效,width:100%是不行的.
4.text-align: center;
适用与行内元素居中
5.绝对定位和transform来实现
口令:父相子绝 absolute 绝对 relative 相对不要搞混
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>元素水平居中 - 绝对定位和 transform</title>
<style>
.parent {
position: relative;
width: 300px;
height: 200px;
background-color: lightgray;
}
.child {
position: absolute;
left: 50%;
transform: translateX(-50%);
background-color: lightblue;
padding: 20px;
}
</style>
</head>
<body>
<div class="parent">
<div class="child">这是要水平居中的内容</div>
</div>
</body>
</html>
还有一种写法是直接使用绝对定位和transform来达到水平居中效果的,两者有什么区别呢? 父相子绝是相对与父元素去发生变化的,父元素的大小或位置的变化会影响子元素的定位,这个方式更加灵活;而直接使用绝对定位absolute,子元素是不受父元素管控,absolute会脱离文档流
6.通过绝对定位和calc()动态计算数值函数
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.parent {
position: relative;
width: 300px;
height: 200px;
background-color: lightgray;
}
.child {
position: absolute;
width: 100px;
height: 50px;
background-color: lightblue;
top: calc(50% - 25px);
/* 50% - 子元素高度的一半 */
left: calc(50% - 50px);
/* 50% - 子元素宽度的一半 */
}
</style>
</head>
<body>
<div class="parent">
<div class="child"></div>
</div>
</body>
</html>
calc()
函数是CSS中用于动态计算数值的功能,可以在属性值中进行数学运算。在这个函数中,可以使用加法、减法、乘法和除法来计算属性值。 在你提到的例子中,calc(50% - 50px)
是一个通过 calc()
函数计算得到的属性值。让我们来解释一下这个表达式:
50%
表示父元素的高度或宽度的50%。-
是减法运算符。50px
表示一个固定的像素值,这里是50像素。
代码中的固定值为何选50px呢,因为我们的子元素宽度是100px
7. 使用table布局和center
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
* {
padding: 0;
margin: 0;
}
.container {
display: table;
width: 100%;
height: 300px;
text-align: center;
}
.content {
display: table-cell;
vertical-align: middle;
}
</style>
</head>
<body>
<div class="container">
<div class="content">
<p>居中内容</p>
</div>
</div>
</body>
</html>
扩展:
transform
是一个CSS属性,用于对元素进行变换,包括旋转、缩放、平移、倾斜等操作。
-
平移(Translate):
translateX(x)
:沿着X轴平移元素。translateY(y)
:沿着Y轴平移元素。translate(x, y)
:同时沿着X轴和Y轴平移元素。
-
旋转(Rotate):
rotate(angle)
:按照给定角度顺时针旋转元素。
css
cssCopy Code
.element {
transform: rotate(45deg); /* 顺时针旋转45度 */
}
-
缩放(Scale):
scaleX(x)
:沿X轴方向缩放元素。scaleY(y)
:沿Y轴方向缩放元素。scale(x, y)
:分别沿X轴和Y轴方向缩放元素。
css
cssCopy Code
.element {
transform: scaleX(1.5); /* 沿X轴方向放大1.5倍 */
}
-
倾斜(Skew):
skewX(angle)
:沿X轴方向倾斜元素。skewY(angle)
:沿Y轴方向倾斜元素。
css
cssCopy Code
.element {
transform: skewX(30deg); /* 沿X轴方向倾斜30度 */
}
-
组合变换(Multiple Transformations):
- 可以将多个变换组合在一起使用,通过空格隔开。
css
cssCopy Code
.element {
transform: rotate(45deg) scale(1.2);
}
如何自定义一个 webpack 插件 (背)
声明一个自定义命名的类或函数 在原型中新增 apply 方法 声明由 Compiler 模块暴露的生命周期函数 使用 webpack 提供的 API 或 自行处理内部实例的数据 处理完成后,调用 webpack 提供的回调函数
import和import()、require的区别
在 JavaScript 中,import
、import()
和 require
都是用于导入模块的方式,它们之间有一些区别。
import
:用于静态导入模块,必须在代码的顶部使用,并且不能在条件语句或函数内部使用。导入的模块会在编译时进行解析。
javascript
javascriptCopy Code
// 静态导入模块
import { someModule } from './someModule';
import()
:用于动态导入模块,可以在运行时根据条件来决定是否加载某个模块。返回一个 Promise 对象,可以使用then
方法获取导入的模块。
javascript
javascriptCopy Code
// 动态导入模块
import('./someModule').then((module) => {
// 使用导入的模块
});
require
:是 Node.js 中的模块加载方式,在浏览器端也可以使用一些 bundler 工具(如 webpack)来加载模块。和import()
类似,require
也支持动态加载模块,但是在浏览器端不建议直接使用require
。
ini
javascriptCopy Code
// 使用 require 加载模块(Node.js)
const someModule = require('./someModule');
为什么说require不建议在浏览器使用
- 兼容性:在浏览器环境中,原生的javascript斌不支持require语法,而是采用ESM模块的Import
- 浏览器环境限制:浏览器环境中没有内置的模块加载系统,直接使用require语法找不到模块位置
- 构建工具转换:为了在浏览器端使用require语法,通常需要使用构建工具webpack、Rollup将代码转换成浏览器可识别的形式,增加了复杂性并可能引入额外问题。
async/await中捕捉异常错误的方法
- 使用 try/catch 捕获异步函数中的错误:
javascript
javascriptCopy Code
async function myAsyncFunction() {
try {
const result = await someAsyncOperation();
// 异步操作成功时的处理
return result;
} catch (error) {
// 捕获异步操作中的错误,并进行处理
console.error('An error occurred:', error);
// 可以选择抛出错误或者做其他处理
throw error;
}
}
- 在调用 async 函数时使用 then 和 catch 方法处理结果和错误:
ini
javascriptCopy Code
myAsyncFunction().then(result => {
console.log('Async operation result:', result);
}).catch(error => {
console.error('An error occurred in async function call:', error);
// 可以选择抛出错误或者做其他处理
});
box-sizing:inherit
inherit
是 CSS 中的一个关键字,用于指定元素的属性值应该继承自其父元素的相同属性。在 box-sizing
属性中使用 inherit
值时,表示元素应该继承其父元素的 box-sizing
值。
待学习知识点
em/px/rem/vh/vw的区别?
viewport适配的原理