JavaScript由浅入深(一)——类型、值和变量

    JavaScript是一门面向web的、高端的、动态的、弱类型的编程语言,是学习web前端开发必备的基础技能之一。JavaScript最初是一门脚本语言(scripting-language),它的语法源自Java注1,它的一等函数(first-class function)来自Scheme注2,它的基于原型(protopy-based)的继承来自于Self注3,但JavaScript已经超出了其“脚本语言”本身的范畴,而成为了一种集健壮性、高效性和通用性为一身的编程语言。下面我就按照自己的学习过程,来给大家分享一些我学到的知识。因为全部是自己总结和手打的,有纰漏错误之处请留言,谢谢。

一:类型

(1)数字(Number)

  Javascript与其他编程语言不同,它不区分整数值和浮点数值,所有的数字都用浮点数值表示。JavaScript采用IEEE754标准注4定义的      64位浮点格式表示数字,他能够表示的数字范围是从-9007199254740992~9007199254740992(即-253~253),包含边界。

  1.1 整型直接量:JavaScript程序中,用一个数字序列表示一个十进制整数,用“0x”或“0X”为前缀,其后跟随十六进制数串的直接量,javaScript某些实现可以允许八进制(基数为8)形式表示整数,但在ECMAScript 6的严格模式下,八进制直接量是明令禁止的。

eg:下面直接在控制台中判断十进制和十六进制的形式,ff转换十进制是255,下面是写法

0xff == 255  //判断十进制255与十六进制0xff是否相等
ture //输出为ture

  1.2 浮点型直接量:浮点型直接量可以含有小数点,采用传统的实数写法。还可以使用指数记数法表示浮点型直接量,即在实属后跟字母e或者E,,后面在跟正负号,其后在加一个整型的指数,这种是表示由前面的实数乘以10的指数次幂。

eg:下面用两种方式表示同一浮点数(左边的是实数写法,右边是指数记数法)

1023 == 1.023e3 //返回true
3.14 == 3.14e0   //返回true
0.0001 == 1e-4  //返回true

  1.3 算数运算:JavaScript使用算术运算符来进行数字运算,包括+、-、*、/、%等,这里需要注意的是二进制浮点数和四合五入错误

var x = 0.3 - 0.2;
var y = 0.2 - 0.1;
x == y;                 // =>false:两值不相等!
x == 0.1;              // =>false: 0.3-0.2 不等于0.1
y == 0.1;         // =>true: 0.2-0.1 等于0.1

由于四舍五入的误差,0.3和0.2之间的近似值实际上并不等于0.2与0.1之间的近似差值。任何使用二进制浮点数的编程语言都会有这个问题。

  1.2 数学函数::JavaScript支持更复杂的算术运算,复杂运算通过作为Math对象的属性定义的函数和常量实现:

console.log(Math.pow(2,53));   //=> 9007199254740992 :2的53次幂
console.log(Math.round(0.6));  //=> 1 :四舍五入
console.log(Math.ceil(0.6));  //=> 1 :向上求整
console.log(Math.floor(0.6));  //=> 0 :向下求整
console.log(Math.abs(-5));  //=> 5 :求绝对值
console.log(Math.max(2,5,1));  //=> 5 :返回最大值
console.log(Math.min(2,5,1));  //=> 1 :返回最小值
console.log(Math.random());  // 返回一个大于等于0小于等于1的伪随机数
console.log(Math.PI);  //=> 3.141592653589793 :圆周率
console.log(Math.E);  //=> 2.718281828459045 :自然对数的底数
console.log(Math.sqrt(3));  // 3的平方根
console.log(Math.pow(3,1/3));  // 3的立方根
console.log(Math.sin(0));  //  三角函数:还有Math.cos ,Math.atan等
console.log(Math.log(10));  // 10的自然对数
console.log(Math.log(100)/Math.LN10);  //=> 2:以10为底100的对数
console.log(Math.exp(3));  // e的三次幂

 (2)文本

  JavaScript通过字符串类型来表示文本。字符串(string)是一组由16位值组成的不可变的有序序列,每个字符串通常来自于Unicode字符集。字符串的长度(length)是其所含16位值的个数,字符串的索引从0开始

  2.1 字符串直接量:在JavaScript程序中的字符串直接量,是由单引号或双引号括起来的字符序列。

