前端面试练习24.3.10

时间:2024-03-10 14:18:04

子元素里面绝对定位,设置宽高,能否撑起父元素

子元素使用绝对定位并设置宽度和高度时,通常情况下是不会撑起父元素的。这是因为绝对定位的元素脱离了文档流,不再影响其父元素的布局。

当子元素使用绝对定位时,它们的位置是相对于其最近的已定位的祖先元素(通常是第一个具有定位属性的祖先元素)来确定的,而不是相对于父元素。因此,即使子元素设置了宽度和高度,也不会对父元素的尺寸产生影响。

如果您希望子元素能够撑起父元素,您可以考虑使用其他布局方法,如相对定位、浮动、Flexbox 或 Grid 等。这些方法中,Flexbox 和 Grid 是比较现代和灵活的布局方式,可以轻松实现复杂的布局结构,并且能够很好地处理子元素的尺寸和位置。

 CSS怎么解析选择器

  1. 选择器分析:解析器首先会识别选择器中的各个部分,例如标签名、类、ID、属性选择器等等。选择器的各个部分通过不同的符号来分隔,比如空格、点、井号等。

  2. 选择器匹配:解析器根据选择器的规则来匹配文档中的元素。这个过程包括根据选择器中的标签名、类名、ID等来定位相应的HTML元素。

  3. 选择器组合:如果选择器包含多个选择器组合,解析器会根据这些组合来选择匹配的元素。例如,.class1.class2选择器会匹配同时具有class1class2类的元素。

  4. 选择器权重计算:如果有多个选择器都能匹配同一个HTML元素,解析器会根据CSS选择器的权重规则来确定应用哪个样式。通常情况下,ID选择器的权重最高,其次是类选择器,最后是标签选择器。

  5. 样式应用:解析器会将匹配的样式规则应用到相应的HTML元素上。

CSS的属性继承相关

  1. font:字体属性(例如font-familyfont-sizefont-style等)会被子元素继承。这意味着如果在父元素上设置了字体样式,子元素通常会继承这些样式。

  2. color:文字颜色属性会被子元素继承。如果在父元素上设置了文字颜色,子元素通常会继承这个颜色。

  3. line-height:行高属性也会被子元素继承。父元素的行高会被应用到子元素的文字中,除非子元素自己有设置行高。

  4. visibility:可见性属性(例如visibility)也可以被子元素继承。不可见的元素会导致其子元素也不可见。

  5. cursor:鼠标样式属性(例如cursor)通常会被子元素继承,但有些浏览器对此属性的继承行为有所不同。

  6. text-decoration:文本修饰属性(例如text-decoration)通常会被子元素继承。

但需要注意的是,并不是所有的CSS属性都会被继承。例如,背景属性(例如background-colorbackground-image)就不会被子元素继承。另外,一些浏览器特定的样式属性也可能不会继承。

可以通过CSS中的inherit关键字来明确指定某些属性的继承行为,比如font-family: inherit;将会继承父元素的字体设置。

V8解析执行JavaScript代码过程

  1. 词法分析(Lexical Analysis): JavaScript 代码首先被分解成词法单元,也称为标记(tokens),比如关键字、标识符、操作符等。这个过程会将源代码字符串分解成一个个有意义的标记,方便后续的语法分析。

  2. 语法分析(Syntax Analysis): V8 接着会将词法分析得到的标记按照 JavaScript 语法规则组合成语法树(Syntax Tree),也称为抽象语法树(Abstract Syntax Tree,AST)。这个树形结构反映了代码的层次结构和逻辑关系,方便后续的代码生成和执行。

  3. 解释与编译: 在解释与编译阶段,V8 会将 AST 转换成字节码(bytecode)或者直接编译成机器码(native code),这取决于 V8 的优化策略和执行环境。字节码可以通过解释器逐行执行,而机器码则可以直接在 CPU 上执行,速度更快。

  4. 优化与执行: V8 会进行一系列优化操作,例如内联缓存(inline caching)、热点代码优化(hot code optimization)和垃圾回收(garbage collection)。这些优化操作旨在提高 JavaScript 代码的执行性能和效率。

  5. 执行结果: 最后,V8 执行 JavaScript 代码,并生成相应的执行结果。这个结果可以是计算出的值、修改的对象状态等等,具体取决于代码的逻辑和执行过程中的操作。

