javascript 标准参考


原文链接: javascript 标准参考

JavaScript 标准参考教程-阮一峰

操作符

布尔操作符

逻辑非

逻辑非操作符用叹号表示

可以应用于任何数据类型,逻辑非操作符首先会把操作数转换为布尔值,然后再求反。

如果操作数为空字符串、0、null、NaN、undefined,返回true。

!!variable 的结果与Boolean(variable)相同。

逻辑与

逻辑或

var myObject=preferredObject||backupObject

条件操作符

variable=bool_expression?true_value:false_value;

基于对bool_expression求值的结果,决定给变量variable赋什么值。如果值为true,则赋值为true_value,否则赋值为false_value。

逗号操作符

可以在一条语句中执行多个操作,例如:

var num1=1,num2=2,num3=3;

语句

if 语句

if (i>25){
	console.log('25')
}else if(i>30){
	console.log('30')
}else{
	console.log('40')
}

ECMAScript 会自动调用Boolean()转换函数将条件表达式的结果转换为布尔值

do-while 语句

do{
	console.log('do')
}while(expression)

while 语

while(expression)
	statement

for 语句

for(initialization;expression;post-loop-expression)
	statement

由于ECMAScript中不存在块级作用域,所以在循环内部定义的变量在外部也可以访问到。

for 语句中的初始化表达式,控制表达式和循环后表达式都是可选的。

for-in 语句

for-in 语句可以用来枚举对象的属性。

for (property in expression)
	statement

ECMAScript 对象的属性是没有顺序的,所以for-in语句循环的属性的顺序是不可预测的。

建议在使用for-in之前,先检查对象的值是否是null或是undefined。

break 和 continue 语句

break语句会立即退出循环,强制继续执行循环后面的语句。
continue语句也是立即退出循环,但是退出之后会从循环的顶部继续执行。

switch 语句

switch(expression){
	case value:
		statement;
		break;
	case value:
		statement;
		break;
	default:
		statement;
}

每一个case的含义是,如果表达式的值等于这个值value,则执行后面的statement。break会跳出switch语句。表达式不匹配任何一种情形时会执行default语句。

可以在switch语句中使用任何数据类型。每个case 的值不一定是常量,可以是变量,也可以是表达式。

switch语句在比较时使用的是全等操作符,不会发生类型转换。

函数

return语句之后的任何代码永远都不会执行。return语句也可以不带有任何返回值,在这种情况下,函数在停止执行后将返回undefined。

ECMAScript 中的所有参数传递的都是值,不可能通过引用传递参数。

变量、作用域和内存问题

变量

变量可以用来保存两种类型的值:

  • 基本类型:Undefined、Null、Boolean、Number和String
  • 引用类型:

基本类型值在内存中占用固定大小的空间,因此被保存在栈内存中;
引用类型的值是对象,因此保存在堆内存中;
当变量的值为引用类型时,它保存的实际上并不是对象本身,而是一个指向该对象的指针;
从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象;

作用域

所有变量(包括基本类型和引用类型)都存在与一个执行环境(或者称为作用域)当中。执行环境决定了变量的生命周期,以及那些代码可以访问其中的变量。

执行环境分为全局执行环境和函数执行环境。

根据ECMAScript实现所在的诉诸环境不同,全局执行环境对象也不一样。在浏览器中,全局执行环境被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。

每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。执行完之后,栈将其环境弹出,把控制权返回给之前的执行环境。

每个执行环境都有一个与之关联的变量对象。环境中定义的所有变量和函数都会保存到这个对象中。但我们的代码无法访问这个对象,解析器会用到它。

当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。作用域链的作用是保证对执行环境有权访问的所有变量和函数的有序访问。如果这个环境是函数,则将其活动对象(activition object)作为变量对象。

延长作用域链

有些语句可以在作用域链的前端临时增加一个变量对象

  • try-catch 语句的catch 块
  • with 语句

块级作用域

javascript没有块级作用域。

使用var 声明的变量会自动添加到最接近的环境中。如果没有使用var 声明,该变量会被添加到全局环境。

引用类型

函数传参,最好的方法是对那些必须值使用命名参数,使用对象字面量来封装多个可选参数。

数组

ECMAScript 数组的每一项可以保存任何类型的数据。

数组的length属性不是只读的。因此,通过设置这个属性,可以从数组的末尾移除项或向数组中添加新项。

检测数组

if(value instanceof Array){

}

ECMAScript 5新增Array.isArray()
if(Array.isArray()){
}

转换方法

调用数组的toString()方法会返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串。
而如果使用join()方法,则可以使用不同的分隔符来构建这个字符串。join()接收一个参数,即分隔符,如果省略,默认用逗号做分隔符。

栈方法

栈是一种后进先出的数据结构。栈中项的插入和移除只发生在一个位置--栈的顶部。ECMAScript专门提供了push()pop()方法,以便实现类似栈的行为。

push()方法接收任意数量的参数,并把它们逐个添加到数组的末尾,并返回修改后的数组长度。

