零碎前端知识(更新中)

arguments 和 形参

在非严格模式下 argument 和形参相辅相成,一方会随着另一方的改变而改变

在严格模式下 argument 是静态副本,二者相互独立

for-in 循环

遍历自身和原型链上的可枚举属性,配合hasOwnProperty()--->判断是否为枚举源的属性 使用

箭头函数和普通函数

箭头函数的this在定义时确定,普通函数的this在执行前(预编译)时确定

箭头函数无法当做构造函数来使用(无法用new调用),因为:1.没有prototype 2.没有[[constructor]] 3.this早已确定

箭头函数没有自己的arguments,但能获取上一层级的arguments

从输入url到浏览器显示页面发生了什么

  • 输入url后,对url进行dns解析,转换成ip地址

    1、首先查找本地的hosts缓存文件是否有这个url地址的映射,如果有,就先调用这个ip地址映射,完成域名解析

    2、如果没有,浏览器向本地dns服务器发送请求(本地dns服务器由运营商提供)

    3、请求到本地dns服务器后,会先查找本地dns服务器的缓存文件,有相关映射会直接返回

    4、如果没有,则向dns根服务器进行查询

    5、如果dns根服务器也没有的话,则告诉本地dns服务器,向dns域服务器进行请求,并返回dns域服务器的地址

    6、本地dns服务器继续向dns域服务器进行查询,域服务器收到请求后,不会直接返回域名和ip的对应关系,而是给出所查询的域名解析服务器的地址

    7、最后,本地dns服务器对域名的解析服务器进行请求,从而得到一个ip地址和域名的对应关系,并存储在缓存文件中

  • 发送HTTP请求

    得到ip地址后,浏览器根据ip地址和端口号构成一个TCP连接请求,这个请求通过各种路由设备后达到服务器端,进入网卡,进入TCP/IP的协议栈,最终到达服务端的web程序,形成TCP/IP的链接

  • 服务器处理清求并返回HTTP报文

    后端从固定的端口接收到tcp报文,对tcp链接进行处理,对http协议进行解析

  • 响应报文

    通常就是服务器给浏览器返回文本信息(HTML,CSS,JavaScript等静态文件)

  • 浏览器渲染页面

    浏览器解析文件,页面会“自上而下”的加载,并在加载的过程中进行解析和渲染(回流(reflow)和重绘(repaint))

  • 连接结束

语义化

通俗地讲,语义化就是对数据和信息进行处理,使得机器可以理解.

优点:易于阅读,即使样式丢失也能呈现清晰的结构

​ SEO(搜索引擎优化),搜索引擎能根据标签来判断上下文和关键字的权重

​ 便于代码维护

前端工程化(说不准)

简而言之言而简之 能让项目快速完成 模块化 组件化 规范化 前后端分离的集合

flex 布局(弹性布局)

简述:将元素display设成flex(行内元素)inline-flex后该元素称为flex容器,其子元素称为flex子项。这便创建了flex布局

​ flex元素内部有两条轴:1)主轴 2)纵轴()。

​ 主轴方向默认为水平方向(row),交叉轴方向默认为垂直方向(column),它们是互相垂直的。flex子项排列方向与主轴方向一致。

属性:

  • ​ flex-direction(决定主轴方向)——>默认从左到右,从上到下

    .box{
        flex-direction : row|row-reverse|column|column-reverse
    }
    
  • flex-wrap (决定换行方式)——>当在一条轴线排不下的处理方式

    .box{
        flex-wrap :wrap|nowrap|wrap-reverse(换行且第一行在最下面)
    }
    
  • flex-flow——>是上面两个属性的简写版本 默认为 row nowrap

  • justify-content(决定了在主轴的对齐方式)

    .box{
        justify-content: flex-start | flex-end | center | space-between | space-around
    }
    
  • align-items(决定了在交叉轴怎么对齐)

    .box{
        align-items: flex-start | flex-end | center | baseline | stretch; 
    }
    
  • align-content(定义了多根轴线的对齐方式,如果项目只有一根轴线,则不起作用)

    .box{
        align-content: flex-start | flex-end | center | space-between | space-around | stretch
    }
    

order:定义排列顺序,数字越小,越靠前

flex-grow :定义放大比例

flex-shrink :定义缩小比例

flex-basis:定义占据主轴的空间大小

状态码

详情

原始值和引用值的类型和区别

原始值:存储在栈中的简单数据段,他们的值直接存储在访问的地址上

​ 类型:Number String Null Boolean undefined Symbol

引用值:存储在堆中的对象,即他们存储在变量处的值只是一个指针,指向存储值的内存处

​ 类型:object array function

区别:1)一个存储在堆中,一个存储在栈中
2)原始变量和他们的值存储在栈中,当一个原始变量传递给另外一个原始变量时,就是把一个栈房间的东西复制到另一个房间的 过程,两个原始变量相互独立,互不影响
引用值是把引用变量的名称存储在栈中,把实际对象存储在堆中,且存在一个指针由变量名指向存储在堆中的实际对象,当把一个引用值传递给另一个变量时,复制的其实是指向实际对象的指针,此时两者指向的是同一个数据,若通过方法改变其中一个变量的值,则访问另一个变量时,其值也会随之加以改变,但若不是通过方法而是通过重新赋值,此时,相当于重新开了一个房间,该值的原指针改变,则另外一个值不会随他的改变而改变。