需要注意的是,V8 的执行过程并不是一成不变的,它会根据代码的特点和执行环境的不同采用不同的策略和优化手段,以提高 JavaScript 代码的执行性能和效率。

词法分析与语法分析

词法分析:

词法分析是编译过程的第一个步骤,也叫做扫描或是标记化。

词法分析是将源代码进行扫描分解,形成一个个标记,也就是词法单元。这些标记可以是关键字、标识符、操作符、常量等。

词法分析器就是通过识别和分类字符或是字符序列,去除不必要的空白字符,注释等,生成这些标记,它的输出是一个标记序列,是下一步语法分析的输入。

语法分析:

语法分析是编译过程的第二个步骤,也叫解析。

它会根据自己的语法规则,将输入的词法分析生成的标记序列递归的转换成抽象语法树AST

抽象语法树是源代码的一种树形表示,反映了代码的层次结构与逻辑关系。

抽象语法树通常由节点表示不同的语法结构,比如表达式、语句、函数定义等。语法分析的输出是抽象语法树,它是后续编译过程的基础。

script标签相关

它是HTML利用来包含JS代码的一个标记,它可以在HTML 的页面嵌入JS代码,使得页面具有交互性和动态性。

他可以出现在HTML文档的<head>部分或是<body>里面,具体的位置要看他的执行时机。

一些常见的使用:

1.内联在<body>结构体里

<script>
    console.log('Hello, world!');
</script>

2.在头部进行引入

<script src="path/to/script.js"></script>

3.异步加载 async

脚本加载完成后会立即执行,可能会影响页面的内容和交互,特别是对于需要立即执行的脚本。适合不需要依赖页面内容的脚本。

<script src="path/to/script.js" async></script>

4.异步加载 defer

脚本会在 HTML 解析完毕后执行,因此不会影响页面内容和交互。适合需要等待页面解析完毕后执行的脚本,例如操作 DOM 元素的脚本。

<script src="path/to/script.js" defer></script>

说一下 var let 和const

首先,var是JS原生的声明变量关键字,let和const都是ES6后来新增的。

区别有以下几点:

作用域:

var是全局作用域或是函数作用域使用

let const是块级的作用域

 

变量提升:

var存在变量提升,同意作用域内可以进行多次的重复声明

let const不存在,同一作用域中不能多次声明同名的 let 变量,否则会报错

const声明的一般类型的变量不可修改,引用类型的地址不能修改,但是堆中的数据可以修改

ES6新增什么作用域,之前有什么作用域

1.全局作用域(Global Scope)

全局作用域是整个 JavaScript 程序的最外层作用域,它包含了所有的*变量和函数声明。在任何地方都可以访问全局作用域中的变量和函数。

2.函数作用域(Function Scope)

函数作用域是在函数内部声明的变量和函数的作用域。在函数作用域内声明的变量和函数只能在函数内部访问,函数外部无法直接访问。

ES6 新增了块级作用域,也就是使用 letconst 关键字声明的变量的作用域。

3.块级作用域(Block Scope)

块级作用域是在 {}(花括号)内部声明的变量的作用域。在块级作用域内部声明的变量只能在该块级作用域内部访问,外部无法访问。在 ES6 之前,使用 var 声明的变量在语法上是没有块级作用域的,它们只有函数作用域或全局作用域。

没有块级作用域之前,如何解决循环过程中异步加载时出现的作用域的问题

当使用 var 声明变量时,在循环中可能会因为变量的作用域问题导致出现微妙的 bug。

一个常见的例子是在循环中使用异步操作,比如 setTimeout 或者 AJAX 请求,由于 var 声明的变量会提升到函数作用域的顶部,导致在异步操作回调函数中访问到的变量值可能不是我们期望的值。

for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}

在这个例子中,我们期望循环结束后分别输出 0、1 和 2,但实际上输出的是 3、3、3。

