笔记

186 阅读8分钟

变量提升

  • 变量提升是指在 JavaScript 代码执行过程中,JavaScript 引擎把变量声明和函数声明提升到当前作用域最前面的行为。
  • 函数声明提升优先级高于变量声明,且不会被同名变量声明覆盖,但是会被变量赋值后覆盖。
  • 下面总结变量提升的过程:
  1. 在当前作用域查找所有的变量声明和函数声明,把这些声明都提到最前面,函数声明在变量声明之前。

  2. 如果函数声明或者变量声明存在同名的,则同名的函数声明或者同名变量声明都是后者覆盖前者,但是变量声明和函数声明同名,变量声明不能覆盖函数声明。

作者:码海浮萍
链接:juejin.cn/post/721891…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

作用域与作用域链

作用域定义了变量的可见性或可访问性。大白话来说,就是一个变量能不能被访问或引用,是由它的作用域决定的。

在 JavaScript 中有三种作用域。

  • 全局作用域
  • 函数作用域(局部作用域)
  • 块作用域

当一个变量在当前作用域无法找到时,便会尝试寻找其外层的作用域,如果还找不到,再继续往外寻找(只会往外寻找,不会寻找兄弟作用域,更不会往内寻找)。这种如同链条一样的寻找规则便被称为作用域链

词法作用域

能访问外部变量的函数就叫闭包,所有的函数好像都有这个特性,所以一般能利用函数的这个特性将某个独立作用域的变量取出来,同时这个变量就会被存入堆内存不会被销毁。那么当多个函数嵌套起来,词法作用域链由此诞生:内部的函数可以一层一层的访问外部函数的变量。

this

  1. 普通函数内部的this指向被调用时的对象 // Object.fn()

    如果没有被对象调用,那就指向全局作用域

  2. 箭头函数的this永远指向定义时的父作用域

var a = 1;
function printA(){
  console.log(this.a);
}
var obj={
  a:2,
  foo:printA,
  bar:function(){
    printA();// 和自调用函数执行一样,this都是指向window
  }
}

obj.foo(); // 2
obj.bar(); // 1
var foo = obj.foo;
foo(); // 1

***************************

var x = 3;
var y = 4;
var obj = {
    x: 1,
    y: 6,
    getX: function() {
        var x = 5;
        return function() {
            return this.x;
        }(); // 自执行函数this指向window
    },
    getY: function() {
        var y = 7;
        return this.y;
    }
}
console.log(obj.getX()) // 3
console.log(obj.getY()) // 6

new

1.新建一个空对象

2.将构造函数的原型和这个空对象进行绑定

3.执行构造函数,将this指向空对象

4.返回这个对象

function _new (Constructor, ...params) {
        const obj = Object.create(Constructor.prototype);
        const resultObj = Constructor.apply(obj, params);
        return typeof resultObj === 'Objiect' ? reslutObj : obj;
}

asyc函数

没有继发关系的异步可以按如下写法,解决asyc函数内await的阻塞问题

// 写法一
let [foo, bar] = await Promise.all([getFoo(), getBar()]);

// 写法二
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;

if else 判断过多 策略模式

1,用对象存储一系列方法逻辑 2,用一个方法,对象键值映射对应方法逻辑

image.png

防抖


function debounce(func, wait=0) {    

   if (typeof func !== 'function') {
    throw new TypeError('need a function arguments')
   }

   let timeid = null;
     let result;

   return function() {
    let context = this;
    let args = arguments;
    if (timeid) {
      clearTimeout(timeid);
    }
    timeid = setTimeout(function() {
      result = func.apply(context, args);
    }, wait);
    return result;
   }
}
// 处理函数
function handle() {    
    console.log(Math.random()); 
}
// 滚动事件
window.addEventListener('scroll', debounce(handle, 1000));

节流

// 节流throttle代码(定时器):
当触发事件的时候,我们设置一个定时器,再次触发事件的时候,如果定时器存在,就不执行,直到delay时间后,定时器执行执行函数,并且清空定时器,这样就可以设置下个定时器。当第一次触发事件时,不会立即执行函数,而是在delay秒后才执行。而后再怎么频繁触发事件,也都是每delay时间才执行一次。当最后一次停止触发后,由于定时器的delay延迟,可能还会执行一次函数。
var throttle = function(func, delay) {            
    var timer = null;            
    return function() {                
        var context = this;               
        var args = arguments;                
        if (!timer) {                    
            timer = setTimeout(function() {                        
                func.apply(context, args);                        
                timer = null;                    
            }, delay);                
        }            
    }        
}        
function handle() {            
    console.log(Math.random());        
}        
window.addEventListener('scroll', throttle(handle, 1000));

区别:

函数防抖:将几次操作合并为一此操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

