JavaScript基础总结

1.JavaScript简介

JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。
在1995年时,由Netscape公司的Brendan Eich,在网景导航者浏览器上首次设计实现而成。因为NetscapeSun合作,Netscape管理层希望它外观看起来像Java,因此取名为JavaScript。
发展初期,JavaScript的标准并未确定,同期有Netscape的JavaScript,微软的JScript和CEnvi的ScriptEase三足鼎立。1997年,在ECMA(欧洲计算机制造商协会-European Computer Manufactures Association)的协调下,由Netscape、Sun、微软、Borland组成的工作组确定统一标准:ECMA-262—定义一种名为ECMAScript(发音“ek-ma-script”)的新脚本语言的标准。


虽然JavaScript和ECMAScript通常被人们用来表达相同的含义,但是JavaScript的含义却比ECMAS-262中规定的要多得多。一个完整的JavaScript 实现应该有下列三个不同的部分组成

  • 核心(ECMAScript)
  • 文档对象模型(DOM)
  • 浏览器对象模型(BOM)

ECMA-262标准规定了这门语言的下列组成部分:

  • 语法
  • 类型
  • 语句
  • 关键字
  • 保留字
  • 操作符
  • 对象
    ECMAScript就是对实现该标准规定的各个方面内容的语言的描述。JavaScript实现了ECMAScript。

在html中使用JavaScript

HTML 中的脚本必须位于 <script> 与 </script> 标签之间。
脚本可被放置在 HTML 页面的 <body> 和 <head> 部分中。
外部的 JavaScript
也可以把脚本保存到外部文件中。外部文件通常包含被多个网页使用的代码。外部 JavaScript 文件的文件扩展名是 .js。
如需使用外部文件,请在 <script> 标签的 "src" 属性中设置该 .js 文件:

<!DOCTYPE html>
<html>
<body>
<script src="myScript.js"></script>
</body>
</html>

JavaScript 操作符

JavaScript语言有多种类型的运算符:

类型 实例 描述
赋值,算术和位运算符 = + - * / 在 JS 运算符中描述
条件,比较及逻辑运算符 == != < > 在 JS 比较运算符中描述

JavaScript 注释

JavaScript 不会执行注释。
我们可以添加注释来对 JavaScript 进行解释,或者提高代码的可读性。
单行注释以 // 开头。
JavaScript 多行注释
多行注释以/* 开始,以 */ 结尾。

HTML注释符号是以 **** 结束的。如果在此注释符号内编写 JavaScrip t脚本,对于不支持 JavaScript 的浏览器,将会把编写的 JavaScript 脚本作为注释处理。

<!-- 这是一个注释 -->

css的注释是以 /* 开始,以 */ 结尾。


JavaScript 字面量

在编程语言中,一般固定值称为字面量,如 3.14。
如:数字(Number)字面量 可以是整数或者是小数

3.14
1001

字符串(String)字面量 可以使用单引号或双引号:

"John Doe"
'John Doe'

数组(Array)字面量 定义一个数组:
[40, 100, 1, 5, 25, 10]