这是因为在循环中使用了 var 声明的 i 变量,而 setTimeout 的回调函数是在循环结束后才执行的,此时 i 的值已经变成了 3。因为 var 声明的变量会提升到函数作用域的顶部,所以所有的回调函数都共享同一个 i 变量,并且都是在循环结束后执行,因此输出的结果都是 3。

要解决这个问题,可以使用闭包或者立即执行函数来创建一个新的作用域,保持每个回调函数访问到的 i 变量值都是期望的值。例如使用立即执行函数:

for (var i = 0; i < 3; i++) {
  (function(index) {
    setTimeout(function() {
      console.log(index);
    }, 1000);
  })(i);
}

这样就可以在每次循环中创建一个新的作用域,并且将 i 的值传递给回调函数,确保每个回调函数访问到的 i 变量值都是期望的值。

JS的作用域链机制

JavaScript 的作用域链机制是一种用于确定变量和函数作用域的机制。在 JavaScript 中,每个函数都会创建一个新的作用域,并且在函数内部定义的变量和函数只能在该作用域内访问,这就是作用域链的基础作用域链是由当前执行的函数的活动对象(activation object)和其父级函数的作用域组成的链式结构。

具体来说,作用域链的形成过程如下:

  1. 当函数被调用时,会创建一个新的执行环境(execution context),其中包含了该函数的作用域链。
  2. 每个执行环境都有一个变量对象(variable object),用于存储变量、函数和形参。
  3. 在函数内部访问变量时,JavaScript 引擎首先在当前执行环境的变量对象中查找,如果找到了对应的变量,则返回其值,如果没找到,则继续向上一级执行环境的变量对象中查找,直到找到全局执行环境,如果还没找到,则返回 undefined。
  4. 当函数执行完毕后,其执行环境会被销毁,作用域链也会随之销毁。

由于作用域链的机制,JavaScript 允许内部函数访问外部函数的变量和函数而外部函数则不能访问内部函数的变量。这种机制使得 JavaScript 具有了闭包(closure)的特性,使得函数可以“记住”自己创建时所处的作用域,即使在函数执行结束后仍然可以访问到外部函数的变量。

总的来说,JavaScript 的作用域链机制是一种通过执行环境中的变量对象组成的链式结构,用于确定变量和函数的作用域,实现了变量的词法作用域和函数的闭包特性。

代码题——立即执行函数能否访问到全局变量

立即执行函数(Immediately Invoked Function Expression,IIFE)可以访问到全局变量。在 JavaScript 中,立即执行函数是一个匿名函数,在定义后立即执行的语法结构。由于 JavaScript 的作用域链机制,内部函数可以访问到外部函数的变量和全局变量。

var globalVariable = 'I am global';

(function() {
  console.log(globalVariable); // 输出: I am global
})();

本地存储

本地存储就是指将客户端的一些信息储存在本地,以供客户端后续使用

主要有两种方法:

1.cookie储存

2.web储存(包括sessionStorage 和localStorage)

Web 存储通常比 Cookies 更灵活、安全且具有更大的存储容量,因此在开发中更常用于实现本地存储的需求。

不同网站之间的存储可以互读吗

不同网站之间的存储一般是不能互相读取的,这是出于安全和隐私考虑而设计的。Web 浏览器在设计时采取了同源策略(Same Origin Policy),该策略规定了一个网页只能访问与其来源相同的资源,这包括 JavaScript 访问本地存储(如 Cookies、localStorage、sessionStorage)时的限制。

具体来说,同源策略要求网页的协议(protocol)、域名(domain)和端口(port)必须完全相同,才能认为是同源。如果两个网页的源不同,即使它们在同一个浏览器窗口中打开,也不能互相访问对方的本地存储。

这意味着在不同网站之间是无法直接读取或操作对方的本地存储数据的。例如,一个网站不能读取另一个网站的 localStorage 中的数据。这种设计保护了用户的隐私和安全,防止了恶意网站窃取用户的敏感信息。

然而,有些情况下可能会有一些例外,比如在同一浏览器标签页中打开了多个同一域的网站,它们可能会共享同一个浏览器的会话,从而可以共享一些本地存储数据。但这通常是在特殊情况下,而不是普遍的现象。

什么是同源策略