""           //空字符串 :它包含0个字符串
'testing'
'3.14'

  2.2 转义字符:在JavaScript字符串中,反斜线()符号后面加一个字符,就不再表示他们字面的意思了,比如, 就是一个转义字符,它表示一个换行符。

  2.3 字符串的操作 :JavaScript内置了许多字符串操作的功能。 

下面介绍一些常用的操作

 1         var s = "hello,world";     // 定义一个字符串
 2         console.log(s.length);     // =>11 字符串的长度
 3         console.log(s.charAt(0));  // =>"h" 第一个字符
 4         console.log(s.charAt(s.length-1));  // =>"d" 最后一个字符
 5         console.log(s.substring(1,4));  // =>"ell" 第2-4个字符,从开始位置到结束位置,但不包括结束位置
 6         console.log(s.slice(1,4));  // =>"ell" 第2-4个字符,与substring的区别是,slice可支持负数下标,表示从结尾部分算位置
 7         console.log(s.slice(-3));  // =>"rld" 最后三个字符
 8         console.log(s.indexOf("l"));  // =>2 :字符串l第一次出现的位置
 9         console.log(s.lastIndexOf("l"));  // =>10 :字符串l最后一次出现的位置
10         console.log(s.slice(","));  // => ["hello","world"] 以","将字符串分隔成字串
11         console.log(s.replace("h","H"));  // =>"Hello,world": 全文字符替换
12         console.log(s.toUpperCase());    // =>HELLO,WORLD: 转换为大写,对应的转为小写用toLowerCase()方法

  2.4 模式匹配:JavaScript定义了RegExp()构造函数,用来创建表示文本匹配模式的对象。这个模式称为“正则表达式”,这里先简单介绍一下,后面会专门整理关于正则的学习总结

  RegExp并不是JavaScript的基本数据类型,但是它具有直接量的写法,可直接在程序中使用。在两条斜线之间的文本构成了一个正则表达式的直接量。

/^HTML/              //匹配以HTML开始的字符串
/[1-9][0-9]/         //匹配一个非零数字,后面是一个任意数字

(3)布尔值

  3.1布尔值(boolean)就是真或假,这个类型只有两个值,保留字true和false。通常比较语句返回的结果就是布尔值:

typeof true; // =>boolean :typeof判断数据类型,返回boolean
a == 4 ;                         // =>false :控制台直接输出false
a =4 ; a==4 ;                // =>先把a等于4,在判断a == 4返回true

(4)null 和 undefined

  4.1 null :JavaScript语言的关键字,它表示一个特殊值,常用来描述“空值”。下面用typeof来判断一下null:

typeof null      // => "object" 

在控制台直接运行发现,返回值为“object”,也就是说可以认为null是一个特殊对象值,含义是“非对象”。通常认为null是它自有类型的唯一一个成员,表示数字,字符串和对象是“无值”

  4.2 undefined:用来表示更深层的“空值”,是变量的一种取值,表明变量没有初始化。

     几种返回undefined的情况:①:查询的对象属性或数组元素不存在时,便返回undefined,说明这个元素或属性不存在。

                  ②:如果函数没有任何的返回值也返回undefined

                    ③:引用没有提供的实参的函数形参的值也是的得到undefined

  4.3 区别 :null和undefined尽管都是表示“值的空缺”,但是两者是不同的,可以理解为undefined是表示系统级别的、出乎意料的或者类似错误的值的空缺,而null是表示程序级的、正常的或在意料之中的值的空缺。举个例子来说,在跑程序的过程中,在控制台中我遇到的好多都是undefined的报错,而没有null报错。

undefined == null   // => true :控制台输出为true,判断相等运算时,认为二者是相等的
undefined === null // => false:输出为false ,二者区分要用“===”区分

(5)对象

关于对象,这里先不做描述,之后会专门描述

二、类型转换

JavaScript是弱类型的语言,它会根据需要自行转换类型,如下有一些例子