对象(Object)字面量 定义一个对象:
{firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"}

函数(Function)字面量 定义一个函数:
function myFunction(a, b) { return a * b;}


JavaScript 变量

在编程语言中,变量用于存储数据值。
JavaScript 使用关键字 var 来定义变量, 使用等号来为变量赋值:

var x;
x = 5;

变量的命名规则

  • 变量必须以字母开头
  • 变量也能以 $ 和 _ 符号开头(不过我们不推荐这么做)
  • 变量名称对大小写敏感(y 和 Y 是不同的变量)

JavaScript let 和 const
ES2015(ES6) 新增加了两个重要的 JavaScript 关键字: let 和 const。
let 声明的变量只在 let 命令所在的代码块内有效。
const 声明一个只读的常量,一旦声明,常量的值就不能改变。


JavaScript 数据类型


值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。

引用数据类型:对象(Object)、数组(Array)、函数(Function)。

注:Symbol 是 ES6 引入了一种新的原始数据类型,表示独一无二的值。


Object类型

 ECMAScript中的对象其实就是一组数据和功能的集合。对象可以通过执行new操作符后跟要创建的对象类型的名称来创建。

var o = new Object();

Object类型是所有它的实例的基础。换句话说,Object类型所具有的任何属性和方法也同样存在于更具体的对象中。
 Object的每个实例都具有下列属性和方法

  • constructor:保存着用于创建当前对象的函数。对于上面的例子而言,构造函数(constructor)就是Object()。
  • hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中是否存在。其中,作为参数的属性名(propertyName)必须以字符串的形式指定(例如:0.hasOwnProperty("name"))。
  • isPrototypeOf(object):用于检查传入的对象是否是当前对象的原型。
  • propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in语句来枚举。参数的属性名必须以字符串的形式指定。
  • toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。
  • toString():返回对象的字符串表示。
  • valueOf():返回对象的字符串、数值或布尔值表示。通常与toString()方法的返回值相同。

JavaScript 拥有动态类型
JavaScript 拥有动态类型。这意味着相同的变量可用作不同的类型:

var x;               // x 为 undefined
var x = 5;           // 现在 x 为数字
var x = "John";      // 现在 x 为字符串

Undefined 和 Null
Undefined 这个值表示变量不含有值。
可以通过将变量的值设置为 null 来清空变量。


声明变量类型
当您声明新变量时,可以使用关键词 "new" 来声明其类型:

var carname=new String;
var x=      new Number;
var y=      new Boolean;
var cars=   new Array;
var person= new Object;

JavaScript 变量均为对象。当您声明一个变量时,就创建了一个新的对象。


JavaScript 对象

JavaScript 对象是拥有属性和方法的数据。


对象定义
你可以使用字符来定义和创建 JavaScript 对象:

var person = {
firstName:"John",
 lastName:"Doe", 
age:50, 
eyeColor:"blue"
};

对象属性

可以说 "JavaScript 对象是变量的容器"。
但是,我们通常认为 "JavaScript 对象是键值对的容器"。
键值对通常写法为 name : value (键与值以冒号分割)。
键值对在 JavaScript 对象通常称为 对象属性。


访问对象属性

你可以通过两种方式访问对象属性:
person.lastName;
person["lastName"];


对象方法

对象的方法定义了一个函数,并作为对象的属性存储。
对象方法通过添加 () 调用 (作为一个函数)。
该实例访问了 person 对象的 fullName() 方法:

name = person.fullName();

尝试一下 »

如果你要访问 person 对象的 fullName 属性,它将作为一个定义函数的字符串返回:

name = person.fullName;

尝试一下 »


访问对象方法

你可以使用以下语法创建对象方法:

methodName : function() { code lines }

你可以使用以下语法访问对象方法:

objectName.methodName()

通常 fullName() 是作为 person 对象的一个方法, fullName 是作为一个属性。


JavaScript 函数

JavaScript 函数语法
函数就是包裹在花括号中的代码块,前面使用了关键词 function来声明,后跟一组参数以及函数体

function functionname()
{
    执行代码
}

当调用该函数时,会执行函数内的代码。


调用带参数的函数

在调用函数时,您可以向其传递值,这些值被称为参数。
这些参数可以在函数中使用。
您可以发送任意多的参数,由逗号 (,) 分隔:

myFunction(argument1,argument2)

当您声明函数时,请把参数作为变量来声明:

function myFunction(var1,var2)
{
      代码
}

变量和参数必须以一致的顺序出现。第一个变量就是第一个被传递的参数的给定的值,以此类推。

<p>点击这个按钮,来调用带参数的函数。</p>
<button onclick="myFunction('Harry Potter','Wizard')">点击这里</button>
<script>
function myFunction(name,job){
    alert("Welcome " + name + ", the " + job);
}
</script>

带有返回值的函数

ECMAScript中函数在定义时不必指定是否有返回值。
有时,我们会希望函数将值返回调用它的地方。
通过使用 return 语句就可以实现。
在使用 return 语句时,函数会停止执行,并返回指定的值。
语法

function myFunction()
{
    var x=5;
    return x;
}

上面的函数会返回值 5。


理解参数

 ECMAScript函数的参数与大多数其他语言中函数的参数有所不同。ECMAScript函数不介意传递进来多少个参数,也不在乎传递进来的参数是什么数据类型。就是说,即使你定义的函数只接受两个参数,在调用这个函数时也未必一定要传递两个参数。可以传递一个,三个、甚至不传。之所以会这样,原因是ECMAScript中的参数在内部是用一个数组来表示的。函数接收到的始终都是这个数组,而不关心数组中包含那些参数。实际上,在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数。
其实,arguments对象只是与数组类似(它并不是啊Array的实例),因为可以使用方括号访问它的每一个元素,使用length属性来确定传进来多少个参数。例如函数:

function sayHi(name,message) {
            alert("Hello" + name + "," + message);
        }

可以使用下面这样重写,即不显式的使用命名参数:

function sayHi() {
    alert("Hello" + arguments[0] + "," + arguments[1]);
}

这个重写后的函数中不包含命名参数。虽然没有使用name和message标识符但是函数的功能依旧。这个事实说明了ECMAScript函数的一个重要特点:命名的参数只提供便利,但不是必需的。另外,在命名参数方面,其他语言可能需要事先创建一个函数签名,而将来的调用必须与该签名一致。但是在ECMAScript中,没有这些条条框框,解析器不会验证命名参数。


没有重载

  ECMAScript函数不能像传统意义上那样实现重载。而在其他语言(如Java)中,可以为一个函数编写连个定义,只要这两个定义的标签不同即可。由于ECMAScript函数没有签名,因为其参数是由包含0或多个值的数组来表示的。而没后函数签名,真正的重载是不可能做到的。
如果在ECMAScript中定义了连个名字相同的函数,则该名字只属于后定义的函数。


函数声明与函数表达式

 解析器在向执行环境中加载数据时,对函数声明和函数表达式并非一视同仁。解析器会率先读取函数的声明,并使其在执行任何代码之前可用(可以访问);至于函数表达式,则必须等到解析器执行到它所在的代码行,才会被解释执行。

alert(sum(10,10));
function sum(num1,num2) {
    return num1 + num2;
}

以上代码可以正常运行。因为在代码开始执行之前,解析器就已经通过一个名为函数声明提升的过程,读取并将函数声明添加到执行环境中。
如果把函数声明改为等价的函数表达式,就会在执行期间导致错误。

alert(sum(10,10));  //执行到此报错 “unexpected identifier”
var sum = function(num1,num2) {
    return num1 + num2;
}

函数内部属性

 在函数内部,有两个特殊的对象:arguments和this 。其中,arguments是一个类数组对象,包含这传入函数中的所有参数。虽然arguments的主要用途是保存函数的参数,但这个对象还有一个名叫callee的属性,该属性是一个指针,执行拥有这个arguments对象的函数。请看下面这个非常金典的阶乘函数。

function factorial(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * factorial(num - 1);
    }
}