同源策略(Same-Origin Policy)是一种浏览器安全策略,用于限制一个源(即协议、域名和端口)的文档或脚本如何与另一个源的资源进行交互。同源策略规定,页面中的脚本只能访问其自身源的数据,而不能直接访问其他源的数据。这个策略旨在保护用户的隐私和安全,防止恶意网站获取用户的敏感信息。

同源策略主要有以下限制:

  1. JavaScript 访问限制:在浏览器中执行的 JavaScript 代码只能与其来源相同的资源进行交互,不能访问其他源的数据。
  2. DOM 限制:一个源的文档对象模型(DOM)只能访问同一源的文档,不能访问其他源的文档。
  3. Cookie 限制:浏览器限制页面从其他源设置的 cookie,使得其他源无法获取用户的 cookie 信息。
  4. AJAX 请求限制:使用 XMLHttpRequest 发送的 AJAX 请求也受到同源策略的限制,只能向同一源发送请求。

同源策略的存在,可以有效防止恶意网站通过浏览器获取用户的敏感信息,保护用户的隐私和安全。但同时,也给一些跨域操作带来了一定的限制,为了克服这些限制,可以使用跨域解决方案,如 CORS(跨源资源共享)、JSONP、代理等。

满足什么条件算跨域

在 Web 开发中,跨域是指在浏览器中执行的 JavaScript 代码试图访问不同源(origin)的资源时所遇到的限制。不同源指的是协议(protocol)、域名(domain)或端口(port)中任何一个不同的情况。具体来说,满足以下任一条件都算作跨域:

  1. 协议不同:例如从 http://example.com 的页面尝试访问 https://example.com 的资源,这算作跨域。
  2. 域名不同:例如从 http://example.com 的页面尝试访问 http://example.net 的资源,这算作跨域。
  3. 端口不同:例如从 http://example.com:8080 的页面尝试访问 http://example.com:3000 的资源,这算作跨域。

跨域限制由浏览器的同源策略(Same Origin Policy)实施。同源策略是浏览器的一种安全机制,它限制页面来自不同源的 JavaScript 脚本如何交互。通过这种限制,浏览器可以防止恶意网站访问用户的敏感信息。

为了解决跨域问题,常用的方法包括使用 JSONP、CORS(跨源资源共享)、代理等技术。JSONP 是一种利用 <script> 标签可以跨域请求资源的技术,而 CORS 则是一种服务器端解决跨域问题的机制,它允许服务器设置响应头来控制跨域访问的权限。代理是指在同源的服务器上设置一个中间层,将请求转发到目标服务器,然后将响应返回给客户端,从而绕过了浏览器的同源策略。

如何解决跨域

跨域问题是由浏览器的同源策略(Same-Origin Policy)所导致的,为了安全起见,浏览器限制页面从不同源加载的资源之间的交互。解决跨域问题的方法有多种,以下是一些常用的方法:

  1. CORS(跨源资源共享)

    • CORS 是一种服务器端解决跨域问题的机制,允许服务器设置响应头来控制跨域访问的权限。
    • 在服务端配置响应头 Access-Control-Allow-Origin 允许特定源访问资源,或者使用 Access-Control-Allow-Origin: * 允许所有源访问资源。
    • 例如,如果你想允许 http://example.com 这个域名的页面访问你的资源,可以设置响应头为 Access-Control-Allow-Origin: http://example.com
  2. JSONP(JSON with Padding)

    • JSONP 是一种利用 <script> 标签可以跨域请求资源的技术。
    • 通过在页面中动态创建 <script> 标签,将目标服务器的数据作为参数传递给一个回调函数,从而实现跨域请求。
    • 例如,页面可以通过创建一个 <script> 标签来请求 http://example.com/data?callback=handleData,服务器会返回 handleData({...}) 的脚本,从而将数据传递给页面中的 handleData 函数。
  3. 代理

    • 在同源的服务器上设置一个中间层(代理服务器),将跨域请求转发到目标服务器,然后将响应返回给客户端。
    • 客户端向同源服务器发送请求,同源服务器再向目标服务器发送请求,并将响应返回给客户端,从而绕过了浏览器的同源策略。
    • 代理可以是服务器端的代理,也可以是客户端的代理,比如使用 Nginx、Apache、Node.js 等。
  4. WebSocket

    • WebSocket 是 HTML5 中新增的协议,它可以建立持久连接,双向通信,不受同源策略的限制。
    • 通过 WebSocket 可以实现跨域通信,但需要服务端支持 WebSocket 协议。