函数节流:使得一定时间内只触发一次函数。原理是通过判断是否到达一定时间来触发函数。

区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现

缓存

www.jianshu.com/p/7bc3b8983… 比如:浏览器第一次请求a.jpg 时,服务器会发送完整的文件并附带额外信息

Cache-Control: max-age=300

浏览器把文件和附带信息保存起来。当再次需要a.jpg 时,如果是在300秒以内发起的请求则直接使用缓存(200, from xx cache),否则重新发起网络请求(200)。下面是Cache-Control常见的几个值:

  • Public表示响应可被任何中间节点缓存,如 Browser <-- proxy1 <-- proxy2 <-- Server,中间的proxy可以缓存资源,比如下次再请求同一资源proxy1直接把自己缓存的东西给 Browser 而不再向proxy2要。
  • Private表示中间节点不允许缓存,对于Browser <-- proxy1 <-- proxy2 <-- Server,proxy 会老老实实把Server 返回的数据发送给proxy1,自己不缓存任何数据。当下次Browser再次请求时proxy会做好请求转发而不是自作主张给自己缓存的数据。
  • no-cache表示不使用 Cache-Control的缓存控制方式做前置验证,而是使用 Etag 或者Last-Modified字段来控制缓存
  • no-store ,真正的不缓存任何东西。浏览器会直接向服务器请求原始文件,并且请求中不附带 Etag 参数(服务器认为是新请求)。
  • max-age,表示当前资源的有效时间,单位为秒。

优点:缓存控制功能更强大

缺点:假如浏览器再次请求资源a.jpg的时间间隔超过了max-age,这时候向服务器发送请求服务器应该会重新返回a.jpg的完整文件。但如果 a.jpg 在服务器上未做任何修改,发送a.jpg的完整文件就太浪费带宽了,其实只要发送一个「a.jpg未被更改」的短消息标示就好了。

缓存+更新机制终极版

比如:浏览器第一次请求a.jpg 时,服务器会发送完整的文件并附带额外信息,其中Etag 是 对a.jpg文件的编码,如果a.jpg在服务端未被修改,这个值就不会变

Cache-Control: max-age=300ETag:W/"e-cbxLFQW5zapn79tQwb/g6Q"

git

警惕:错误的Git版本回退姿势 - 许怀远的文章 - 知乎 zhuanlan.zhihu.com/p/34844206

proxy defineProperty

  • Proxy 是对整个对象的代理,而 Object.defineProperty 只能代理某个属性。所以我们在编写响应式函数的时候,defineProperty 需要用for in 去给每个属性添加监听

  • 对象上新增属性,Proxy 可以监听到,Object.defineProperty 不能。

  • 数组新增修改,Proxy 可以监听到,Object.defineProperty 不能。

  • vue中对数组没有进行defineProperty,而是重写了数组的7个方法。 分别是:

  • push

  • shift

  • pop

  • splice

  • unshift

  • sort

  • reverse

因为这些方法都会改变数组本身。

数组里的索引和长度是无法被监控的。

  • 若对象内部属性要全部递归代理,Proxy 可以只在调用的时候递归,而 Object.definePropery 需要一次完成所有递归,性能比 Proxy 差。 这个我们可以对比两个递归,definePropery 是在一开始,将传入的对象,所有属性,包括内部属性全部进行递归。之后才取处理set get。 但是Proxy的递归是在set中,这样,我们就可以根据需求,来调整递归原则,也就是说,在一些条件下,让其不进行递归。 举个很简单的例子。   我们页面上需要渲染一个对象,这个对象总是 会被整体重新赋值。不会单独的去修改其中的属性。那么我们就可以通过Proxy控制不让其递归这个对象,从而提高性能

  • Proxy 不兼容 IE,Object.defineProperty 不兼容 IE8 及以下

  • Proxy 使用上比 Object.defineProperty 方便多。

作者:云积分大前端团队
链接:juejin.cn/post/699433…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • CSS columns分栏布局和break-inside属性

  • 最外层列表盒子加上属性: column-count:2; 将页面分为两列

  • 列表中的每一个单独的小盒子添加属性:break-inside:avoid; 控制文本块分解成单独的列,以免项目列表的内容跨列,破坏整体的布局**

  • 图片的宽度设置:width:100%

blog.csdn.net/weixin_4371…

flex

zhuanlan.zhihu.com/p/25303493

symbol

zhuanlan.zhihu.com/p/22652486

Symbol 生成一个全局唯一的值。


var race = {
  protoss: Symbol(),
  terran: Symbol(),
  zerg: Symbol()
}

race.protoss !== race.terran // true
race.protoss !== race.zerg // true

vue3

juejin.cn/post/711112…

react

children

www.jianshu.com/p/d1975493b…

useLayoutEffect

juejin.cn/post/708110…