js基础--算术运算,日期时间,正则表达式和全局对象

 

  • JavaScript中的算术运算

JavaScript程序是使用语言本身提供的算术运算符来进行数字运算的。这些运算符包括加法运算符(+)、减法运算符(-)、乘法运算符(*)、除法运算符(/)和求余(求整除后的余数)运算符(%)。

除了基本的运算符外,JavaScript还支持更加复杂的算术运算,这些复杂运算通过作为Math对象的属性定义的函数和常量来实现:

Math.pow(2,53)//=>9007199254740992:2的53次幂

Math.round(.6)//=>1.0:四舍五入

Math.ceil(.6)//=>1.0:向上求整

Math.floor(.6)//=>0.0:向下求整

Math.abs(-5)//=>5:求绝对值

Math.max(x,y,z)//返回最大值

Math.min(x,y,z)//返回最小值

Math.random()//生成一个大于等于0小于1.0的伪随机数

Math.PI//π:圆周率

Math.E//e:自然对数的底数

Math.sqrt(3)//3的平方根

Math.pow(3,1/3)//3的立方根

Math.sin(0)//三角函数:还有Math.cos,Math.atan等

Math.log(10)//10的自然对数

Math.log(100)/Math.LN10//以10为底100的对数

Math.log(512)/Math.LN2//以2为底512的对数

Math.exp(3)//e的三次幂

 

  • 日期和时间

JavaScript语言核心包括Date()构造函数,用来创建表示日期和时间的对象。这些日期对象的方法为日期计算提供了简单的API。日期对象不像数字那样是基本数据类型。本节给出了使用日期对象的一个简单教程。在第三部分可以查阅更多细节:

var then=new Date(2011,0,1);//2011年1月1日

var later=new Date(2011,0,1,17,10,30);//同一天,当地时间5:10:30pm,

var now=new Date();//当前日期和时间

var elapsed=now-then;//日期减法:计算时间间隔的毫秒数

later.getFullYear()//=>2011

later.getMonth()//=>0:从0开始计数的月份

later.getDate()//=>1:从1开始计数的天数

later.getDay()//=>5:得到星期几,0代表星期日,5代表星期一

later.getHours()//=>当地时间17:5pm

later.getUTCHours()//使用UTC表示小时的时间,基于时区
  • 字符串的使用

JavaScript的内置功能之一就是字符串连接。如果将加号(+)运算符用于数字,表示两数相加。但将它作用于字符串,则表示字符串连接,将第二个字符串拼接在第一个之后,例如:
msg="Hello,"+"world";//生成字符串"Hello,world"
greeting="Welcome to my blog,"+""+name;
要确定一个字符串的长度——其所包含的16位值的个数——可以使用字符串的length属性。比如,要得到字符串s的长度:

s.length

除了length属性,字符串还提供许多可以调用的方法:
var s="hello,world"//定义一个字符串

s.charAt(0)//=>"h":第一个字符

s.charAt(s.length-1)//=>"d":最后一个字符

s.substring(1,4)//=>"ell":第2~4个字符

s.slice(1,4)//=>"ell":同上

s.slice(-3)//=>"rld":最后三个字符

s.indexOf("l")//=>2:字符l首次出现的位置

s.lastIndexOf("l")//=>10:字符l最后一次出现的位置

s.indexOf("l",3)//=>3:在位置3及之后首次出现字符l的位置

s.split(",")//=>["hello","world"]分割成子串

s.replace("h","H")//=>"Hello,world":全文字符替换

s.toUpperCase()//=>"HELLO,WORLD"
记住,在JavaScript中字符串是固定不变的,类似replace()和toUpperCase()的方法都返回新字符串,原字符串本身并没有发生改变。

在ECMAScript 5中,字符串可以当做只读数组,除了使用charAt()方法,也可以使用方括号来访问字符串中的单个字符(16位值):
s="hello,world";

s[0]//=>"h"

s[s.length-1]//=>"d"
 
  • 模式匹配(正则表达式)

JavaScript定义了RegExp()构造函数,用来创建表示文本匹配模式的对象。这些模式称为“正则表达式”(regular expression),JavaScript采用Perl中的正则表达式语法。String和RegExp对象均定义了利用正则表达式进行模式匹配和查找与替换的函数。

