20230505----重返学习-回顾JavaScript知识体系的综合性整理-数据类型转化-堆栈内存及闭包作用域

本文详尽梳理了JavaScript中的数据类型转化规则,包括基础类型和引用对象类型的检测方法。此外,还探讨了堆栈内存机制,以及闭包和作用域的概念,特别是柯里化、惰性函数以及函数的防抖和节流技术。同时,文章涵盖了异步编程的处理,如Promise和async/await,以及HTTP网络和Ajax通信的基本原理和常见问题。
摘要由CSDN通过智能技术生成

day-062-sixty-two-20230505-回顾JavaScript知识体系的综合性整理-数据类型转化-堆栈内存及闭包作用域

回顾JavaScript知识体系的综合性整理

  1. 数据类型和堆栈内存
    • 变量声明:
      • 声明方式(var、function、let、const、class、import模块)
      • 命名方式
        • kebab-case:连字符命名法,用于CSS样式类名 & Vue中的组件调用 如<el-button>
        • camelCase : 小驼峰命名法「用于JavaScript常规变量及属性命名…」
        • PascalCase:帕斯卡命名法(或者大驼峰命名)「JavaScript类、组件名…」
      • 数据类型分类
        • 基础类型
        • 引用对象类型
      • 数据类型检测 *****
        • typeof 主用于基础数据类型
        • instanceof 主要用于已知的引用数据类型
        • constructor 用于已知构造函数的引用数据类型
        • Object.prototype.toString.call
      • 数据类型转换 ***
      • 对象、函数、数组、正则、字符串、Math、Date等常用的方法和细节处理 *
        • 对象常用方法
        • 函数常用方法
        • 数组常用方法
        • 正则元字符和修饰符
      • 堆栈内存
      • 闭包作用域 ***
      • 柯里化函数、compose函数、惰性函数 *****
      • 函数的防抖和节流 *****
      • 数组和对象的深浅拷贝和深浅合并 *****
  2. 面向对象编程
    • 对象、类、实例
      • 三者关系
    • new的原理 *****
      • new与不new的区别
      • 写一个new
    • prototype和__proto__
    • this指向的问题 ***
    • 链式写法
    • 类的继承、封装、多态 *****
    • 插件组件封装及鸭式变形…
  3. DOM操作
    • 获取DOM元素/元素(节点)集合的方法
    • 节点关系属性
    • 节点的增删改
    • 操作DOM元素的样式
    • 事件绑定
      • DOM0级DOM2级事件绑定
      • 事件对象
      • 事件的传播机制
      • 事件委托(事件代理) ***
      • 拖拽的处理
  4. 异步编程&动画处理
    • 定时器 和 requestAnimationFrame ***
    • 动画的处理
    • EventLoop事件循环机制 *****
    • Promise *****
    • async/await *****
    • 浏览器底层沉浸机制[DOM回流重绘]
  5. HTTP网络&Ajax前后端数据通信
    • 从输入URL地址到看到整个页面,中间发生了什么(HTTP网络知识) *****
    • ajax基础知识
      • 核心四步操作
      • GET系列请求和POST系列请求的区别
        • 核心是因为传参方式
          1. 安全问题
          2. 传输内容大小的问题
          3. 缓存问题
      • readyState状态值
      • status(HTTP状态码)
        • 200成功
          • 无特殊处理的成功
        • 301永久重定向(用于域名交替,域名服务器帮你的)、302临时转移/307临时重定向(服务器超负荷时先转移,服务器负载均衡)、304走缓存(协商缓存,浏览器自己帮你的)
          • 都是经过特殊处理的错误
        • 400(服务器拒绝-参数有误)、401(服务器拒绝-权限问题)、403(服务器拒绝访问-不告知原因)、404(访问地址错误)、405(请求方式不被支持,如用post去访问)、408(请求超时)
          • 一般是前端的问题,换参数等
        • 500(未知服务器错误–服务器那边有问题,如服务器起火)、502(网关有问题)、503(服务器超负荷–可用服务器负载均衡来处理,有人能进,有人不能进)
        • HTTP状态码
      • xhr的属性和方法及事件监听
        • 查看原型,看私有属性与公有属性
    • 传输数据的问题
      • 客户端发请求给服务器,想要传递一些信息给服务器
        • 请求头,如token等
        • 问号传参,如get请求参数
        • 请求主体
          • 请求主体的具体格式要求
            • 通过请求头的Content-Type
          • 格式类型
            • 字符串格式 主要用于与服务通信
              • JSON字符串,最常用 ‘{“xxx”:xxx,…}’ MIME:application/json
              • urlencoded字符串 ‘xxx1=xxx&xxx2=xxx…’ MIME:application/x-www-form-urlencoded
              • 普通字符串 ‘…’ MIME:text/plain
            • Form-Data格式 主要用于文件的上传 MIME:multipart/form-data
            • Buffer或者二进制格式
          • 不支持普通对象格式,默认情况下 xhr.send({xxx:xxx,…}), 写的普通对象,会变为’[object Object]’ 传递给服务器!
      • 服务器想把信息返回给客户端
        • 响应头
        • 响应主体[也有一些具体的格式]
          • 字符串格式
            • 一般常用的就是json字符串
          • Buffer、二进制、文件流格式
    • jQuery中的$.ajax库(选学)
    • 基于Promise封装的ajax库:axios
      • 基础运用 axios.get/axios.post…
      • 二次封装
        • 通用配置
        • transformRequest,请求主体处理
        • 请求拦截器
        • 响应拦截器
      • axios的几个特点
        • 会把在请求主体中写的普通对象,默认转换为JSON字符串,发送给服务器
        • 会自动识别常见的数据格式,自动基于Content-Type设置对应的MIME类型
        • 会自动把从服务器获取的JSON字符串转换为JSON对象(可以基于responseType配置项设置)
    • fetch新一代前后端通信方案 *****
    • 跨域解决方案及其原理和运用
      • jsonp:原理和封装
        • 偶尔用
      • CORS:跨域资源共享,后端的服务器配置
      • proxy:跨域代理(最常用的),前端的服务器配置
        • 原理和配置
      • 其它方案:postMessage、document.domain…
  6. 一些其它的知识体系
    • 设计模式: *****
      • 单例模式、构造函数模式、发布订阅模式、Promise承诺者模式、观察者模式、装饰器模式…
    • 插件和库:jQuery、swiper、animate.css、Bootstrap(选学)…
    • ES6知识汇总
      • let/const/class(和var/function区别)
      • 模块规范:单例、AMD、CommonJS(CMD)、ES6Module
      • 箭头函数(主要是和普通函数的区别)
      • 解构赋值
      • ...运算符
      • 模块字符串
      • ?.可选链 obj?.x?.y.z
      • 数组和对象中新增的方法 ***
      • Symbol/BigInt
      • Set/Map *****
      • Promise/async/await *****
      • Generator/Iterator *****
      • Proxy/Reflect *****
      • Fetch *****

