IT编程技术

天行健,君子以自强不息;地势坤,君子以厚德载物;

JS第二节-类型、值和变量

2021-2-22 博主:Splendor JavaScript笔记

类型、值和变量
     计算机程序在运行的时候需要对值(如数字3或文本"Frist program")进行操作。在编程语言中,能够表示并操作的值的类型称做数据类型,编程语言最基本的特性就是能够支持多种数据类型。当程序需要将值保存起来以备将来使用时,便将其赋值给一个变量。
     JS数据本为两类:①原始类型(数字,字符串,布尔值) ②对象类型

1,数字
     JS中不区分整数和浮点数值。JS中所有数字均浮点数值表示(下面数值都表示数字)
     var x = 3.14;    // 带小数点的数值
     var y = 3;       // 不带小数点的数值

1.1整型直接量(下面数值都是整型)
      0
      10
      30000

1.2浮点型直接量(下面数值都是浮点型)
     1.68
     0.3333333
     23456.45987
     6.02e23     //6.02*10^23

1.3JS中的算术运算
算术运算符对数值(文字或变量)执行算术运算。
运算符 描述
+ 加法
- 减法
* 乘法
**
/ 除法
% 系数
++ 递增
-- 递减

1.4二进制浮点数和四舍五入错误
     在JS中使用实数的时候,常常只是真实值的一个近似表示。JS采用了IEEE-754浮点数表示法,可以精确地标识分数1/2、1/8等。但常用分数(特别是在金融计算时)都是十进制分数1/10,1/00等,二进制浮点数表示法并不能精确表示0.1这样数字。JS中数字具有足够的精度,并可以极其近似于0.1。例如下面的代码:
var x=0.3-0.2;         //0.09999999999999998
var y=0.2-0.1;         //0.1
x==y                   //false 两值不相等
1.5日期和时间
    JS语言核心包括Date()构造函数,用来创建表示日期和时间的对象。
var d = new Date(); //Mon Feb 22 2021 14:18:32 GMT+0800 (中国標準時)
1.6文本
   字符串是一组由16位值组成的不可变的有序序列,每个字符通常来自于Unicode字符集。JS通过字符串类型来表示文本。

1.7字符串直接量
   JS程序中字符串直接量,是由单引号或双引号括起来的字符序列。由单引号定界的字符串中可以包含双引号,由双引号定界的字符串也可以包含单引号。例子如下:
""                  //空字符串:包含0个字符
'test'
"34434"
'wo="我"'      //单引号定界中可以包含双引号
"ni='你'"       //双引号定界中可以包含单引号
1.8转义字符
   在JS字符串中,反斜杠(\)有着特殊的用途,反斜杠符号后加一个字符,就不在表示他们的字面含义,比如\n就是一个转义字符换行的意思。
代码 结果
\b 退格键
\f 换页
\n 新行
\r 回车
\t 水平制表符
\v 垂直制表符

1.9字符串连接
    字符串的连接在JS中用”+“号,但”+“号也同样表示两个数值的计算,这时就要看表达式左右两边的类型。
msg="Hello" + 123         //Hello123
msg=2+3+4+"456"          //9456
msg="wo" + "ai" + ”ni"  // woaini
msg="452"+2+3+1          //452231

2.0布尔值
    布尔值指代真或假,开或关,是或否。这个类型只有两个值true和false
    在JS中的值都可以转换为布尔值,下面这些值会被转换成false;除了下面的值其它值都可以转换成true真值
    undefind 
    null 
    0 
    -0 
    NaN   
    ""//空字符串

2.1 null和undefined
null 表示空值 typeof值为object
undefined 表示值的未定义 typeof值为undefined
null==undefined        //true
null === undefined   //false

2.2 全局对象
     全局对象的属性是全局定义的符号,JS程序可以直接使用。当JS解释器启动时,它将创建一个新的全局对象,并给他一组定义初始属性:

  • 全局属性:undefined,infinity,NaN
  • 全局函数:isNaN(),parseInt(),eval()
  • 构造函数:Date(),RegExp(),String(),Object(),Array()
  • 全局对象:Math和JSON
2.3 包装对象
    JS对象是一种复合值:它是属性或已命名值的集合。通过“.”符号来引用属性值。当属性值是一个函数的时候,称其为方法。看如下代码:
var ss="nihao";
var newSs=ss.substring(2,3)   //h
字符串不是一个对象怎么有了属性呢?在JS中只要引用了字符串s的属性,JS解释器就会把他自动包装成一个对象,通过new String(s)方法在解释器中自动完成。一旦属性引用结束,这个新创建的对象就会被自动销毁。

2.4 不可变的原始值和可变的对象引用
   JS中的原始值是不可更改的:任何方法都无法更改一个原始值。
var s="woaini";
s.toUpperCase()    //返回WOAINI,只是创建了一个新的字符串
s                  //但打印s值却是woaini,原始字符串并未改变
   JS中对象和原始值不同,首先,对象是可变的,值是可以修改的:
var o={x:1};        //定义一个对象
o.x=2;              //修改对象属性
o.y=3;              //再次更改这个对象,给它增加一个新属性
   对象的比较:即使两个对象包含同样的属性及相同的值,它们也是不相等的。各个索引元素完全相等的两个数组也不相等:
var o={x:1},p={x:1};
o===p;                          //false
var a=[1,2],b=[1,2];
a===b;                          //false
2.5 类型转换
    JS期望使用一个字符串,它会把给点的值转换为字符串。如果JS期望使用一个数字,它会把给定的值转换为数字。
10 + "abc"               //10abc  数字10转换为字符串
"7" * "5"                  //35    JS将乘号左右转換为数字
var b=1-"x"              //NaN   字符串x无法转换为数字
b+"aaa"                  //NaNaaa    JS将NaN转換为字符串
2.6 转换和相等性
     JS可以做灵活的类型转换,“==”相等运算符也灵活多变
null == undefined               //true
"0"==0                         //true
0 == false                     //true
"0" == false                   //true

2.7 显式类型转换
    JS可以自动做类型转换,但有些时候还是需要程序员做制定的显未转换
Number("3")         // 3
String(false)       //  "false"
Boolean([])         //  true 空对象{}和空数组[]在JS中都会转换成true
Object(3)           // new Number(3) 
2.8 对象转换为原始值
    对象=>布尔
            对象到布尔值所有的转换都是true

    对象=>字符串
           转换时系统会调用对象的toString()方法,有则返回原始值,没有或不返回原始值,那么JS会调用valueOf()方法。如果这个方法有就调用它返回原始值,将返回值返回字符串型。如果JS无法从toString()或valueOf()获得一个原始值,此时它会抛出一个类型异常错误。
   
    对象=>数值
            如果对像具有valueOf()方法,会返回一个原始值,JS将这个原始值转换为数字返回这个数字。如果对象具有toString()方法,则返回原始值,JS将期转换并返回。

2.9 变量声明
    在JS程序中,使用一个变量时应当先声明。声名变量关键字var
    如下所示:
var i;
var iSum;
var i,iSum;
var i=1,j=0,k=0;
注:如果未在var声明语句中给变量定初始值,那么虽然声明了这个变量,但在给它存入值之前,调用它时他的值是undefined

3.0  变量作用域
     一个变量的作用域是程序源代码中定义这个变量的区域。全局变量拥有全局作用域,而在函数体内定义的变量,作用域只能在函数内,是局部性的。函数参数也是局部变量它们在函数体内有定义。
例1:函数体内,局部变量的优先级高于同名的全局变量。如果在函数内声明或者参数中带有变量和全局变量名重名,那么全局变量就被局部变量所遮盖。
var a="global";            //声明一个全局变量
function fun(){            // 定义一个fun函数
     var a="local";        //声明一个局部变量a
     return a;             //此时a返回的是"local"
}
fun();                     // "local"
例2:在全局作用域声明全局变量时可以不写var,但在局部声明变量时必须使用var语句。如果函数体内不使用var声明一个
a="global";               //声明一个全局变量
function fun(){           //定义一个fun函数
    a="local";            //函数体内声明了一个全局变量
    return a;             //返回local
}
fun();                    //调用函数
a                         //此时全局变量被函数体内的a变量替换成”local"
例3:函数定义是可以嵌套的。由于每个函数都有它自己的做用域,因此会出现几个局部作用域嵌套的情况。
var a="global string";                      //声明全局变量
function fun1(){
      var a="local string";                 //声明局部变量
      function fun2(){
            var a="nested string";          //嵌套作用域内的局部变量
            return a;                       //返回当前作用域内的值
      }
     return fun2
}
fun1()                                      //"nested string"


3.1 函数作用域和声明提前
     函数作用域:JS中使用了函数作用域(变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的)
function test(ik){
     var i=0;                             //i在整个函数体内都是有效定义
     if(ik>0){
           var j=0;                       //j在整个函数体内都是有效定义
           for(var k=0;k<10;k++){         //k在整个函数体内都是有效定义
                 console.log(k);          //输出1~9
           }
           console.log(k);                //输出10,k循环到10时跳出循环但此时k的值是10
     }
     console.log(j);                      //j在定义时赋值0此时也为0
}
     JS的函数作用域是指在函数内声明的所有变量在函数体内始终是可见的。这就意味着变量在声明之前甚至已经可以使用。JS这个特性被非正式的称为声明提前,也就是JS函数里声明的所有变量(不涉及赋值)都被“提前”至函数体的顶部:
例:
var aa="global";           //定义一个全局变量
function f(){              //定义一个函数
      console.log(aa);     //打印变量aa,此时aa没有被定义结果为undefined
      var aa="local";      //声名局部变量aa,此时局部变量aa,替换全局变量aa的值
      console.log(aa);     //打印aa值
}
f();                       //输出 undefined local
分析:
大家可能会误以为函数中的第一个会输出全局变量的“global”,因为代码还没有执行到var语句声明的局部变量的地方。其实不是,由于函数作用域的特性,局部变量在整个函数体始终是有定义的,也就是说,在函数体内局部变量遮盖了同名全局变量。只有在程序执行到var语句的时候,局部变量才会被真正赋值。因此,上面的过程等价于:将函数内的变量声明“提前”到函数体顶部,同时变量初始化留在原来的位置不变:
function f(){
    var aa;               //在函数体内相当于提前到函数顶部声明变量
    console.log(aa);     //在函数顶部声明了变量但还没有赋值,所以输出undefined
    aa="local";          //此时变量赋值初始化
    console.log(aa);     //输出初始化后的值“local”
}

标签: JavaScript笔记