如上代码所示,在函数有名字,而且名字以后也不会变的情况下,这样定义没有问题。但问题是这个函数的执行与函数名factorial紧紧耦合在了一起。为了消除这种紧密耦合的现象,可以像下面这样使用arguments.callee。

function factorial(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * arguments.callee(num - 1);
    }
}

函数内部的另一个特殊对象是this,this引用的是函数执行的环境对象。

函数的属性和方法

 ECMAScript中函数是对象,因此函数也有属性和方法。每个函数都包含两个属性:length和prototype。其中length属性表示函数希望接收的命名参数的个数。
 每个函数都包含两个飞继承而来的方法:apply()和call()。这两个方法的用途是在特定作用域中调用函数,实际上等于设置函数体内this对象的值。


JavaScript 字符串

字符串可以存储一系列字符,如 "John Doe"。
字符串可以是插入到引号中的任何字符。你可以使用单引号或双引号
你可以使用索引位置来访问字符串中的每个字符:

var carname = "Volvo XC60";
var character = carname[7];

字符串的索引从 0 开始,这意味着第一个字符索引值为 [0],第二个为 [1], 以此类推。


特殊字符

反斜杠是一个转义字符。 转义字符将特殊字符转换为字符串字符:
转义字符 (\) 可以用于转义撇号,换行,引号,等其他特殊字符。
下表中列举了在字符串中可以使用转义字符转义的特殊字符:

代码 输出
' 单引号
" 双引号
\\ 反斜杠
\n 换行
\r 回车
\t tab(制表符)
\b 退格符
\f 换页符

字符串可以是对象
通常, JavaScript 字符串是原始值,可以使用字符创建: var firstName = "John"
但我们也可以使用 new 关键字将字符串定义为一个对象: var firstName = new String("John")

var x = "John";              
var y = new String("John");
(x === y) // 结果为 false,因为 x 是字符串,y 是对象

尝试一下 »

=== 为绝对相等,即数据类型与值都必须相等。


字符串属性和方法
原始值字符串,如 "John", 没有属性和方法(因为他们不是对象)。

原始值可以使用 JavaScript 的属性和方法,因为 JavaScript 在执行方法和属性时可以把原始值当作对象。


字符串属性

属性 描述
constructor 返回创建字符串属性的函数
length 返回字符串的长度
prototype 允许您向对象添加属性和方法

字符串方法

方法 描述
charAt() 返回指定索引位置的字符
charCodeAt() 返回指定索引位置字符的 Unicode 值
concat() 连接两个或多个字符串,返回连接后的字符串
fromCharCode() 将 Unicode 转换为字符串
indexOf() 返回字符串中检索指定字符第一次出现的位置
lastIndexOf() 返回字符串中检索指定字符最后一次出现的位置
localeCompare() 用本地特定的顺序来比较两个字符串
match() 找到一个或多个正则表达式的匹配
replace() 替换与正则表达式匹配的子串
search() 检索与正则表达式相匹配的值
slice() 提取字符串的片断,并在新的字符串中返回被提取的部分
split() 把字符串分割为子字符串数组
substr() 从起始索引号提取字符串中指定数目的字符
substring() 提取字符串中两个指定的索引号之间的字符
toLocaleLowerCase() 根据主机的语言环境把字符串转换为小写,只有几种语言(如土耳其语)具有地方特有的大小写映射
toLocaleUpperCase() 根据主机的语言环境把字符串转换为大写,只有几种语言(如土耳其语)具有地方特有的大小写映射
toLowerCase() 把字符串转换为小写
toString() 字符串对象值
toUpperCase() 把字符串转换为大写
trim() 移除字符串首尾空白
valueOf() 返回某个字符串对象的原始值