CSS的布局问题

详情

HTML问题汇总

详情

闭包问题

一句话概述:函数能访问外部自由变量 在函数生命周期结束后,外部仍能访问函数内部变量 闭包是指有权访问另外一个函数作用域中的变量的函数,

展开说的话:从执行期上下文方面入手

详情

typeof可以正确判断类型嘛?

答案当然为否,对于原始类型来说,除了 null 都可以调用typeof显示正确的类型。

typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'

但对于引用数据类型,除了函数之外,都会显示”object”。

typeof [] // 'object'
typeof {} // 'object'
typeof console.log // 'function'

能代替typeof的方法还有instanceof——>在原型链从底向上查找,但是有些情况不符合

var str1 = 'hello world'
str1 instanceof String // false

instanceof这个方法只能检测由包装类new出来的值,如const a = new String("132")这种情况instanceof就会返回true

那有没有兼容性再强一点的判断方法呢?

当然有——>Object.prototype.toString.call()

//原始值
Object.prototype.toString.call(123)  //"[object Number]"
Object.prototype.toString.call("123")  //“[object String]”
Object.prototype.toString.call(undefined)  //“[object Undefined]”
Object.prototype.toString.call(null)  //“[object Null]”
Object.prototype.toString.call(Symbol(1))  //“[object Symbol]”
Object.prototype.toString.call(true)  //“[object Boolean]”
//基础引用值
Object.prototype.toString.call(function(){})  //“[object Function]”
Object.prototype.toString.call({})  //“[object Object]”
Object.prototype.toString.call([])  //“[object Array]”

但是这个方法也不是最完善的,还是有缺点,比如

function Person(name, sex){
    this.name = name;
    this.sex = sex;
}
const person = new Person("ZJX","male")
Object.prototype.toString.call(person)   //[object Object]

这种自定义类型,Object.prototype.toString.call()是无法判断person是Person的实例的,这种时候就是instanceof发挥作用的时候

console.log(person instanceof Person)  //true

JS类型转换有哪几种

JS中,类型转换只有三种:

  • 转换成数字
  • 转换成布尔值
  • 转换成字符串

转换具体规则如下:

原型链

原型对象和构造函数有何关系?

在JavaScript中,每当定义一个函数数据类型(普通函数、类)时候,都会天生自带一个prototype属性,这个属性指向函数的原型对象。

当函数经过new调用时,这个函数就成为了构造函数,返回一个全新的实例对象,这个实例对象有一个__proto__属性,指向构造函数的原型对象。

能不能描述一下原型链?

JavaScript对象通过prototype指向父类对象,直到指向Object对象为止,这样就形成了一个原型指向的链条, 即原型链。

  • 对象的 hasOwnProperty() 来检查对象自身中是否含有该属性
  • 遍历原型链可以用instanceof——>核心:原型链的向上查找
  • 使用 in 检查对象中是否含有某个属性时,如果对象中没有但是原型链中有,也会返回 true

HTTPS和HTTP的区别

JS的继承问题

逻辑CPU和物理CPU

os.cpus.length中显示的是逻辑cpu的数量

1.物理cpu数:主板上实际插入的cpu数量,可以数不重复的 physical id 有几个(physical id)

2.cpu核数:单块CPU上面能处理数据的芯片组的数量,如双核、四核等 (cpu cores)

3.逻辑cpu数:一般情况下,逻辑cpu=物理CPU个数×每颗核数

​ 如果超频的情况下,逻辑cpu = 物理CPU个数×每颗核数×2

浏览器的event loop顺序

同步任务—>微任务(异步await、Promise.then后面的代码)—>**宏任务(setTimeOut等定时器)**—>查看时候还有检查其中的微任务队列,如果为空则直接执行下一个宏任务,如果不为空,则依次执行微任务,执行完成才去执行下一个宏任务

async function async1() {
    console.log('async1 start')
    await async2()
    console.log('async1 end')
}

async function async2() {
    console.log('async2')
}

console.log('script start')

setTimeout(function() {
    console.log('setTimeout') 
}, 0)  

async1()

new Promise(function(resolve) {
    console.log('promise1')
    resolve()
}).then(function() {
    console.log('promise2')
})

console.log('script end')

答案:

script start

async1 start

async2

promise1

script end

async1 end

promise2

setTimeout

node.js的EventLoop

梳理一下,nodejs 的 eventLoop 分为下面的几个阶段:

  1. timer 阶段——>setTimeout、setInterval
  2. I/O 异常回调阶段
  3. 空闲、预备状态(第2阶段结束,poll 未触发之前)
  4. poll 阶段
  5. check 阶段
  6. 关闭事件的回调阶段