数据类型转化

  • 把其他数据类型转换为Number

    • Number([val])

      • 一般用于浏览器的“隐式转换”中
        1. 数学运算
        2. isNaN检测
        3. ==比较
      • 规则:
        1. 字符串转换为数字:空字符串变为0,如果出现任何非有效数字字符,结果都是NaN

        2. 把布尔转换为数字:true->1 false->0

        3. null->0 undefined->NaN

        4. Symbol无法转换为数字,会报错:Uncaught TypeError: Cannot convert a Symbol value to a number

        5. BigInt去除n(超过安全数字的,会按照科学计数法处理)

        6. 把对象转换为数字:

          1. 先调用对象的 Symbol.toPrimitive 这个方法
            • 如果不存在这个方法:则继续下一步处理
            • 如果存在这个方法:则把这个方法执行,传递"number"标识进去
              • 调用此方法可以传递’number’/‘string’/‘default’
          2. 再调用对象的 valueOf 获取原始值
            • 如果获取的值是原始值:这就是转换的结果
            • 如果不是原始值,则继续下一步
          3. 再调用对象的 toString 把其变为字符串
          4. 最后再把字符串基于Number方法转换为数字
          //===============================
          let obj = {};
          let arr = [10];
          let time = new Date();
          let num = new Number(10);
          
          console.log(Number(obj)); //NaN
          // obj[Symbol.toPrimitive] -> undefined
          // obj.valueOf() -> {}
          // obj.toString() -> '[object Object]'
          // Number('[object Object]') -> NaN
          
          console.log(Number(arr)); //10
          // arr[Symbol.toPrimitive] -> undefined
          // arr.valueOf() -> [10]
          // arr.toString() -> '10'
          // Number('10') -> 10
          
          console.log(Number(time)); //时间戳(距离1970.1.1毫秒差)
          // time[Symbol.toPrimitive] -> 函数
          // time[Symbol.toPrimitive]('number')  调用此方法会传递‘number’、‘string’、‘default’
          
          console.log(Number(num)); //10
          // num[Symbol.toPrimitive] -> undefined
          // num.valueOf() -> 10
          
          /* // 2.a等于什么值,可以让条件成立
          var a = ?;
          if (a == 1 && a == 2 && a == 3) {
              console.log('OK');
          } */
          
          /*
          方案一:当前的比较是基于“==”来处理的,所以a的值只要不是数字类型,都会隐式转换为数字类型「Number(a)」
            @1 经过初步分析,a只能是一个对象 
            @2 把对象基于Number进行隐式转换,会经历 Symbol.toPrimitive -> valueOf -> toString -> Number
            @3 所以我们只要对其转换的某一步进行重写,让每一次转换分别返回 1/2/3 ,就可以实现需求了
          */
          
          var a = { x: 0 };
          a[Symbol.toPrimitive] = function toPrimitive() {
            return ++a.x;
          };
          if (a == 1 && a == 2 && a == 3) {
            console.log("OK");
          }
          
          /* 
          var a = [1, 2, 3];
          a.toString = a.shift;
          if (a == 1 && a == 2 && a == 3) {
          console.log('OK');
          } 
          */
          
          /* 
          方案二:在全局上下文中,基于var声明的变量,会放在GO中(相当于给window设置一个属性)
            @1 以后 a==1 ,就是获取window.a的值,和1进行比较
            @2 既然这样,我们就可以对window.a做数据劫持,在获取其值的时候,让每一次返回 1/2/3「GET函数」
          */
          var i = 0;
          Object.defineProperty(window, "a", {
            get() {
              return ++i;
            },
          });
          if (a == 1 && a == 2 && a == 3) {
            console.log("OK");
          }
          
    • parseInt([val])与parseFloat([val])

      • 一般用于手动转换
      • 规则:[val]值必须是一个字符串,如果不是则先转换为字符串;然后从字符串左侧第一个字符开始找,把找到的有效数字字符最后转换为数字「一个都没找到就是NaN」;遇到一个非有效数字字符,不论后面是否还有有效数字字符,都不再查找了;parseFloat可以多识别一个小数点;
    • parseInt([val],[radix])

      • 从[val]左侧开始进行查找,找到所有符合[radix]进制的内容,然后把其按照[radix]进制转换为10进制!!
        • [radix]是设置的进制,取值有效范围是2~36之间,如果不在有效范围内,结果就是NaN
        • [radix]不写或者设置为0,默认就是10
          • 特殊情况:如果[val]是以0x开始的,则默认值是16
  • 把其他数据类型转换为字符串

    • 也分为:隐式转换和显式转换
      • 显式转换
        • 方法有:String([val]) 或者 [val].toString() 等
          • String([val]) 和 [val].toString() 的处理机制是不一样的
            • [val].toString()规则:
              1. 基于原型链查找机制,找私有和公有上的toString方法
              2. 把找到的方法执行即可!!-> 如果用的是Object.prototype.toString方法,不是用来转字符串,而是检测数据类型的!!
            • String([val])规则:
              1. 对于其它原始值来讲,基本上就是拿字符串包起来
              2. 对象转字符串
              • String(对象):按照 先找Symbol.toPrimitive -> 再调用valueOf -> 最后调用toString 来处理
      • 隐式转换使用的都是String([val])这种方式
    • +除数学运算,还可能代表的字符串拼接
      • 有两边,一边是字符串,肯定是字符串拼接

      • 有两边,一边是对象,则可能是字符串拼接,还有可能是数学运算

      • 只出现在左边,例如:+“10” 这种方式就是把其它值转换为数字

      • 遇到++i或者i++,一定是把i的值变为数字再进行累加的

      • let result = 100 + true + 21.2 + null + undefined + "Tencent" + [] + null + 9 + false;
        // 100 + true + 21.2 + null -> 122.2
        // 122.2 + undefined -> NaN
        // NaN + "Tencent" -> "NaNTencent"
        // 往后所有操作都是字符串拼接 "NaNTencentnull9false"
        
  • 把其他数据类型转换为Boolean

    • 转换规则:除了0/NaN/空字符串/null/undefined五个值是false,其余都是true
    • 出现情况:
      1. Boolean([val]) 或者 !/!!
      2. 条件判断
  • ==相等,两边数据类型不同,需要先转为相同类型,然后再进行比较

    1. 对象==字符串 对象转字符串
    2. null==undefined -> true null/undefined和其他任何值都不相等
      • null===undefined -> false
    3. 对象==对象 比较的是堆内存地址,地址相同则相等
    4. NaN!==NaN NaN和任何值(包含本身)都不相等
    5. 除了以上情况,只要两边类型不一致,剩下的都是转换为数字,然后再进行比较的
  • ===绝对相等,如果两边类型不同,则直接是false,不会转换数据类型「推荐」

  • Object.is([val1],[val2]) 检测两个值是否相等「ES6新增的」

    • 核心用的是===
    • 特殊:
      • Object.is(NaN,NaN) => true
      • Object.is(+0,-0) => false