pop()方法从数组末尾移除最后一项,返回移除的项。

队列方法

队列是一种先进先出的数据结构。结合使用shift()push()可以模拟队列。

shift()方法移除数组中的第一项,并返回移除的项。

unshift()方法和shift()用途相反:它能在数组前端添加任意个项,并返回新数组的长度。

重新排序方法

reverse()方法会反转数组项的排序。

更加灵活的方式是使用sort()。默认情况下,sort()按升序排列数组项。为了实现排序,sort()会调用每个数组项的toString()方法,然后比较字符串。

sort()方法可以接收一个比较函数。用来确定顺序。比较函数接收两个参数,如果第一个参数应该位于第二个参数前面则返回一个负数,如果两个参数相等则返回0,反之返回一个正数。

操作方法

concat()方法会先创建当前数组的一个副本,然后将接收到的参数添加到副本的末尾。如果参数是一个或多个数组,则将这些数组中的每一项都添加到结果数组中。如果参数不是数组,则会被简单地添加到数组的末尾。

slice()方法接收一个或两个参数,及要返回想的起始位置和结束位置。如果只传入了一个参数,则返回指定位置到数组结尾的所有项。如果传入了两个参数,则返回起始位置和结束位置之间的项--但不包括结束位置的项。slice()方法不影响原来的数组。

splice()方法可以用来删除、插入和替换数组中的项。splice()方法始终会返回一个数组,包含了从原始数组中删除的项(如果没有删除任何项,则返回一个空数组)。

  • 删除:需要指定两个参数,要删除第一项的位置和要删除的项数;
  • 插入:需要指定三个参数,起始位置,0(要删除的项数)和要插入的项。如果要插入多个项,则可以传入第四、五...任意多个项。
  • 替换:需要指定三个参数,起始位置,要删除的项数和要插入的项。插入的项数不必和删除的项数相等。

位置方法

indexOf()lastIndexOf(),都接收两个参数:要查找的项和查找的起点位置(可选)。都是返回要查找项在数组中的位置,如果没找到,则返回-1。在比较时使用的是全等操作符。

迭代方法

ECMAScript 5为数组定义了五个迭代方法。每个方法都接收两个参数:要在每一项上运行的函数和运行该函数的作用域对象(可选)。第二个参数会影响this的值。第一个参数:函数,接受三个参数:数组项的值,该项在数组中的位置和数组对象本身。

  • every():如果该函数对每一项都返回true,则返回true
  • some():如果该函数对任一项返回true,则返回true
  • filter():返回该函数会返回true的项组成的数组
  • forEach():没有返回值
  • map():返回每次函数调用的结果组成的数组

以上方法都不会修改数组中包含的值。

缩小方法

reduce()reduceRight()。这两个方法都会迭代数组所有项,然后构建一个最终返回的值。

这两个方法都接收两个参数:一个在每一项上调用的函数和作为缩小基础的初始值(可选)。第一参数:函数,接受四个参数,前一个值,当前值,项的索引和数组对象。这个函数返回的任何值都会作为第一个参数自动传给下一项。第一次迭代发生在数组的第二项上。

Date类型

Date.now() 返回调用这个方法时的日期和时间的毫秒数。

Date.valueOf()也是返回日期的毫秒数。

RegExp 类型

创建正则表达式:

var expression=/pattern/flags

或者使用RegExp构造函数,它接收两个参数:一个是要匹配的字符串模式,另一个是可选的标志字符串。要注意的是:传给RegExp构造函数的两个参数都是字符串(不能把正则表达式字面量传递给构造函数)。

var pattern=new RegExp("[bc]at","i")

模式中使用的所有元字符都需要转义。元字符包括:

([{\^$|)?*+.]}

由于RegExp构造函数的模式参数是字符串,所以在某些情况下要对字符进行双重转义。所有元字符都必须双重转义,那些已经转移过的字符也是如此。

函数

每个函数都是Function类型的实例,都与其它应用类型一样具有属性和方法。而函数名实际上是一个指向函数对象的指针,不会与某个函数绑定。换句话说,一个函数可以有多个名字。

定义函数有两种语法:

  • 函数声明:

    function sum(num1,num2){
        return sum1+sum2;
    }
    
  • 函数表达式:

    var sum=function(num1,num2){
        return sum1+sum2;
    }
    

在代码开始运行之前,解析器会通过一个名为函数声明提升(function declaration hoisting)的过程,使其在执行任何代码之前可用;至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正的被解释执行。

函数内部属性

在函数内部,有两个特殊的对象:argumentsthis

arguments的主要用途是保存函数参数,它还有一个callee属性,指向拥有这个arguments对象的函数。

this引用的是函数据以执行的环境对象。

函数的属性和方法

每个函数包含两个属性:lengthprototype。其中length属性表示函数希望接收的命名参数的个数。

prototype是保存它们所有实例方法的真正所在。prototype属性是不可枚举的,因此使用for-in 无法发现。