RegExp并不是JavaScript的基本类型。和Date一样,它只是一种具有实用API的特殊对象。正则表达式的语法很复杂,API也很丰富。RgeExp是一种强大和常用的文本处理工具。

尽管RegExp并不是语言中的基本数据类型,但是它们依然具有直接量写法,可以直接在JavaScript程序中使用。在两条斜线之间的文本构成了一个正则表达式直接量。第二条斜线之后也可以跟随一个或多个字母,用来修饰匹配模式的含义,例如:
/^HTML///匹配以HTML开始的字符串

/[1-9][0-9]*///匹配一个非零数字,后面是任意个数字

/\bjavascript\b/i//匹配单词"javascript",忽略大小写
RegExp对象定义了很多有用的方法,字符串同样具有可以接收RegExp参数的方法,例如:
var text="testing:1,2,3";//文本示例

var pattern=/\d+/g//匹配所有包含一个或多个数字的实例

pattern.test(text)//=>true:匹配成功

text.search(pattern)//=>9:首次匹配成功的位置

text.match(pattern)//=>["1","2","3"]:所有匹配组成的数组

text.replace(pattern,"#");//=>"testing:#,#,#"

text.split(/\D+/);//=>["","1","2","3"]:用非数字字符截取字符串
  • 全局对象

全局对象(global object)在JavaScript中有着重要的用途:全局对象的属性是全局定义的符号,JavaScript程序可以直接使用。当JavaScript解释器启动时(或者任何Web浏览器加载新页面的时候),它将创建一个新的全局对象,并给它一组定义的初始属性:

·全局属性,比如undefined、Infinity和NaN。

·全局函数,比如isNaN()、parseInt()和eval()

·构造函数,比如Date()、RegExp()、String()、Object()和Array()

·全局对象,比如Math和JSON

全局对象的初始属性并不是保留字,但它们应该当做保留字来对待。

在代码的最顶级——不在任何函数内的JavaScript代码——可以使用JavaScript关键字this来引用全局对象:

var global=this;//定义一个引用全局对象的全局变量

在客户端JavaScript中,在其表示的浏览器窗口中的所有JavaScript代码中,Window对象充当了全局对象。这个全局Window对象有一个属性window引用其自身,它可以代替this来引用全局对象。Window对象定义了核心全局属性,但它也针对Web浏览器和客户端JavaScript定义了一少部分其他全局属性。

当初次创建的时候,全局对象定义了JavaScript中所有的预定义全局值。这个特殊对象同样包含了为程序定义的全局值。如果代码声明了一个全局变量,这个全局变量就是全局对象的一个属性。
  • 包装对象

JavaScript对象是一种复合值:它是属性或已命名值的集合。通过“.”符号来引用属性值。当属性值是一个函数的时候,称其为方法。通过o.m()来调用对象o中的方法。

我们看到字符串也同样具有属性和方法:

var s="hello world!";//一个字符串

var word=s.substring(s.indexOf("")+1,s.length);//使用字符串的属性


字符串既然不是对象,为什么它会有属性呢?只要引用了字符串s的属性,JavaScript就会将字符串值通过调用new String(s)的方式转换成对象,这个对象继承了字符串的方法,并被用来处理属性的引用。一旦属性引用结束,这个新创建的对象就会销毁(其实在实现上并不一定创建或销毁这个临时对象,然而整个过程看起来是这样)。

同字符串一样,数字和布尔值也具有各自的方法:通过Number()和Boolean()构造函数创建一个临时对象,这些方法的调用均是来自于这个临时对象。null和undefined没有包装对象:访问它们的属性会造成一个类型错误。

看如下代码,思考它们的执行结果:

var s="test";//创建一个字符串

s.len=4;//给它设置一个属性

var t=s.len;//查询这个属性


当运行这段代码时,t的值是undefined。第二行代码创建一个临时字符串对象,并给其len属性赋值为4,随即销毁这个对象。第三行通过原始的(没有被修改过)字符串值创建一个新字符串对象,尝试读取其len属性,这个属性自然不存在,表达式求值结果为undefined。这段代码说明了在读取字符串、数字和布尔值的属性值(或方法)的时候,表现的像对象一样。但如果你试图给其属性赋值,则会忽略这个操作:修改只是发生在临时对象身上,而这个临时对象并未继续保留下来。

