JavaScript学习笔记--变量与数据类型(一)----变量声明、基础运算符以及控制结构

变量声明

变量的声明有三种关键字let、const和var

var操作符

  1. 作用域
  • var操作符定义的变量会成为包含它的函数的局部变量,变量在函数体内部申明,则变量的作用域为整个函数体,在函数体外不可引用
  • 函数内省略var操作符定义的变量会被创建为一个全局变量(当然这是在非严格模式下,严格模式不允许不声明)
  • 逗号分割变量及可选的初始化var message = 'acs', password = 'ass',age;
  • 可以反复声明,允许重复定义,后面的会被忽略
  1. 变量提升
  • var关键字声明的变量会自动提升到函数作用域顶部
  1. for循环渗透,for循环中用var声明的变量会泄露到for循环之外

  2. 可以被删除

let操作符

  1. 作用域
  • 声明的作用域为块级作用域(块级作用域是函数作用域的子集)
  • 不允许在一个块级作用域中出现冗余声明,不允许被重复定义,重复声明会爆出SyntaxError
  • 暂时性死区
  • 在let声明执行之前的瞬间被称为“暂时性死区”,在此阶段引用后面才声明的变量会抛出ReferenceError(在解析代码时,JavaScript引擎也会注意出现在块后面的let声明,只不过在此之前不能以任何方式来引用未声明的变量。)
  1. 不会进行变量提升

  2. 全局声明

  • 全局声明的变量不会成为window对象的属性,var声明的会
  1. 条件声明
  • 不能依赖条件声明模式
  1. 不允许被删除

  2. for循环不会渗透

for (var i = 0 ; i < 5 ; i++) {
    setTimeout(() = > {
        console.log(i);
    },2000);
} // 55555

for (let i = 0 ; i < 5 ; i++) {
    setTimeout(() = > {
        console.log(i);
    },2000);
} // 01234

let和var

这两个关键字声明的并不是不同类型的变量,而是只是指出变量在相关作用域如何存在。
区别

  1. 作用域
  2. 变量提升和暂时性死区
  3. 全局声明
  4. for渗透
  5. 冗余声明
  6. 能否被删除

const

  1. 块级作用域、不会进行变量声明提升
  2. 初始化时赋值
  3. 声明的变量值不允许修改(对象的话,只是那个引用不能改)
  • 使用const来定义常量,基本和let相同,唯一重要区别就是声明变量的时候必须同时初始化变量,尝试修改const声明的变量(基本数据类型)会导致运行错误
  • 若const声明的变量是引用数据类型的,那个变量只是一个指针,存储在栈内存,所指向的对象存储在堆内存,故可以修改的
  • 如果想要整个对象都不能修改,可以使用Object.freeze()

作用域总结

  • 两个不同函数各自声明同一个变量,则其只在各自的函数体内起作用,互相独立,互不影响
  • JS函数可以嵌套,此时内部函数可以访问外部函数定义的变量,反之不行,若内部和外部重名,则JS函数在查找变量时从自身函数定义开始,由内向外查找,重名则屏蔽外面
  • 变量提升,JS会先扫描整个函数体的语句,将所有var声明的变量提升到函数顶部;函数也存在变量提升,let声明的则无变量提升
  • 全局作用域,JS默认有一个全局对象window(浏览器环境下),全局作用域的变量实际被绑定成window的一个属性,以变量方式定义的函数也是一个全局变量
    var course = 'xxx'
    alert(course);
    alert(window.course);
    //等价 
  • 全局变量会绑定到window上,不同的JS文件如果使用了相同的全局变量或者定义了相同名字的顶层函数会造成命名冲突,减少冲突的方法是把自己的所有变量和函数全部绑定到一个全局变量中,
  • 由于JS的变量作用域实际上是函数内部,故在for循环等语句块中是无法按定义具有局部作用域的变量的,为了解决这个问题,ES6引入新的关键词let来声明一个块级作用域变量
    function () {
        for (var i = 0 ; i < 100 ; i ++) {
        }
        i += 100;//仍然可以使用
    }

    function () {
        for (let i = 0 ; i < 100 ; i ++ ){
        }
        i += 100; //错误
    }
  • ES6引入新的关键字const来定义常量,具有块级作用域
    const PI = 3.14;
  • 声明的风格及最佳实践,尽量使用let和const,不用var;其中const更好,const可以让给浏览器运行时保持变量不变,也可以让静态代码分析工具提前发现不合法的赋值操作。只有在知道变量会变的时候才用let

运算符

  1. '+'操作符
    可以用来加法运算或者字符串的连接,如果用一个字符串加上一个数字,那么操作数都会首先转换为字符串
  2. 比较操作符
  • =====
    不严格相等与严格相等,===在比较之前会进行自动类型转换。

控制结构

  1. if…else(else if)
  2. while和do-while
  3. for循环
  4. for…of
    for…of语句在可迭代对象(包括Array、Map、Set、String(迭代其中的每一个字符)、TypedArray、arguments对象等)上创建一个的迭代循环,通过调用自定义迭代钩子为每个不同属性的值执行语句
// 语法
for (variable of iterable) {
    //statements
}
// 迭代arguments
(function() {
  for (let argument of arguments) {
    console.log(argument);
  }
})(1, 2, 3);

// 1
// 2
// 3
  1. for…in
    for…in以任意顺序迭代一个对象的除Symbol以外的可枚举属性,包括继承的可枚举属性。forin是为了遍历对象属性而构建的,可以更方便的去检查对象属性。不建议与数组一起使用
  • 可枚举属性是指那些内部"可枚举标志"设置为true的属性,通过直接的赋值和属性初始化的属性默认设置true,通过Object.defineProperty等定义的默认为false
  • 属性的所有权是通过判断该属性是否直接属于某个对象决定的
  1. 三元操作符
  2. switch

for…of、for…in、hasOwnProperty、in

  • for…of遍历的是可迭代对象,for…in遍历的是一个对象的可枚举属性,包括继承得到的,导致其遍历数组是得到的是下标索引,那个才是可枚举的
  • hasOwnProperty可以确定某个属性是否是对象本身的属性或者使用getOwnPropertyNames(),所有继承了Object的对象都会继承到这个方法。需要注意的是,js并没有保护这个属性名,当某一个对象可以自有一个占用该属性名的属性时,我们需要使用外部的这个方法来获得正确的结果,例如是引用Object原型上的hasOwnProperty属性,如查看foo对象上的bar属性是否是自身的属性,Object.property.hasOwnProperty.call(foo,'bar')
  • in运算符,如果指定的属性在指定的对象或其原型链中,则in运算符返回true,in右操作数必须是一个对象值
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
0 in trees        // 返回true
6 in trees        // 返回false
"bay" in trees    // 返回false (必须使用索引号,而不是数组元素的值)
"length" in trees // 返回true (length是一个数组属性)
Symbol.iterator in trees // 返回true (数组可迭代,只在ES2015+上有效)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值