变量、作用域

基本类型和引用类型的值

 变量可能包含两种不同数据类型的值:基本类型值和引用类型值。基本类型值指的是简单的数据段,而引用类型值指那些可能由多个值构成的对象。
  在将一个值赋值给变量时,解析器必须确定这个值是基本类型还是引用类型值。5种基本数据类型:Undefined、Null、Boolean、Number、和String。这5种基本数据类型是按值访问的,因为可以 操作保存在变量中的实际的值。
 引用类型的值是保存在内存中的对象。与其他语言不同,JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象时,实际上是操作对象的引用而不是实际的对象。


动态属性

定义基本类型和引用类型值的方式是类似的:创建一个变量并为该变量赋值。但是这个值保存到变量中后,对不同类型的值可以执行的操作则大不相同。对于引用类型的值,我们可以为其添加属性和方法,也可以改变和删除其属性和方法。
但是我们不能给基本数据类型的值添加属性,尽管这样做不会导致任何的错误。比如:

var name = "jack";
name.age = 27;
alert(name.age);   //Undefined

复制变量的值

除了保存的方式不同之外,从一个变量像另一个变量复制基本数据类型值和引用类型值时,也存在不同。如果从一个变量像另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上。
当从一个变量像另一个变量复制引用类型的值时,同样也会将存储在变量对象中的值复制一份到新变量分配的空间中。不同的是,这个值的副本实际上是一个指针,而这个指针指向存储在堆中的一个对象。复制操作结束后,两个变量实际上引用同一个对象。一次改变其中一个变量,就会影响另一个变量。


传递参数

EMCAScript中所有函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。


没有块级作用域

JavaScript没有块级作用域。在其他类C语言中,由花括号封闭的代码块都有自己的作用域,因而支持根据条件来定义变量。例如下面的代码在JavaScript中并不会得到想象中的结果:

if (true) {
      var color = "blue";
}
alert(color);       //blue

这里是在一个if语句中定义了变量color。如果是C、C++,color会在if语句执行完毕后被销毁。但在JavaScript中,if语句中的变量声明会将变量添加到当前的执行环境(在这里是全局环境)中。在使用for语句时尤其要牢记这一差异,例如:

for (var i = 0; i < 10; i++) {
        doSomething(i);
    }
    alert(i);    //10

对于有块级作用域的语言来说,for语句初始化变量的表达式所定义的变量,只会存在于循环的环境之中。而对于JavaScript来说,for语句创建的变量i即使for循环执行结束后,也依旧存在于循环外部的执行环境中。
1.声明变量
使用var 声明的变量会自动被添加到最近的环境中,在函数内部,最接近的环境就是函数的局部环境;在with语句中,最接近的环境是函数环境。如果初始化变量时没有使用var 变量,该变量会自动被添加到全局环境。如下所示:

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

var result = add(10,20);
alert(sum);     //由于sum不是有效的变量,因此会导致错误

以上代码中的函数add()定义了一个名为sum的局部变量,该变量包含加法操作的结果。虽然结果值从函数中返回了,但变量sum在函数外部是访问不到的。如果省略var关键字名,那么当add()执行完毕后,sum也将可以访问到:

function add (num1,num2) {
     sum = num1 + num2;
     return sum;
}

var result = add(10,20);
alert(sum);     //30

这个例子中的变量sum在被初始化赋值时没有使用var关键字。于是,当调用完add()之后,添加到全局环境中的变量sum将继续存在;即使函数已经执行完毕,后面的代码依旧可以访问它。


JavaScript Array(数组) 对象

什么是数组?
数组对象是使用单独的变量名来存储一系列的值。
数组的每一项可以保存任何类型的数据。也就是说,可以用数组的第一个位置来保存字符串,第二个位置保存对象,第三个位置保存数值。


创建一个数组

创建一个数组,有三种方法。
下面的代码定义了一个名为 myCars的数组对象:
1: 常规方式:

var myCars=new Array(); 
myCars[0]="Saab";       
myCars[1]="Volvo";
myCars[2]="BMW";

2: 简洁方式:

var myCars=new Array("Saab","Volvo","BMW");

3: 字面:

var myCars=["Saab","Volvo","BMW"];

