<Javascript重拾①>Js基本运行机制与数据类型

时间:2021-1-8 作者:admin

最近刚做完一个全栈项目,反思时,发现JS基础薄弱,痛定思痛,故决定回顾JS,查漏补缺,温故知新

JS的运行机制:

1.当浏览器(内核/引擎)渲染和解析JS代码的时候,会为JS代码提供一个可运行的环境,即”全局作用域(global/window scope)”

2.代码自上而下执行(执行前存在变量提升阶段)

Js的垃圾回收机制

个人觉得最主要的概念就是可达性,这么理解真是太简单粗暴了,里面的优化算法还是相当优秀的

  1. 可达性: 即当前的所有变量与参数是否可以从全局对象从延神过去,如果不行则会回收该变量或参数.

基本数据类型与引用数据类型的赋值差异(执行差异)

  1. 基本数据类型(值类型),为按值操作,即当每创建一个新值,都会为该值开辟一个新空间,存储在当前作用域下(栈内存)

    值类型: 数字Number, 字符串 String, 布尔Boolean, null, undefined

     数字 Number : 
         NaN(not a number),指该值为一个数字类型,但非为有效数字,且与任何值都不相等
         isNaN,检测一个值是否非有效数字,会先使用Number()将值转换为数字再进行检测
    

    栈内存: 本身即是JS运行环境

  2. 复杂数据类型(引用类型), 由于存储数据类型可能复杂,存储后的内容通过地址(16进制)引用进行修改,额外开辟新的空间(堆内存),而不会存储在当前作用域.

    引用类型: 对象 Object(数字, 日期….), 函数 Function, ( 在ES6中加入了唯一值 Symbol )

    堆内存: 用于存放引用数据类型,如: 对象内存放键值对,函数体内存放代码字符串

数据类型

基本数据类型
数字Number 整数 浮点数 Infinity -Infinity
数字Bigint 大于 (2^53-1) 小于-(2^53-1)
字符串 String
布尔Boolean
null 自成类型
undefined 自成类型
symbol 唯一值

复杂数据类型
Object

Tip: 通过tyepof 去判断null类型会得到Object,但这是Javascript本身的问题,去输出函数如alert会得到function类型,但是在Javascript并不存在function类型

数字类型

  1.小数计算,应该避免相等性检查.这与计算机存储数字的方式有关,即二进制无法精确的存储0.1这种小数.

  2.使用小数时,要记住小数会有精度问题.

  3. isFinite() 用于判断一个变量是否为有效数字(非infinity,-infinity,NaN)

// 记一个复杂度较低的算法, 带到日后刷起 leetcode, 我相信这是我对算法兴趣的开端
function getMaxSubSum(arr) {
  let maxSum = 0;
  let partialSum = 0;

  for ( let item of arr) {
    partialSum += item
    maxSum = Math.max(maxSum, partialSum)
    if(partialSum < 0) partialSum = 0;
  }
  return maxSum;
}
alert( getMaxSubSum([-1, 2, 3, -9]) ); // 5

字符串类型

  1.字符串可通过[]charAt() 获取字符串的固定字符,区别在于如果[]获取不到字符,返回undefined,而charAt()返回一个空字符串.

  2.for..of 可以遍历字符串.

  3.slice(start, [end]) 用于字符串的截取.

  4.localeCompare() 根据当前的语言规则来判断两个字符串的大小.

Symbol

  1. Symbol类型是唯一值,字面量中使用是给键添加一个[]
      如 [id] : 123;

  2. Symbol 能够起到唯一标识的作用且创建的属性会被隐藏,即在循环时,该属性将不会被访问到,或者该库内的脚本,被第三方应用的时候,该属性也不会被访问到,不会引起冲突.

  3. Symbol类型的创建方式

 let id = Symbol("id"); // 对该变量的描述

  4. 全局注册表
    通过 Symbol.for() 进行查询,如果变量不存在,则创建.

 let id = Symbol.for("id"); // 查询or创建一个description为 id 的Symbol

 let id2 = Symbol.for("id"); // id是存在,即此行为查询.

 alert( id === id2 )  // true

    通过 Symbol.keyFor() 可以通过变量名查找Symbol.

 let link = Symbol.for("name"); // 查询or创建一个description为 id 的Symbol

 alert(Symbo.keyFor(link)) // name

注意: Symbol(“id”)与Symbol.for(“id”)是有区别的,前者是局部上的一个唯一值,而后者是全局范围内的.

系统 Symbol

这个内容尚未接触,待补充.

基本数据类型操作中要注意的地方

1.运算符中,只要 + 的运算会将 元(参数) 转换为字符串类型(String),其余则全部转换为数字类型(Number)

2.有意思的是,单元运算中,+ 类似于Number()方法,可以将参数转换为数字

    +=''  // 0
    += undefined // NaN
    += null // 0
    += " \t \n" // 0

复杂数据类型(Object)

方括号

  1.用于对多字段属性名的命名.
  2.计算属性简单来说,就是从对象外部去获取属性名.

let fruit = prompt("Which fruit to buy?", "apple");

let bag = {
  [fruit]: 5, // 属性名是从 fruit 变量中得到的
};

alert( bag.apple ); // 5 如果 fruit="apple"

  3.通过外部动态输入的值访问变量

let user = {
  name: "John",
  age: 30
};

let key = prompt("What do you want to know about the user?", "name");

// 访问变量
alert( user[key] ); // John(如果输入 "name")

for(..in..)

记录自己遗漏的点.

  1. 如果对象的属性存在,for循环才会执行.

可选链 “?.”

1.可选链 “?.” 用于防止访问的值不存在的时候报错,但是实际上用了可选链,返回的值仍是undefined,对用户来说还是不友好,但可以自己处理错误.
2.可选链的结构:

 let user = {
     name = "Link",
 }

// ↓↓这里
 alert( user?.name )

可见可选链是为问号所在节点提供可选,但对name是不起作用的,也就是说如果name属性不存在,代码仍会报错

3.可选链使用规则

注意一下 这里纯属个人推测理解

   1) 可选链要求被判断属性的对象必须被声明,但可以为空

      let user = {};
      alert(user?.address) // 代码不会报错
 //-----------------------------
      let user = {};
      alert(user.address?.street)  // 同样不会报错,但是address属性,并没有被定义
 //-----------------------------
      alert(user?.address) // 代码报错


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。