堆栈内存及闭包作用域

对象的堆栈内存

/* //3. 下面代码输出结果?
let obj={
  x:1,
  y:[10,20]
};
let obj2=obj;
let obj3={
  ...obj2
};
obj2.x=100;
obj2.y[1]=30;
obj3.x=200;
obj3.y[2]=40;
obj=obj3.y={
  x:0,
  y:[1,2]
};
console.log(obj,obj2,obj3); */

let obj = {
  x: 1, //1-->100
  y: [10, 20], //[10, 20]-->[10,30]-->[10,30,40]
}; //{ x: 0, y: [1, 2], }
let obj2 = {
  ...obj,
}; //{ x: 100, y: [10,30,40], }
let obj3 = {
  ...obj2,
}; //{x:1,y:obj.y}-->{x:200,y:obj.y}-->{x:200,y:{ x: 0, y: [1, 2], }}
obj2.x = 100;
obj2.y[1] = 30;
obj3.x = 200;
obj3.y[2] = 40;
obj = obj3.y = {
  x: 0,
  y: [1, 2],
};
console.log(obj, obj2, obj3); //{ x: 0, y: [1, 2], }//{ x: 100, y: [10,30,40], },{x:200,y:{ x: 0, y: [1, 2], }}

函数及闭包作用域

  • 作用域链:遇到一个变量,要怎么查找–通过作用域链,上级上下文。
  • 原型链:一个对象变量里的属性,要怎么查找,对象的原型。
/* // 4. 下面代码输出结果?
let x = 5;
function fn(x) {
  return function (y) {
    console.log(y + ++x);
  };
}
let f = fn(6);
f(7);
fn(8)(9);
f(10);
console.log(x); */

let x = 5;
function fn(x) {
  return function (y) {
    console.log(y + ++x);
  };
}
let f = fn(6); //function (y) {console.log(y + ++x);} |-|-| x=6  |-|-| x=7 |-|-| x=8
f(7); //14;
fn(8)(9); //18
f(10); //18
console.log(x); //5

进阶参考

  1. HTTP状态码
  2. ES6入门教程 – 作者:阮一峰
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值