访问数组

通过指定数组名以及索引号码,你可以访问某个特定的元素。
以下实例可以访问myCars数组的第一个值:

var name=myCars[0];

以下实例修改了数组 myCars 的第一个元素:

myCars[0]="Opel";

在读取和设置数组的值时,要使用方括号并提供相应值的基于0的数子索引,如下所示:

var colors = ["red","blue","green"];
alert(colors[0]);       //显示第一项
colors[2] = "black";    //修改第三项
colors[3] = "brown";    //新增第四项

如果索引小于数组中的项数,则返回对应项的值。如果设置的索引超过了数组现有的项数,数组就会自动增加到该索引值加1的长度(就这个例子而言,索引是3,因此数组长度就是4)。
 数组的length属性不是只读的。因此,通过设置这个属性,可以从数组的末尾移除项或向数组中添加新项。

var colors = ["red","blue","green"];
colors.length = 2;
alert(colors[2]);     //Undefined
var colors = ["red","blue","green"];
colors.length = 4;
alert(colors[3]);     //Undefined

栈方法

 ECMASCript数组也提供了一种让数组的行为类似于其他数据结构的方法。具体来说,数组可以表现的像栈一样。栈是一种 LIFO(Last-In-First-Out,后进先出)的数据结构。而栈中的插入和移除,只发生在一个位置--栈的顶部。ECMASCript为数组专门提供了push()和pop()方法,以便实现类似栈的行为。
 push()方法可以接受任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。而pop()方法则从数组末尾移除最后一项,减少数组的length值,然后返回移除的项。

var color = new Array();
var count =  colors.push("red","green"); //推入两项
alert(count);   //2

var item = colors.pop();  //取得自后一项
alert(item);    //green
alert(colors.length);  //1

队列方法

 栈数据结构的访问规则是LIFO(后进先出),而队列数据结构的访问规则是FIFO(First-In-First-Out,先进先出);队列在列表的末端添加项,从列表的前端移除项。shift()它能够移除数组中饿第一个项并返回该项,同时数组长度减1。结合使用shift()和push()方法,可以像队列一样使用数组。

var color = new Array();
var count =  colors.push("red","green"); //推入两项
alert(count);   //2

count = colors.push("black");  //推入另一项
alert(count);   //3

var item = colors.shift();  //取得第一项
alert(item);    //red
alert(colors.length);  //2

 ECMASCript还为数组提供了unshift()方法。unshift()于shift()的用途相反:能在数组前端添加任意个项并返回数组长度。


重排序方法

 数组中已经存在的两个直接用来排序的方法:reverse()和sort()。
reverse()方法会反转数组的顺序。

var values = [1,2,3,6,5,9,0];
values.reverse();
alert(values);   //0,9,5,6,3,2,1

 默认情况下,sort()方法按升序排列数组项,sort()方法会调用每个数组项的toString()转型方法,然后表得到的字符串,以确定如何排序。即使数组中的每一项都是数值,sort()方法比较的依然是字符串,如下所示:

var values = [0,1,5,10,15];
values.sort();
alert(values);   //0,1,10,15,5

sort()方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面。
 比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,相等返回0,第一个参数应该位于第二个之后则返回一个正数。以下是一个简单的比较函数:

function compare(value1,value2) {
    if (value1 < value2) {
        return -1;
    } else if (value1 > value2) {
        return 1
    } else {
        return 0;
    }
}

这个比较函数可以适用于大多数数据类型,只要将其作为参数传递给sort()方法即可

var values = [0,1,5,10,15];
values.sort(compare);
alert(values);   //0,1,5,10,15

操作方法

 concat()方法:创建当前数组的一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。

var colors = ["red","blue","green"];
var colors2 = colors.concat("yellow",["black","brown"]);

alert(colors); // red ,green,blue
alert(colors2);  // red ,green,blue,yellow,black,brown

 slice()方法:能够基于当前数组中的一或多个项创建一个新数组。该方法可以接收一或两个参数,既要返回项的起始和结束位置。在只有一个参数的情况下,slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。

var colors = ["red","green","blue","yellow","purple"];
var colors2 = colors.slice(1);
var colors3 = colors.slice(1,4);

alert(colors2); // green,blue,yellow,purple
alert(colors2);  // green,blue,yellow

 splice()方法有多种用法,主要用途是像数组的中部插入项,但使用这种方法的方式则有如下3种。

  • 删除:可以删除任意数量的项,只需指定2个参数:要删除的第一项的位置和要删除的项数。
    例如,splice(0,2)会删除数组中的前两项。
  • 插入:可以像指定位置插入任意数量的项,只需要提供3个参数:起始位置、0(要删除的项数)和要插入的项。如果要插入多个项,可以再传入第四、第五,以至任意多个项。例如,splice(2,0,"red","green")会从当前数组的位置2开始插入字符串"red"和"green"。
  • 替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需要指定3个参数:起始位置、要删除的项数和要插入的任意数量的项。插入的项数不必于删除的项数相等。例如,splice(2,1,"red","green")会删除当前数组位置2的项,然后在从位置2开始插入字符串"red"和"green"。
     splice()始终都会返回一个数组,该数组中包含从原始数组中删除的项(没有删除则返回一个空数组)。
