《整理5》

367 阅读6分钟

一. 用es5的方式实现es6中的const

const的特点:声明一个常量,只能读,不能修改。

思路:利用Object.defineProperty,

 function myConst(key, val) {
            window.key = val
            Object.defineProperty(window, key, {
                enumerable: false,//不能遍历
                configurable: false,//不可以配置,重新定义或删除
                writable: false,//不可以重新赋值
                value : val
                //也可以用属性访问器的方式
                // get() {
                //     return val
                // },
                // set(value) {
                //     if (value !== val) {
                //         throw new TypeError('不能重复定义')
                //     } else {
                //         return val
                //     }
                // }
            })
}

二. html5用于性能测试的api

window.performance

Performance Timing API 是一个支持 Internet Explorer 9 以上版本及 WebKit 内核浏览器中用于记录页面加载和解析过程中关键时间点的机制,它可以详细记录每个页面资源从开始加载到解析完成这一过程中具体操作发生的时间点,这样根据开始和结束时间戳就可以计算出这个过程所花的时间了。

三. 三栏布局,两侧定宽,中间自适应

1. flex布局

<div class="box">
    <div class="left">左侧</div>
    <div class="center">中间</div>
    <div class="right">右侧</div>
</div>
.box {
    display: flex;
}
.left {
	height:300px;
    width: 100px;
    background-color: yellow;
}
.center {
	height:300px;
    flex-grow: 1;
    background-color: red;
}
.right {
	height:300px;
    width: 50px;
    background-color: pink;
}

使用flex布局,两侧设置好宽度,中间设置flex-grow: 1;即可。如果有多余空间,就全给中间。两侧默认是0.

2. float布局

<div class="box">
    <div class="left">左侧</div>
    <div class="right">右侧</div>
    <div class="center">中间</div>
</div>
.left, .right, .center {
    height: 300px;
}
.left {
    width: 100px;
    float: left;
    background-color: yellow;
}
.right {
    width: 50px;
    float: right;
    background-color: pink;
}
.center {
    background-color: red;
}

这种布局方式,DOM结构必须是先写左右两侧浮动部分,然后再写中间部分,否则右浮动块会掉到下一行。 浮动布局的优点就是比较简单,兼容性也比较好。但浮动布局是有局限性的,浮动元素脱离文档流,要做清除浮动,这个处理不好的话,会带来很多问题,比如父容器高度塌陷等。这种布局的特点就是浮动对旧浏览器兼容性好,缺点就是主体内容需要放到最后加载,当页面元素较多时候可能会影响体验

3. grid布局

<div class="box">
    <div class="left">左侧</div>
    <div class="center">中间</div>
    <div class="right">右侧</div>
</div>
.box {
    display: grid;
    grid-template-columns: 100px auto 50px;
    grid-template-rows: 300px;
}
.left {  
    background-color: yellow;
}
.center { 
    background-color: red;
}
.right {  
    background-color: pink;
}

设置父元素的属性,比如第一列宽度占100px,第二列auto,第三列50px.这样就把父元素分成了三列,然后三个子元素自动分布。

4. 绝对定位

<div class="box">
    <div class="left">左侧</div>
    <div class="center">中间</div>
    <div class="right">右侧</div>
</div>
.box{
  border:1px solid black;
  background:pink;
  position:relative;
}
.left{
  width:100px;
  background:yellow;
  height:300px;
  
  position:absolute;
  left:0;
}
.right{
  width:100px;
  height:300px;
  background:red;
  
  position:absolute;
  right:0;
}
.center{
  background:green;
  height:300px;
  
  position:absolute;
  left:100px;
  right:100px;
}

父元素相对定位。三个子元素都绝对定位,让他们都相对box定位。左元素设置宽度,并且设置left为0。右元素也设置宽度,right为0.中间的不设宽度,但是设left和right属性等于它左侧元素的宽度和右侧元素的宽度。 可以看到三个元素都脱离了box的文档流。

四. HTTP的keep-alive字段

http 1.0 是普通模式,每次客户端和服务器进行请求和响应的时候,都会建立一个新的连接,响应完毕后就断开连接。所以就很低效,需要频繁的建立和断开连接。

所以http1.1 出现了keep-alive模式,就是长连接,客户端和服务器的连接是长久有效的,某一次通信完成后,连接也不会断开。当对服务器有后继请求时,keep-alive模式就避免了重新建立连接。

参考文章

五. 静态(词法)作用域和 动态作用域

作用域是用来限定一个变量名字的可用范围的。

词法作用域是在写代码,函数定义的时候就确定的,它关注函数是在哪里声明的,但是动态作用域是在运行时才确定的,关注函数是在哪里被调用的。

JS是通过作用域链的方式进行变量查找,而JS的作用域链是词法作用域链

var a = 2;

function foo() {
  console.log(a); // 会输出2还是3?
}

function bar() {
  var a = 3;
  foo();
}

bar();

因为JS遵循词法作用域:执行foo时,打印a,但是a既不是形参,也不是函数内部可找到的局部变量。所以会找foo函数定义的位置,顺着定义时就确定好的作用域链查找,所以打印2.

如果在动态作用域的情况下:就会找foo函数被调用的位置,所以打印3.

console.log(a)

function foo() {
  console.log(a); // 会输出2还是3?
}

function bar() {
  var a = 3;
  foo();
}
var a = 2;

bar();

会先打印undefined,再打印2。

六. Vue v-for循环中key的作用

key的作用主要是给每个节点一个唯一的标识,通过这个唯一的key,可以在新旧虚拟DOM的diff算法中,更快的找到对应的节点,从而提升效率。

传统的diff算法是遍历新旧虚拟DOM树中的每一个节点,Vue的diff算法是只比较同一层级中的节点,然后再比较他们的子节点。这样效率更高。那么在比较子节点的时候,会先从首尾依次两两比较,再通过key比较,相当于一个map映射。这时key的作用就出来了:如果没有key,就只能通过遍历的方式比较来匹配节点,增加性能消耗。明显,map映射找节点要比遍历的速度更快。

所以在Vue中,不绑定key并不会有问题,只会有警告。但是绑定了key,会提升性能。

七. vue2 和 vue3实现数据响应式的区别

  1. vue2是通过Object.defineProperty()对data上的每个属性设置getter/setter,来实现对每个属性的监听和拦截。这种方法有一个缺点,必须预先知道有哪些key,才能监听。所以对于新增的key,是无法实现响应式的。 vue3是通过proxy这个API实现数据响应式的,它是在更高维度上拦截属性的,它直接监听并拦截整个data对象,所以不管是已有的key还是新增的key,都能响应式。 提升效率
  2. vue2 只能通过重写数组原型上的方法来实现响应式,但是vue3 可以直接监听数组的变化。