【JavaScript语言核心】二、类型、值和变量

2021/7/16 17:05:10

本文主要是介绍【JavaScript语言核心】二、类型、值和变量,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

   本节梗概:

 

  1. 数字
    • JavaScript不区分整数值和浮点数值,所有数字均用浮点数值表示;
    • JavaScript采用IEEE 754标准定义的64位浮点格式表示数字,能表示的最大值是±1.7976931348623157×10308,最小值是±5×10-324
    • JavaScript能表示的整数范围:-253~253(包含边界值),若超出此范围将无法保证低位数字的精度;
    • JavaScript实际的操作是基于32位整数;
    • 程序中直接出现的数字称为数字直接量(numeric literal),有多种形式,如整型直接量3,0xCAFE911;浮点型直接量6.02e23等;
    • 数字直接量前添加负号可以得到其负值,但负号并不是数字直接量语法的组成部分;
    • 基本运算:+、-、*、/、%,复杂运算通过Math对象实现:
       1 Math.pow(2,53)             //2的53次幂
       2 Math.round(.6)              //0.6四舍五入
       3 Math.ceil(.6)                  //0.6向上求整
       4 Math.floor(.6)                //0.6向下求整
       5 Math.abs(-5)                 //-5的绝对值
       6 Math.max(x,y,z)            //返回最大值
       7 Math.min(x,y,z)            //返回最小值
       8 Math.random()             //生成一个大于等于0小于1.0的伪随机数
       9 Math.PI                       //圆周率π
      10 Math.E                        //自然对数的底数e
      11 Math.sqrt(3)                //3的平方根
      12 Math.pow(3,1/3)          //3的立方根
      13 Math.sin()                    //三角函数,还有Math.atan(),Math.cos()等
      14 Math.log(10)               //10的自然对数
      15 Math.log(100)/Math.LN10                  //以10为底100的对数
      16 Math.exp(3)                //e的3次幂

       

    • JavaScript中的数据在数据溢出、被0整除时不会报错,将返回无穷大(±Infinity)、非数字值(NaN)或零(±0);
       1 1.7976931348623157e400              //大于JavaScript所能表示正数的最大值(正上溢),返回无穷大(Infinity)
       2 Infinity
       3 -1.7976931348623157e400              //小于JavaScript所能表示的绝对值最大负数(负上溢),返回负无穷大(-Infinity)
       4 -Infinity
       5 5e-400                              //比JavaScript所能表示的最小正数还小(正下溢),返回0
       6 0
       7 -5e-400                            //比JavaScript所能表示的绝对值最小负数还小(负下溢),返回-0
       8 -0
       9 1/0                               //正数被0整除,返回无穷大(Infinity)
      10 Infinity
      11 -1/0                              //负数被0整除,返回负无穷大(-Infinity)
      12 -Infinity
      13 0/0                              //0除以0,没有意义,将返回非数字值(Not-a-Number,NaN)
      14 NaN
    • 关于NaN和±0
      • NaN和任何值都不相等,包括它本身;
        1 /*相关函数:
        2         isNaN()
        3         isFinite()*/
        4 
        5 
        6 isNaN("js")             //参数是一个非数字值时返回true
        7 true
        8 isFinite(3)            //在参数不是NaN、Infinity、-Infinity时返回true
        9 true 
      • 正零和负零几乎一摸一样,除了作为除数之外;
    • 实数有无数多个,但JavaScript只能表示其中的有限多个(18437736874454810627个);
    • JavaScript是使用二进制浮点数的编程语言,并不能精确地表示类似于0.1这样的数字,这将带来一些问题:
      1 0.3-0.2                                                //0.3-0.2并不等于0.1
      2 0.09999999999999998
    • 时间和日期(更多详情请看后续的博客)
      • Date()构造函数用来创建表示日期和时间的对象,下面是一个简单的例子:   
  2. 文本
    • JavaScript通过字符串来表示文本,并没有表示单个字符的“字符型”;
    • JavaScript字符串是一组无符号的16位值组成的不可变的有序序列,索引从0开始,长度是其所含16位值的个数,空字符串长度为0;
    • JavaScript使用UTF-16编码的Unicode字符集,常用的Unicode字符使用16位的内码表示,代表字符串中的单个字符,那些不能表示为16位的Unicode字符使用两个16位值组成的序列(称为“代理项对”)表示,如字符"e"通过UTF-16编码后包含两个16位值:\ud835\udc52,其字符串长度为2;
    • 各种字符串操作方法均作用于16位值,而非单个字符,且不会对代理项对作单独处理;
    • 字符串直接量
      • 由单/双引号界定,需注意单/双引号的包含;
      • ES3中,字符串直接量必须写在一行;ES5中可拆分为数行,每行必须以反斜杠(\)结束;
      • 若希望在字符串直接量中另起一行,可使用转义字符\n;
      • 在单引号和所有格符号同时出现时,必须使用反斜杠(\)来转义所有的撇号;
      • JavaScript代码和HTML代码相互混杂时,建议对两者使用不同的引号风格加以区分;
    • 转义字符
      • 也称转义序列(escape)、逃逸符;
      • JavaScript转义字符:
        JavaScript转义字符
        转义字符 含义
        \o NUL字符(\u0000)
        \b 退格符(\u0008)
        \t 水平制表符(\u0009)
        \n 换行符(\u000A)
        \v 垂直制表符(\u000B)
        \f 换页符(\u000C)
        \r 回车符(\u000D)
        \" 双引号(\u0022)
        \' 撇号或单引号(\u0027)
        \\ 反斜杠(\u005C)
        \xXX 由两位16进制数XX指定的Latin-1字符
        \uXXXX 由四位16进制数XXXX指定的Unicode字符
          
    • 字符串的使用
      • “+”用于连接两个字符串;
      • length属性可得到字符串的长度;
      • 其他方法:
         1 var s = "hello world"           //定义一个字符串
         2 undefined
         3 s.charAt(1)                     //取索引为1的字符
         4 "e"
         5 s.charAt(s.length-1)           //取最后一个字符
         6 "d"
         7 s.substring(1,4)                //取索引为1~3的字符
         8 "ell"
         9 s.slice(1,4)                    //取索引为1~3的字符
        10 "ell"
        11 s.slice(-3)                    //取最后3个字符
        12 "rld"
        13 s.indexOf("l")                 //字符“l”首次出现的索引位置
        14 2
        15 s.lastIndexOf("l")             //字符“l”最后一次出现的索引位置
        16 9
        17 s.indexOf("l",3)             //求在位置3及之后首次出现“l”的位置
        18 3
        19 s.split(",")                 //使用“,”分割成子串
        20 s.replace("h","H")              //全文字符替换
        21 "Hello world"
        22 s.toUpperCase()                 //全文字符大写
        23 "HELLO WORLD"

         

      • JavaScript中字符串是固定不变的,类似replace()和toUpperCase()方法返回的是新字符串,原字符串并未改变;
      • 除了使用charAt()方法,在ES5中还可使用方括号("[]")来访问字符串中的字符;
    • 模式匹配
      • RegExp()构造函数用于创建表示文本匹配模式的对象,这些模式称为“正则表达式”(regular expression);
      • JavaScript采用的是Perl中的正则表达式语法,并为RegExp对象和String对象定义了利用正则表达式进行模式匹配和查找替换的函数;
      • RegEXp虽不是JavaScript的基本类型,但仍有直接量写法:两条斜杠之间的文本构成正则表达式的直接量(第二条斜杠后可跟一个或多个字母用于修饰匹配模式的含义)
        1 /^HTML/                               //匹配以HTML开始的字符串
        2 /[1-9][0-9]*/                          //匹配一个非0数字,后面是任意个数字
        3 /\bjavascript\b/i                    //匹配单词"javascript",忽略大小写
    •   
  3. 布尔值
    • 布尔值指代真或假、开或关、是或否,有true和false两个值,通常用于控制结构中;
    • 任意JavaScript值都可转换为布尔值,以下值会被转换为false:undefined、null、0、-0、NaN、“”(空字符串);
    • toString()可将字符串转换为true或false;
    • &&(与)、||(或)、!(非);
  4. null和undefined
    • 两者都是其自有类型的唯一成员,都表示“值的空缺”,都不包含任何属性和方法,相等运算符("==")认为二者是相等的,严格相等运算符("===")认为二者是不等的;
    • undefined是预定义的全局变量,null是JavaScript的关键字,可将null认为是一种特殊的对象值;
    • null(或nil)表示“无值”,undefined表示“未定义”、“不存在”或“未初始化”;
    • 若想将“空缺”赋值给变量或属性,或作为参数传入函数,建议使用null;
  5. 全局对象
    • 不在任何函数内的JavaScript代码,可以使用this关键字来引用全局对象
    • 客户端JavaScript中,Windows对象充当全局对象,属性window引用其自身,可以代替this来引用全局对象
  6. 包装对象
    • 对象是属性或命名值的集合,对象中的函数称为方法;
    • 字符串不是JavaScript对象 ,但当引用其属性时,JavaScript会将字符串值通过new String()方式转换为对象,这个对象继承了字符串的方法,被用来处理属性的引用,一旦属性引用结束,这个新创建的对象就会被销毁,这个创建的临时对象称为包装对象。数字和布尔值也有这种实现细节;
    • 可通过String()、Number()、Boolean()来显示地创建包装对象:
    • "=="将原始值和包装对象视为相等,"==="将原始值和包装对象视为不等;
    • 通过typeof可看到原始值和包装对象的不同;
  7. 不可变的原始值和可变的对象引用
    • 原始值的比较是值的比较
      • 对于字符串,只有当两个字符串长度相等并且每个索引的字符都相等时才相等
    • 对象的比较是引用的比较:只有当两个对象引用同一个基对象时它们才相等
      • 即使两个对象包含同样的属性及相同的值,它们也是不等的,如各个索引元素完全相等的两个数组并不相等
  8. 类型转换
    • JavaScript会根据需要自行转换数据类型,下表简要说明了类型转换(3.8.3节为对象转换为原始值):
    • 一个值转换为另一个值并不意味着两个值相等;
    • 显示类型转换:使用Boolean()、Number()、String()、Object()函数;
    • 除了null和undefined之外的任何值都有toString()方法,其返回结果和String()一致;
    • 某些运算符会做隐式的类型转换:如"+"、"!"等
      1 x + ""                 //等价于String(x)
      2 + x                        //等价于Number(x)
      3 !! x                           //等价于Boolean(x)

       

    • Number类的几个关于类型转换的方法:
      • toString()方法可接收表示转换基数(radix)的一个可选参数,可将数字转换为其他进制数(2~36),若不指定该参数,默认转换为十进制;
      • toFixed()根据小数点后指定的位数将数字转换为字符串;
      • toExponential()将数字转换为科学计数法形式的字符串,小数位数由参数指定,小数点前只有一位;
      • toPrecision()根据指定的有效数字位数将数字转换为字符串,若有效数字位数少于数字整数部分的位数将转换为指数形式;
    • 使用Number()转换字符串时,将字符串转换为一个整数或浮点数直接量(十进制),parseInt()将字符串转换为整数(第二个参数可指定转换的基数,取值为2~36),parseFloat()将字符串转换为整数或浮点数,两者都会忽略空格,若第一个非空格字符是非法的数字直接量,将返回NaN;
    • 对象到布尔值的转换:所有对象(包括数组和函数)都转换为true;
    • 对象到字符串、数字的转换一般是通过调用待转换对象的方法实现的(toString()和valueOf()),转换规则只适用于本地对象(native object),宿主对象(由Web浏览器定义的对象)将根据各自的算法进行转换;
    • 所有对象都继承了两个转换方法:toString()和valueOf()
      • toString()返回一个反映这个对象的字符串
        • 对于数组类:将每个数组元素转换为一个字符串,并在元素间添加逗号合并成结果字符串;
        • 对于函数类:转换为源代码字符串;
        • 对于日期类:转换为一个可被JavaScript解析的日期和时间字符串;
        • 对于RegExp类:转换为表示正则表达式直接量的字符串;
      • valueOf()
        • 返回原始值:对象存在任意原始值;
        • 返回对象本身(默认):对象是复合值,大多数无法表示为一个原始值,如数组、函数、正则表达式;
        • 日期类定义的valueOf()将返回对象的一个内部表示:1970年1月1日以来的毫秒数;
    • 对象到字符串的转换过程:
    • 对象到数字的转换过程:
    • 对象转换为原始值
      • 对于非日期对象:对象到原始值的转换基本上是对象到数字的转换;
      • 对于日期对象:对象转换为字符串(toString()或valueOf()返回的原始值被直接使用);
    • 任何对象都会首先尝试调用valueOf(),然后调用toString();
    • ……
  9. 变量声明
    • 变量先声明后使用;
    • JavaScript中使用var关键字声明变量,可在声明的同时给变量赋初始值;
    • JavaScript变量可以是任意数据类型,例如:
      1 /*先给变量f一个数字类型的值,再给一个字符串类型的值,是完全合法的 */
      2 var i = 3;
      3 i = "javascript"

       

    • 静态语言与动态语言
      • 动态语言
        • 在运行期间才去作数据类型的检查,典型代表:JavaScript、Python、Ruby;
      • 静态语言
        • 在编译期间检查数据类型,写程序时要声明变量的数据类型,典型代表:C/C++、C#、Java;
    • JavaScript重复声明变量合法且无害,未声明就赋值或读取会报错,应当始终先使用var来声明变量;
  10. 变量作用域
    • 变量作用域是指程序源代码中定义变量的区域;
    • 全局变量在JavaScript代码中的任何地方都有定义,局部变量的作用域是局部性的;
    • 函数内定义的局部变量或函数参数中的变量与全局变量重名时,全局变量会被遮盖;
    • 声明全局变量可以不写var关键字,但声明局部变量时必须使用var关键字声明;
    • 块级作用域(block scope):类似于C语言中花括号内的作用域,其中的变量在外面不可见;
    • 函数作用域(function scope):JavaScript没有块级作用域,取代为函数作用域:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内始终都有定义;
    • 声明提前(hoisting):函数作用域意味着函数体中的变量在定义之前已经可用,即JavaScript函数中声明的所有变量(不涉及赋值)都被提前至函数体顶部;
       1 var scope = "global";
       2 function f(){
       3   console.log(scope);
       4   var scope = "local";
       5   console.log(scope);          
       6 }
       7 
       8 
       9 /*以上代码等价于*/
      10 function f(){
      11   var scope;                            //在函数顶部声明了局部变量
      12   console.log(scope);                  //变量存在,其值是"undefined"
      13   scope="local";                     //初始化并赋值
      14   console.log(scope);        
      15 }

       

    • 声明一个全局变量时,实际是定义了一个全局对象的的一个属性,可使用this关键字引用全局对象,局部对象可当作根函数调用相关的某个属性,ES3称该对象为“调用对象”(call object),ES5则称“声明上下文对象”(declarative environment record);
    • 使用var声明的变量无法通过delete运算符删除(称这个属性是不可配置的),给一个未声明的变量赋值,JavaScript会自动创建一个全局变量,这种变量是可配置的;
       1 var a = 1;
       2 undefined
       3 delete a;
       4 false
       5 b = 2;
       6 2
       7 delete b;
       8 true
       9 this.c = 3;
      10 3
      11 delete c;
      12 true

       

    • JavaScript是基于词法作用域的语言:通过阅读包含变量定义在内的数行源码就能直到变量的作用域;
    • 作用域链(scope chain):每一段JavaScript代码都有一个与之相关的作用域链,这个作用域链是一个对象列表或链表,定义了这段代码“作用域中”的变量,当需要查找变量x(“变量解析”(variable resolution))时,会从第一个对象开始逐个地查找属性x,若任何一个对象都没有属性x,认为这段代码的作用域链上不存在x,并最终会抛出一个引用错误(ReferenceError)异常;
      • 在不包含于任何函数定义内的代码,作用域链由1个全局对象组成;
      • 在不包含嵌套的函数体内,作用域由2个对象组成:一个是定义函数参数和局部变量的对象,一个是全局对象;
      • 在一个嵌套的函数体内,作用域上至少由3个对象组成;
    • 定义一个函数时,实际是保存一个变量作用域链,调用一个函数时,会创建一个新的对象来存储它的局部变量,并将其添加到保存的作用链上,同时创建一个新的更长的表示函数调用作用域的“链”,内部函数在每次调用外部函数时作用域链都是不一样的,每次调用时都会重新定义一遍;


这篇关于【JavaScript语言核心】二、类型、值和变量的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程