var colors = ["red","green","blue"];
var removed = colors.splice(0,1);   //删除第一项
alert(colors);   // green,blue
alert(removed);  // red

removed = colors.splice(1,0,"yellow","orange");   //从位置1开始插入两项
alert(colors);   // green,yellow,orange,blue
alert(removed);  // 返回一个空数组

removed = colors.splice(1,1,"red","purple");     //插入两项,删除一项
alert(colors);  // green,red,purple,orange,blue
alert(removed); //yellow,返回数组中只包含一项

位置方法

 ECMAScript5为数组实例添加了两个位置方法:indexOf()和lastIndexOf()。这两个方法都接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中indexOf()方法从数组的开头位置0开始向后查找,lastIndexOf()方法则从数组的末尾开始向前查找。
 这两个方法都返回要查找的项在数组中的位置,或在没找到的情况下返回-1.在比较第一个参数与数组中的每一项时,会使用全等操作符;要求查找的项必须严格相等。

var numbers = [1,2,3,4,5,4,3,2,1];

alert(numbers.indexOf(4));      //3
alert(numbers.lastIndexOf(4));  //5

alert(numbers.indexOf(4,4));     //5
alert(numbers.lastIndexOf(4,4)); //3

var person = {name: "Nicholas"};
var people = [{name: "Nicholas"}];

var morePeople = [person];

alert(people.indexOf(person));   //-1
alert(morePeople.indexOf(person));  //0

迭代方法

 ECMAScript5为数组定义了5个迭代方法。每个方法都接收两个参数:要在每一项上运行的函数和运行该函数的作用域对象(可选的)--影响this的值。传入这些方法中的函数会接收三个参数:数组项的值、该项在数组中的位置和数组对象本身。以下是5个迭代方法的作用。

  • every():对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true 。
  • filter():对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组。
  • forEach():对数组中的每一项运行给定函数,这个方法没有返回值。
  • map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
  • some():对数组中的每一项运行给定函数,如果该函数对任意一项返回true,则返回true。
    以上方法都不会修改数组中包含的值。
     在这些方法中,最相似的是every()和some(),它们都用于查询数组中的项是否满足某个条件。
var numbers = [1,2,3,4,5,4,3,2,1];

var everyResult = numbers.every(function(item, index, array){
    return (item > 2);
});

alert(everyResult);   // false

var someResult = numbers.some(function (item,index,array) {
    return (item > 2);
});

alert(someResult);   // true

filter()函数实例:

var numbers = [1,2,3,4,5,4,3,2,1];

var filterResult = numbers.filter(function(item, index, array){
    return (item > 2);
});

alert(filterResult);   // [3,4,5,4,3]

map() 函数实例:

var numbers = [1,2,3,4,5,4,3,2,1];

var mapResult = numbers.filter(function(item, index, array){
    return item * 2;
});

alert(mapResult);   // [2,4,6,8,10,8,6,4,2]

最后的forEach(),它只是对数组中的每一项运行传入的函数。本质上与使用for循环迭代数组一样。

var numbers = [1,2,3,4,5,4,3,2,1];

numbers.forEach(function(item, index, array){
    //执行某些操作
});

归并方法

 ECMAScript5还新增了两个归并数组的方法:reduce()和reduceRigth()。这两个方法都会迭代数组的所有项,然后构建一个最终返回值。其中reduce()方法从数组的第一项开始,逐个遍历到最后。而reduceRigth()则从数组的最后一项开始,向前遍历到第一项。
 这两个方法都接收两个参数:一个在每一项上调用的函数和作为归并基础的初始值(可选的)。传给reduce()和educeRigth()的函数接收4个参数:前一个值、当前值、项的索引和数组对象。这个函数返回的任何值都会作为第一个参数自动传给下一项。第一次迭代发生在数组的第二项上,因此第一个参数是数组的第一项,第二个参数就是数组的第二项。
 使用reduce()方法可以执行求数组中所有值之和的操作,比如:

var values = [1,2,3,4,5];
var sum = values.reduce(function (prev, ucr, index, array) {
        return prev + cur;
});

alert(sum); // 15


JavaScript 运算符

JavaScript 算术运算符
y=5,下面的表格解释了这些算术运算符:

运算符 描述 例子 x 运算结果 y 运算结果 在线实例
+ 加法 x=y+2 7 5 实例 »
- 减法 x=y-2 3 5 实例 »
* 乘法 x=y*2 10 5 实例 »
/ 除法 x=y/2 2.5 5 实例 »
% 取模(余数) x=y%2 1 5 实例 »
++ 自增 x=++y 6 6 实例 »
x=y++ 5 6 实例 »
-- 自减 x=--y 4 4 实例 »
x=y-- 5 4 实例 »

JavaScript 赋值运算符

赋值运算符用于给 JavaScript 变量赋值。

给定 x=10 y=5,下面的表格解释了赋值运算符:

运算符 例子 等同于 运算结果 在线实例
= x=y x=5 实例 »
+= x+=y x=x+y x=15 实例 »
-= x-=y x=x-y x=5 实例 »
*= x*=y x=x*y x=50 实例 »
/= x/=y x=x/y x=2 实例 »
%= x%=y x=x%y x=0 实例 »

用于字符串的 + 运算符
+ 运算符用于把文本值或字符串变量加起来(连接起来)。

如需把两个或多个字符串变量连接起来,请使用 + 运算符。

如需把两个或多个字符串变量连接起来,请使用 + 运算符:

txt1="What a very";
txt2="nice day";
txt3=txt1+txt2;
txt3 运算结果如下:
What a verynice day

对字符串和数字进行加法运算
两个数字相加,返回数字相加的和,如果数字与字符串相加,返回字符串,如下实例:

x=5+5;
y="5"+5;
z="Hello"+5;

x,y, 和 z 输出结果为:

10
55
Hello5

规则: 如果把数字与字符串相加,结果将成为字符串!


JavaScript 比较 和 逻辑运算符


比较和逻辑运算符用于测试 true 或者 false。


比较运算符在逻辑语句中使用,以测定变量或值是否相等。
x=5,下面的表格解释了比较运算符:

运算符 描述 比较 返回值 实例
== 等于 x==8 false 实例 »
x==5 true 实例 »
=== 绝对等于(值和类型均相等) x==="5" false 实例 »
x===5 true 实例 »
!= 不等于 x!=8 true 实例 »
!== 不绝对等于(值和类型有一个不相等,或两个都不相等) x!=="5" true 实例 »
x!==5 false 实例 »
> 大于 x>8 false 实例 »
< 小于 x<8 true 实例 »
>= 大于或等于 x>=8 false 实例 »
<= 小于或等于 x<=8 true 实例 »

运算符
逻辑运算符用于测定变量或值之间的逻辑。

给定 x=6 以及 y=3,下表解释了逻辑运算符:

运算符 描述 例子
&& and (x < 10 && y > 1) 为 true
|| or (x==5 || y==5) 为 false
! not !(x==y) 为 true

条件语句

通常在写代码时,您总是需要为不同的决定来执行不同的动作。您可以在代码中使用条件语句来完成该任务。

在 JavaScript 中,我们可使用以下条件语句:

  • if 语句 - 只有当指定条件为 true 时,使用该语句来执行代码
  • if...else 语句 - 当条件为 true 时执行代码,当条件为 false 时执行其他代码
  • if...else if....else 语句- 使用该语句来选择多个代码块之一来执行
  • switch 语句 - 使用该语句来选择多个代码块之一来执行

JavaScript for 循环

avaScript 支持不同类型的循环:

  • for - 循环代码块一定的次数
  • for/in - 循环遍历对象的属性
  • while - 当指定的条件为 true 时循环指定的代码块
  • do/while - 同样当指定的条件为 true 时循环指定的代码块

JavaScript Break 和 Continue 语句


break 语句用于跳出循环。
continue 用于跳过循环中的一个迭代。


JavaScript typeof, null, 和 undefined

typeof 操作符
你可以使用 typeof 操作符来检测变量的数据类型。

typeof "John"                // 返回 string 
typeof 3.14                  // 返回 number
typeof NaN                    // 返回 number
typeof false                 // 返回 boolean
typeof [1,2,3,4]             // 返回 object
typeof {name:'John', age:34} // 返回 object
typeof new Date()             // 返回 object
typeof function () {}         // 返回 function
typeof myCar                  // 返回 undefined (如果 myCar 没有声明)
typeof null                   // 返回 object

在JavaScript中,数组是一种特殊的对象类型。 因此 typeof [1,2,3,4] 返回 object。

请注意:

  • NaN 的数据类型是 number
  • 数组(Array)的数据类型是 object
  • 日期(Date)的数据类型为 object
  • null 的数据类型是 object
  • 未定义变量的数据类型为 undefined

如果对象是 JavaScript Array 或 JavaScript Date ,我们就无法通过 typeof 来判断他们的类型,因为都是 返回 object。


