【JavaScript数据结构及算法——基础知识篇】

前言

为了准备秋招,开始了算法刷题之路,痛苦的刷了十几道后,惊觉自己还没有系统地、扎实地学习JavaScript的数据结构,虽然通过刷题也能刺激学习,但总归东一榔头西一棒槌,不成体系,且基础知识结构都没掌握好,耗时必然久且痛苦。故下定决心先把《学习JavaScript数据结构与算法》该书通读一遍,再来刷题巩固。此乃系列的第一篇:基础知识。

变量

变量类型

  • ES5的5种:Null,undefined,Boolean,Number,String, ES6新增:Symbol 表示独一无二的值 。ES10新增:BigInt 表示任意大的整数
  • 一种引用数据类型:(本质上是由一组无序的键值对组成):
    引用数据类型:Object。包含Object、Array、 function、Date、RegExp。 JavaScript不支持创建任何自定义类型的数据,也就是说JavaScript中所有值的类型都是上面8中之一。

如何定义变量

JavaScript并不是一种强类型语言。在强类型语言中,声明变量时需要指定变量的类型(例如,在Java中声明一个整型变量,要使用intnum = 1;)。在JavaScript中,我们只需要使用关键字var、let、const,而不必指定变量类型。(如果要对变量设定类型,见TypeScript)
其中,let 和 const 关键字是在 ES6 中才新增的。

let和var的区别

深入理解JS:var、let、const的异同 - OneForCheng - 博客园 (cnblogs.com)

1.作用域

var 声明的变量的作用域是它当前的执行上下文,即如果是在任何函数外面,则是全局执行上下文,如果在函数里面,则是当前函数执行上下文。换句话说,var 声明的变量的作用域只能是全局或者整个函数块的。
let 声明的变量的作用域则是它当前所处代码块,即它的作用域既可以是全局或者整个函数块,也可以是 if、while、switch等用{}限定的代码块
let 声明的变量的作用域可以比 var 声明的变量的作用域有更小的限定范围,更具灵活

function varTest() {
  var a = 1;
  {
    var a = 2; // 函数块中,同一个变量
    console.log(a); // 2
  }
  console.log(a); // 2
}

function letTest() {
  let a = 1;
  {
    let a = 2; // 代码块中,新的变量
    console.log(a); // 2
  }
  console.log(a); // 1
}
varTest();
letTest();

即在块作用域中两者的区别较为明显, let只在for()循环中可用,而 var是对于包围for循环的整个函数可用:

function  aFun1(){
    // i 对于for循环外的范围是不可见的(i is not defined)
    for(let i = 1; i<5; i++){
        //  i只有在这里是可见的
    }
    // i 对于for循环外的范围是不可见的(i is not defined)
}
function aFun2(){
    // i 对于for循环外的范围是可见的
    for(var i = 1;i<5; i++){
        // i 在for 在整个函数体内都是可见的
    }
    // i 对于for循环外的范围是可见的
}
2.重复声明

var 允许在同一作用域中重复声明,而 let 不允许在同一作用域中重复声明,否则将抛出异常。

var:

var a = 1;
var a = 2;

console.log(a) // 2

function test() {
  var a = 3;
  var a = 4;
  console.log(a) // 4
}

test()

let:

if(false) {
  let a = 1;
  let a = 2; // SyntaxError: Identifier 'a' has already been declared
}
3.绑定全局对象 this

var 在全局环境声明变量,会在全局对象里新建一个属性,而 let 在全局环境声明变量,则不会在全局对象里新建一个属性。

var foo = 'global'
let bar = 'global'

console.log(this.foo) // global
console.log(this.bar) // undefined
4.变量提升与暂存死区

var 声明变量存在变量提升

定义变量提升是当栈内存作用域形成时,JS代码执行前,浏览器会将带有var, function关键字的变量提前进行声明 declare(值默认就是 undefined),定义 defined(就是赋值操作), 这种预先处理的机制就叫做变量提升机制也叫预定义。

在变量提升阶段:带 var 的只声明还没有被定义,带 function 的已经声明和定义。所以在代码执行前有带 var 的就提前声明,比如这里的 a 就赋值成 undefined,在代码执行过程中遇到创建函数的代码浏览器会直接跳过。

console.log(a) // undefined
var a = 1;
console.log(a) // 1

使用是在执行阶段,而在此之前的创建阶段就已经将声明的变量添加到了变量对象中,所以执行阶段通过标识符可以在变量对象中查找到,也就不会报错

let 声明变量存在暂存死区,ES6 规定了其初始化过程是在执行上下文的执行阶段(即直到它们的定义被执行时才初始化),使用未被初始化的变量将会报错。

在变量初始化前访问该变量会导致 ReferenceError,因此从进入作用域创建变量,到变量开始可被访问的一段时间(过程),就称为暂存死区(Temporal Dead Zone)。

console.log(bar); // undefined
console.log(foo); // ReferenceError: foo is not defined

var bar = 1;
let foo = 2;
var foo = 33;
{
  let foo = (foo + 55); // ReferenceError: foo is not defined
}
小结

1.var 声明的变量在执行上下文创建阶段就会被**「创建」和「初始化」,因此对于执行阶段来说,可以在声明之前使用**。

2.let 声明的变量在执行上下文创建阶段只会被**「创建」而不会被「初始化」,因此对于执行阶段来说**,如果在其定义执行前使用,相当于使用了未被初始化的变量,会报错

const

const 声明的是一个只读变量,声明之后不允许改变其值.其实 const 其实保证的不是变量的值不变,而是保证变量指向的内存地址所保存的数据不允许改动(即栈内存在的值和地址)
const 只能保证指针是不可修改的,至于指针指向的数据结构是无法保证其不能被修改的(在堆中):

const obj = {
  value: 1
}

obj.value = 2

console.log(obj) // { value: 2 }

obj = {} // TypeError: Assignment to constant variable

.
.

运算符

JavaScript包含算术运算符、赋值运算符、比较运算符、逻辑运算符、位运算符、一元运算符和其他运算符。

  • 算术运算符
    在这里插入图片描述

  • 赋值运算符
    在这里插入图片描述

  • 比较运算符
    在这里插入图片描述

  • 逻辑运算符
    在这里插入图片描述

  • 位运算符
    在这里插入图片描述

JavaScript还支持delete运算符,可以删除对象里的属性

    var myObj = {name: 'John', age: 21};
    delete myObj.age;
    console.log(myObj); // 输出对象{name: "John"}

.

总结

在JavaScript中应该尽量少用全局变量,即var来定义。代码质量可以用全局变量和函数的数量来考量(数量越多越糟)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值