ECMAScript 5规范了另一个函数对象的属性:caller。这个属性保存着调用当前函数的的函数的引用。

每个函数都包含两个非继承而来的方法:apply()call()。它俩的用途是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。

apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组,可以是Array的实例,也可以是arguments对象。

call()方法与apply()方法区别仅在于接收参数的方式不同。使用call()方法时,传递给函数的参数必须逐个列举出来。

使用call()apply()来扩充作用域最大的好处是,对象不需要与方法有任何耦合关系。

ECMAScript 5还定义了一个方法bind()。这个方法会创建一个函数的实例,其this的值会被绑定到传给bind()函数的值。例如:

var o={color:'red'};

function sayColor(){
	alert(this.color);
}

var objectSayColor=sayColor.bind(o);

objectSayColor(); //red

参考资料:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

String 类型

String 类型的实例都有一个length属性,表示字符串中包含的字符数量。需要注意的是,即使字符串中包含双字节字符(不是只占一个字节的ASCII字符),每个字符也只算一个字符。

字符方法

用于访问字符串中特定字符。charAt()charCodeAt()。这两个方法都接收一个参数,即基于0的字符位置。

字符串操作方法

concat(),用于将一个或多个字符串拼接起来。返回拼接得到的新字符串。concat()方法可以接受任意多个参数。在实践中更多的是使用加号操作符。

三个基于子字符串创建新字符串的方法:

  • slice():接收一到两个参数。第一个参数指定子字符串的起始位置,第二个参数指定了结束位置。如果省略,默认是字符串末尾。
  • substr():接收一到两个参数。第一个参数指定子字符串的起始位置,第二个参数指定子字符串长度。如果省略,默认是字符串末尾。
  • substring():接收一到两个参数。第一个参数指定子字符串的起始位置,第二个参数指定了结束位置。如果省略,默认是字符串末尾

字符串位置方法

indexOf()lastIndexOf()用于从字符串中查找子字符串。返回子字符串的位置,如果没有找到返回-1。

字符串模式匹配

  • match():本质上与调用RegExp 的 exec() 方法相同。只接收一个参数,正则表达式或者 RegExp 对象。返回结果是一个数组:数组的第一项是与整个模式匹配的字符串,之后的每一项(如果有)保存着与正则表达式中的捕获组匹配的字符串
  • search():只接收一个参数,正则表达式或者 RegExp 对象。返回字符串中第一个匹配项的索引,如果没有找到,则返回-1。
  • replace():接收两个参数:第一个参数是一个 RegExp 对象或者一个字符串(这个字符串不会被转换成正则表达式),第二个参数是一个字符串或者函数。如果第一个参数是字符串,那么只会替换第一个子字符串。要想替换所有子字符串,唯一的办法就是提供一个正则表达式,而且要指定全局标志。
  • split():基于指定的分隔符将一个字符串分割为多个字符串,并将结果放到一个数组中。分割符可以使字符串,也可以是 RegExp 对象。它还接收可选的第二个参数,用于指定数组的大小,以确保返回的数组不会超过既定大小。

fromCharCode()

String构造函数还有一个静态方法:fromCharCode()。它接收一个或多个字符编码,然后将它们转换成一个字符串。从本质上看,它与charCodeAt()执行的是相反的操作。

单体内置对象

Global

事实上,没有全局变量或全局函数,所有在全局作用域中定义的属性和函数,都是Global对象的属性。

它包含的方法有:

  • isNaN()
  • isFinite
  • parseInt()
  • parseFloat()

还包括URI编码方法:

  • encodeURI() :不会编码下面的字符

    保留字符:; , / ? : @ & = + $
    非转义的字符:alphabetic, decimal digits, - _ .! ~ * ' ( )
    score: #

  • encodeURIComponent() :不会编码下面的字符:

    非转义的字符:alphabetic, decimal digits, - _ .! ~ * ' ( )

  • decodeURI() :只能对使用encodeURI()替换的字符进行解码。

  • decodeURIComponent(): 能够解码使用encodeURIComponent()编码的所有字符。

eval() 方法,只接受一个参数,要执行的ECMAScript字符串。当解析器发现代码中调用eval()方法时,它会将传入的参数当做实际的ECMAScript语句来解释,然后把执行结果插入到原位置。通过eval()执行的代码被认为是包含该次调用的执行环境的一部分,因此被执行的代码具有与该执行环境相同的的作用域链。

Math 对象

min()max()用于确定一组数中最大值或是最小值。这两个方法都接收任意多个数值参数。

要找到数组中的最大最小值,可以使用apply(),例如:

var values=[1,2,3,4,5]
var max=Math.max.apply(Math,values)

舍入方法

  • Math.ceil() 向上舍入
  • Math.floor() 向下舍入
  • Math.round() 标准舍入

random() 方法返回一个介于0到1之间的一个随机数,不包括0和1。

从某个整数范围内随机选择一个值

值=Math.floor(Math.random()*可能值得总数+第一个可能的值)
`