null

在 JavaScript 中 null 表示 "什么都没有"。
null是一个只有一个值的特殊类型。表示一个空对象引用。
用 typeof 检测 null 返回是object。

你可以设置为 null 来清空对象:

var person = null;           // 值为 null(空), 但类型为对象 

尝试一下 »

你可以设置为 undefined 来清空对象:

var person = undefined;     // 值为 undefined, 类型为 undefined 

尝试一下 »


undefined

在 JavaScript 中, undefined 是一个没有设置值的变量。
typeof 一个没有值的变量会返回 undefined

var person;                  // 值为 undefined(空), 类型是undefined

尝试一下 »

任何变量都可以通过设置值为 undefined 来清空。 类型为 undefined.

person = undefined;          // 值为 undefined, 类型是undefined

尝试一下 »


undefined 和 null 的区别

null 和 undefined 的值相等,但类型不等:

typeof undefined             // undefined
typeof null                  // object
null === undefined           // false
null == undefined            // true

JavaScript 类型转换


Number() 转换为数字, String() 转换为字符串, Boolean() 转化为布尔值。


检测数据类型:typeof 与 instanceof

typeof 用以获取一个变量或者表达式的类型,typeof 一般只能返回如下几个结果:

number,boolean,string,function(函数),object(NULL,数组,对象),undefined。

instanceof
可通过 instanceof 操作符来判断对象的具体类型,语法格式:

var result = objectName instanceof objectType

返回布尔值,如果是指定类型返回 true,否则返回 false


JavaScript 错误 - throw、try 和 catch

JavaScript try 和 catch
try 语句允许我们定义在执行时进行错误测试的代码块。
catch 语句允许我们定义当 try 代码块发生错误时,所执行的代码块。
JavaScript 语句 try 和 catch 是成对出现的。
语法

try {
  //在这里运行代码
} catch(err) {
  //在这里处理错误
}

在下面的例子中,我们故意在 try 块的代码中写了一个错字。
catch 块会捕捉到 try 块中的错误,并执行代码来处理它。

var  txt=""; 
function  message()  
{ 
    try  {  
          adddlert("Welcome guest!"); 
    }  catch(err)  { 
         txt="本页有一个错误。\n\n"; 
         txt+="错误描述:" + err.message + "\n\n";
         txt+="点击确定继续。\n\n"; alert(txt); 
    } 
}

尝试一下 »


Throw 语句
throw 语句允许我们创建自定义错误。
正确的技术术语是:创建或抛出异常(exception)。
如果把 throw 与 try 和 catch 一起使用,那么您能够控制程序流,并生成自定义的错误消息。

语法
throw exception
异常可以是 JavaScript 字符串、数字、逻辑值或对象。
本例检测输入变量的值。如果值是错误的,会抛出一个异常(错误)。catch 会捕捉到这个错误,并显示一段自定义的错误消息:

function  myFunction()  {  
var  message, x; 
message = document.getElementById("message"); message.innerHTML = ""; 
x = document.getElementById("demo").value;
 try  { 
           if(x == "")  throw  "值为空";
           if(isNaN(x))  throw  "不是数字"; 
           x = Number(x); 
           if(x < 5)  throw  "太小";
           if(x > 10)  throw  "太大"; 
      }  catch(err)  {  
          message.innerHTML = "错误: " + err; 
    } 
 }

尝试一下 »


JavaScript 变量提升

JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。
JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明。

以下两个实例将获得相同的结果:
实例 1

x = 5; // 变量 x 设置为 5
elem = document.getElementById("demo"); // 查找元素 
elem.innerHTML = x;                     // 在元素中显示 x

var x; // 声明 x

实例 2

var x; // 声明 x
x = 5; // 变量 x 设置为 5 
elem = document.getElementById("demo"); // 查找元素 
elem.innerHTML = x;                     // 在元素中显示 x 

尝试一下 »

要理解以上实例就需要理解 "hoisting(变量提升)"。
变量提升:函数声明和变量声明总是会被解释器悄悄地被"提升"到方法体的最顶部。

注意JavaScript 只有声明的变量会提升,初始化的不会。


JavaScript 严格模式(use strict)

"use strict" 的目的是指定代码在严格条件下执行。

严格模式下你不能使用未声明的变量。

"use strict";
x = 3.14;       // 报错 (x 未定义)

严格模式的限制

  • 不允许使用未声明的变量

  • 不允许删除变量或对象。

"use strict";
var x = 3.14;
delete x;                // 报错
  • 不允许删除函数。
"use strict";
function x(p1, p2) {}; 
delete x;                // 报错 
  • 不允许变量重名

  • 不允许使用八进制:

"use strict";
var x = 010;             // 报错

等等...


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容