存取字符串、数字或布尔值的属性时创建的临时对象称做包装对象,它只是偶尔用来区分字符串值和字符串对象、数字和数值对象以及布尔值和布尔对象。通常,包装对象只是被看做是一种实现细节,而不用特别关注。由于字符串、数字和布尔值的属性都是只读的,并且不能给它们定义新属性,因此你需要明白它们是有别于对象的。

需要注意的是,可通过String(),Number()或Boolean()构造函数来显式创建包装对象:

var s="test",n=1,b=true;//一个字符串、数字和布尔值

var S=new String(s);//一个字符串对象

var N=new Number(n);//一个数值对象

var B=new Boolean(b);//一个布尔对象


JavaScript会在必要时将包装对象转换成原始值,因此上段代码中的对象S、N和B常常——但不总是——表现的和值s、n和b一样。“==”等于运算符将原始值和其包装对象视为相等,但“===”全等运算符将它们视为不等。通过typeof运算符可以看到原始值和其包装对象的不同。

  • 不可变的原始值和可变的对象引用

JavaScript中的原始值(undefined、null、布尔值、数字和字符串)与对象(包括数组和函数)有着根本区别。原始值是不可更改的:任何方法都无法更改(或“突变”)一个原始值。对数字和布尔值来说显然如此——改变数字的值本身就说不通,而对字符串来说就不那么明显了,因为字符串看起来像由字符组成的数组,我们期望可以通过指定索引来修改字符串中的字符。实际上,JavaScript是禁止这样做的。字符串中所有的方法看上去返回了一个修改后的字符串,实际上返回的是一个新的字符串值。例如:
var s="hello";//定义一个由小写字母组成的文本

s.toUpperCase();//返回"HELLO",但并没有改变s的值

s //=>"hello":原始字符串的值并未改变
原始值的比较是值的比较:只有在它们的值相等时它们才相等。这对数字、布尔值、null和undefined来说听起来有点儿难懂,并没有其他办法来比较它们。同样,对于字符串来说则并不明显:如果比较两个单独的字符串,当且仅当它们的长度相等且每个索引的字符都相等时,JavaScript才认为它们相等。

对象和原始值不同,首先,它们是可变的——它们的值是可修改的:
var o={x:1};//定义一个对象

o.x=2;//通过修改对象属性值来更改对象

o.y=3;//再次更改这个对象,给它增加一个新属性

var a=[1,2,3]//数组也是可修改的

a[0]=0;//更改数组的一个元素

a[3]=4;//给数组增加一个新元素
对象的比较并非值的比较:即使两个对象包含同样的属性及相同的值,它们也是不相等的。各个索引元素完全相等的两个数组也不相等。
var o={x:1},p={x:1};//具有相同属性的两个对象

o===p//=>false:两个单独的对象永不相等

var a=[],b=[];//两个单独的空数组

a===b//=>false:两个单独的数组永不相等
我们通常将对象称为引用类型(reference type),以此来和JavaScript的基本类型区分开来。依照术语的叫法,对象值都是引用(reference),对象的比较均是引用的比较:当且仅当它们引用同一个基对象时,它们才相等。
var a=[];//定义一个引用空数组的变量a

var b=a;//变量b引用同一个数组

b[0]=1;//通过变量b来修改引用的数组

a[0]//=>1:变量a也会修改

a===b//=>true:a和b引用同一个数组,因此它们相等
就像你刚看到的如上代码,将对象(或数组)赋值给一个变量,仅仅是赋值的引用值:对象本身并没有复制一次。如果你想得到一个对象或数组的副本,则必须显式复制对象的每个属性或数组的每个元素。下面这个例子则是通过循环来完成数组复制:
var a=['a','b','c'];//待复制的数组

var b=[];//复制到的目标空数组

for(var i=0;i<a.length;i++){//遍历a[]中的每个元素
    b[i]=a[i];//将元素值复制到b中
}
同样的,如果我们想比较两个单独的对象或者数组,则必须比较它们的属性或元素。下面这段代码定义了一个比较两个数组的函数:
function equalArrays(a,b){
    if(a.length!=b.length)return false;//两个长度不同的数组不相等
    for(var i=0;i<a.length;i++)//循环遍历所有元素
    if(a[i]!==b[i])return false;//如果有任意元素不等,则数组不相等
    return true;//否则它们相等
}

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值