1 10 + “ object”;      // => "10 object" :数字10转换成字符串
2 "7" * "4";                // => 28 :两个字符串转换成数字
3 var n = 1- "x";        // => NaN :字符串"x"无法转换成数字
4 NaN + "object";      // => "NaNobject" :NaN转换成字符串

简单数值转换表

转换为:字符串 数字 布尔值
 undefined “undefined”   NaN false 
null "null" 0 false
true "true" 1 true
false "false" 0 false
""(空字符串)   0 false
"one"(非空字符串)   NaN true
0 "0"   false
NaN "NaN"   false

(1)显式类型转换

JavaScript显示类型转换最简单的方法就是使用 Boolean()、Number()、String()或Object()函数。 

Number("3") ;         // =>3
String(false);          // =>"false" 或使用false.toString()
Boolean([]);           // =>true
Object(3);              // =>Number {[[PrimitiveValue]]: 3}即 new Number(3)

 需要注意的是:试图把null或undefined转化成对象,会抛出类型错误(TypeError)。Object在这种情况下不会抛出异常,会返回一个空对象

(2)转换和相等性

JavaScript有灵活的类型转换,但是注意一个值转换成另外一个值并不意味着两个值相等。

null == undefined       //这两个值被认为相等
"0" == 0                //在比较之前字符串转换成数字
0 == false              //在比较之前布尔值转换成数字
"0" == false            //在比较之前字符串和布尔值都转换成了数字

"=="等于运算符在判断两个值是否相等时做了类型转换,如果需要真正判断是否相等需要使用"==="恒等运算。

三、变量声明

在JavaScript中,使用一个变量前需要使用关键字var声明。可同时声明多个变量并同时赋值。若在声明的时候未给变量赋值,那么这个变量在赋值之前,它的初始值是undefined。

var i=0,j=4;     //声明多个变量并赋值
var a;              //声明了一个变量未赋值,在存入一个值之前初始值是undefined

(1)变量的作用域

变量的作用域(scope)是程序源代码中定义这个变量的区域。

 1.1 全局变量和局部变量

全局变量:拥有全局作用域,在JavaScript中的任何地方都有定义;

局部变量:只有在函数体内有定义的

var a = "global";      //声明一个全局变量
function fun(){
   var a = "local";     //声明一个同名的局部变量
  return  a;             //函数返回局部变量的值,而不是全局变量的值
}
console.log(a);        // => "global" 全局变量的值在全局作用下依旧是"global"
console.log(fun());   // => "local"   函数返回了局部变量的值,在函数中覆盖了全局变量的值      

(2)函数作用域和声明提前

函数作用域(functions scope):变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。

下面例子中,在函数test的不同位置定义了变量i,j,k,他们都处于同一个作用域内,均在函数体内有定义

 1 (function(){
 2     function test(){
 3         var i = 0;        // i 在整个函数体内均是有定义的
 4         if(i == 0){
 5             var j = 1;    // j 在函数体内是有定义的,不仅仅是在这个代码内
 6             for(var k=0;k<10;k++){  //k 在函数体内是有定义的,不仅仅是在这个代码内
 7                 console.log(k);     //输出数字0-9
 8             }
 9             console.log(k);          //k 已经被定义,输出10
10         }
11         console.log(j);        //j 已经定义了,输出1;
12     }
13     test();
14     console.log(j);         //在函数体外调用 报错 j is not undefined;
15 })()

声明提前:将变量声明放在函数体的顶部,能清晰的显示出变量的作用域

注1:是一种可以撰写跨平台应用程序的面向对象的程序设计语言。

注2:Scheme 编程语言是一种Lisp方言,诞生于1975年,由 MIT 的 Gerald J. Sussman 和 Guy L. Steele Jr. 完成。它是现代两大Lisp方言之一;另一个方言是Common Lisp。

注3:self相当于C++中的this指针,它也是用于指向当前对象的一个指针。

注4:Java程序猿应该很熟悉这种格式,就像他们熟悉双精度(dobule)类型一样。在C和C++的所有现代实现中也都用到了双精度类型。

本文主要内容主要是笔者结合JavaScript权威指南总结写出,纯手打,所以如有笔误之处,还请提出,谢谢。

原文地址:https://www.cnblogs.com/plum-yang/p/5517476.html