这些方法各有优缺点,可以根据具体的情况选择适合的方法来解决跨域问题。通常情况下,首选的解决方案是使用 CORS,因为它是浏览器端和服务器端共同支持的一种标准解决方案。

CDN的原理

CDN(Content Delivery Network,内容分发网络)是一种通过将内容分发到全球各地的服务器,以提高用户访问网站时的性能和体验的网络架构。CDN 的原理包括以下几个方面:

  1. 内容缓存: CDN 通过在全球范围内部署大量的缓存服务器,将网站的静态资源(如图片、CSS、JavaScript 文件)缓存到这些服务器上。当用户请求访问网站时,CDN 会根据用户的地理位置和网络条件,将静态资源从最近的缓存服务器中返回,而不是直接从源服务器获取。这样可以大大减少用户访问时的网络延迟和加载时间。

  2. 负载均衡: CDN 使用负载均衡技术来分配用户请求到不同的缓存服务器上。当一个缓存服务器负载过高或者故障时,CDN 可以自动将请求转发到其他可用的服务器上,确保用户始终能够快速访问到内容。

  3. 动态内容加速: 除了静态资源,CDN 也可以加速动态内容的传输。一些高级 CDN 服务提供商通过缓存动态生成的内容或者使用边缘计算技术,在缓存服务器上动态生成内容的副本,以加速动态内容的传输和响应速度。

  4. 数据压缩和优化: CDN 可以对传输的数据进行压缩和优化,以减少数据的传输量和加载时间。例如,CDN 可以使用 Gzip 等压缩算法对静态资源进行压缩,以减小文件大小,加快传输速度。

  5. 安全防护: 一些 CDN 提供商还提供安全防护功能,包括 DDoS 攻击防护、SSL 加密传输、内容加密等,以保护网站免受网络攻击和安全威胁。

综上所述,CDN 的原理包括内容缓存、负载均衡、动态内容加速、数据压缩和优化以及安全防护等技术,通过这些技术手段,CDN 可以提高网站的访问速度、稳定性和安全性,从而改善用户的访问体验。

http2.0

HTTP/2.0 是 HTTP 协议的下一版本,旨在改进 HTTP/1.x 的性能和效率。以下是 HTTP/2.0 的一些主要特点和改进:

  1. 多路复用(Multiplexing): HTTP/2.0 使用多路复用技术,允许在单个 TCP 连接上同时发送多个请求和响应。这样可以减少建立和关闭连接的开销,提高了连接的利用率,减少了网络延迟。

  2. 头部压缩(Header Compression): HTTP/2.0 使用 HPACK 压缩算法对 HTTP 头部进行压缩,减少了传输的头部大小。这样可以降低请求和响应的大小,减少了网络带宽的使用。

  3. 二进制传输(Binary Protocol): HTTP/2.0 使用二进制格式传输数据,而不是 HTTP/1.x 中的文本格式。这样可以减少解析和处理数据的开销,提高了数据的传输效率。

  4. 服务端推送(Server Push): HTTP/2.0 允许服务器在客户端请求之前主动推送资源到客户端的缓存中,以提高页面加载速度。例如,当客户端请求 HTML 页面时,服务器可以主动推送相关的 CSS 和 JavaScript 资源到客户端,从而减少了客户端的等待时间。

  5. 流优先级(Stream Prioritization): HTTP/2.0 允许客户端指定请求的优先级,服务器可以根据请求的优先级进行相应的处理。这样可以确保重要资源的优先传输,提高了页面加载的效率和体验。

HTTP/2.0 的引入主要是为了解决 HTTP/1.x 中存在的性能瓶颈和效率低下的问题,通过引入多路复用、头部压缩、二进制传输等技术,HTTP/2.0 提高了页面加载速度、减少了网络延迟和带宽的使用,从而改善了用户的访问体验。