JavaScript简明教程之快速入门

JavaScript代码可以直接嵌入到网页的任何地方,不过我们通常把它们放到head中

<html>
  <head>
    <script>
      alert('Hello World');
    </script>
  </head>
  <body>
    ...
  </body>
</html>

<script>...</script>包含的代码就是JavaScript代码,它将直接被浏览器执行

第二种方法就是把JavaScript代码放到一个单独的.js文件里,然后在HTML中通过

<script src="..."></script>来引入这个文件

<html>
  <head>
    <script src="/static/js/abc.js"></script>
  </head>
  <body>
    ...
  </body>
</html>

把JavaScript代码放入一个单独的.js文件中更利于维护代码,并且多个页面可以各自引用同一份.js文件

可以在同一页面中引入多个.js文件,还可以在页面中多次编写<script>js代码...</script>,浏览器按顺序依次执行

有时你也会看到<script>标签里还设置了一个type属性

<script type="text/javascript"></script>

其实这是没有必要的,因为默认的type就是Javascript,所以不必显式的指定它

基本语法

JavaScript中的每个语句都以;结束,语句块用{...}

完整的赋值语句:

var x = 1;

下面的一行代码是一个字符串,但也可以视为一个完整的语句

'Hello World!';

语法

JavaScript语法与Java类似,每个语句以;结束,语句块用{...}

下面的语句是一个完整的赋值语句:

var x = 1;

下面的代码表示一个字符串,但也可以被视为一个完整的语句

'Hello, World!';

注释

//开头直到行末的字符被视为行注释

// 这事一行注释
alert('hello');  //这也是注释

另一种注释是用/*...*/,它可以把多行字符包括起来

/* 从这里开始是块注释
仍然是注释
仍然是注释
注释结束*/

大小写

JavaScript严格区分大小写

数据类型

Number

JavaScript不区分整数和浮点数,统一使用Number表示

123; // 整数123
0.456; // 浮点数0.456
1.2345e3; // 科学计数法表示1.2345x1000,等同于1234.5
-99; // 负数
NaN; // NaN表示Not a Number,当无法计算结果时用NaN表示
Infinity; // Infinity表示无限大,当数值超过了JavaScript的Number所能表示的最大值时,就表示为Infinity

Number可以直接做四则运算,规则和数学一致

1 + 2; // 3
(1 + 2) * 5 / 2; // 7.5
2 / 0; // Infinity
0 / 0; // NaN
10 % 3; // 1,求余运算
10.5 % 3; // 1.5,求余运算

字符串

字符串是以单引号'或双引号"括起来的任意文本,比如'abc',"xyz"
等等

布尔值

布尔值和布尔代数的表示完全一致,一个布尔值只有truefalse
两种值,要么是true,要么是false

true; // 这是一个truefalse; // 这是一个false2 > 1; // 这是一个true2 >= 3; // 这是一个false

&&运算是与运算,只有所有都为true&&运算结果才是true

true && true; // 这个&&语句计算结果为true
true && false; // 这个&&语句计算结果为false
false && true && false; // 这个&&语句计算结果为false

||运算是或运算,只要其中有一个为true,||运算结果就是true

false || false; // 这个||语句计算结果为false
true || false; // 这个||语句计算结果为true
false || true || false; // 这个||语句计算结果为true

!运算是非运算,它是一个单目运算符,把true变成false,false变成true

! true; // 结果为false
! false; // 结果为true
! (2 > 5); // 结果为true

比较运算符

当我们对Number做比较时,可以通过比较运算符得到一个布尔值

实际上,JavaScript允许对任意数据类型做比较:

要特别注意相等运算符==,JavaScript在设计时,有两种比较运算符:

第一种是==比较,它会自动转换数据类型再比较,很多时候,会得到非常诡异的结果;

第二种是===比较,它不会自动转换数据类型,如果数据类型不一致,返回false,如果一致,再比较。

由于JavaScript这个设计缺陷,不要使用==比较,始终坚持使用===比较。

另一个例外是NaN,这个特殊的Number与所有其他值都不相等,包括它自己:

NaN === NaN; // false

唯一能判断NaN的方法是通过isNaN()函数:

isNaN(NaN); // true

null和undefined

null表示一个“空”的值,它和0以及空字符串''不同,0是一个数值,''表示长度为0的字符串,而null表示“空”。

在JavaScript中,还有一个和null类似的undefined,它表示“未定义”。

数组

数组是一组按顺序排列的集合,集合的每个值称为元素。JavaScript的数组可以包括任意数据类型

[1, 2, 3.14, 'Hello', null, true];

另一种创建数组的方法是通过Array()函数实现:

new Array(1, 2, 3); // 创建了数组[1, 2, 3]

数组的元素可以通过索引来访问。请注意,索引的起始值为0

var arr = [1, 2, 3.14, 'Hello', null, true];
arr[0]; // 返回索引为0的元素,即1
arr[5]; // 返回索引为5的元素,即true
arr[6]; // 索引超出了范围,返回undefined

对象

JavaScript的对象是一组由键-值组成的无序集合

var person = { 
  name: 'Bob', 
  age: 20, 
  tags: ['js', 'web', 'mobile'], 
  city: 'Beijing', 
  hasCar: true, 
  zipcode: null
};

JavaScript对象的键都是字符串类型,值可以是任意数据类型

要获取一个对象的属性,我们用对象变量.属性名的方式:

person.name; // 'Bob'
person.zipcode; // null

变量

变量在JavaScript中就是用一个变量名表示,变量名是大小写英文、数字、$_的组合,且不能用数字开头。变量名也不能JavaScript的关键字,如ifwhile等。申明一个变量用var语句

var a; // 申明了变量a,此时a的值为undefined
var $b = 1; // 申明了变量$b,同时给$b赋值,此时$b的值为1
var s_007 = '007'; // s_007是一个字符串
var Answer = true; // Answer是一个布尔值true
var t = null; // t的值是null

在JavaScript中,使用等号=对变量进行赋值。可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量,但是要注意只能用var申明一次

var a = 123; // a的值是整数123
a = 'ABC'; // a变为字符串

strict模式

如果一个变量没有通过var申明就被使用,那么该变量就自动被申明为全局变量

i = 10; // i现在是全局变量

为了修补JavaScript这一严重设计缺陷,ECMA在后续规范中推出了strict模式,在strict模式下运行的JavaScript代码,强制通过var申明变量,未使用var申明变量就使用的,将导致运行错误

启用strict模式的方法是在JavaScript代码的第一行写上

'use strict';

下面的代码测试你的浏览器是否支持strict模式

'use strict';
// 如果浏览器支持strict模式,
// 下面的代码将报ReferenceError错误:

abc = 'Hello, world';
alert(abc);

字符串

JavaScript的字符串就是用''""括起来的字符表示。

如果字符串内部既包含'又包含",可以用转义字符``来标识

多行字符串用\n来写,但在ES6中增加了``的方式来定义多行字符串

`这是一个
 多行
 字符串
`

常见的字符串操作如下:

  • 获取字符串长度
var s = 'Hello, World!';
s.length;  // 13
  • 获取字符串指定位置的字符,使用下标方式访问,索引从0开始
var s = 'Hello, World!';

s[0];  // 'H'
s[6];  // ' '
s[7];  // 'W'
s[13]; // undefined 超出范围的索引不会报错,但一律返回undefined

需要特别注意的是,字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果

  • toUpperCase()把一个字符串全部变为大写
var s = 'Hello';
s.toUpperCase();  // 'HELLO'
  • toLowerCase()把一个字符串全部变为小写
var s = 'Hello';
s.toLowerCase();  // 'hello'
  • indexOf()会搜索指定字符串出现的位置
var s = 'hello, world';
s.indexOf('world');  // 7
s.indexOf('World');  // 没有找到自定的子串,返回-1
  • substring()返回指定索引区间的子串
var s = 'hello, world';
s.substring(0, 5);  // 从索引0开始到5(不包括5), 返回'hello'
s.substring(7);  // 从索引7开始到结束, 返回'world'

数组

JavaScript的Array可以包含任意数据类型,并通过索引来访问每个元素

要得到Array的长度,使用length属性

var arr = [1, 2, 3.14, 'Hello', null, true];
arr.length; // 6

如果直接给Arraylength赋一个新值会导致Array大小发生变化

var arr = [1, 2, 3];
arr.length; // 3
arr.length = 6;
arr; // arr变为[1, 2, 3, undefined, undefined, undefined]
arr.length = 2;
arr; // arr变为[1, 2]

请注意,如果通过索引赋值时,索引超过了范围,同样会引起Array大小的变化:

var arr = [1, 2, 3];
arr[5] = 'x';
arr; // arr变为[1, 2, 3, undefined, undefined, 'x']

indexOf

Array也可以通过indexOf()来搜索一个指定的元素的位置:

var arr = [10, 20, '30', 'xyz'];
arr.indexOf(10); // 元素10的索引为0
arr.indexOf(20); // 元素20的索引为1
arr.indexOf(30); // 元素30没有找到,返回-1
arr.indexOf('30'); // 元素'30'的索引为2

slice

slice()就是对应Stringsubstring(),它截取Array的部分元素,然后返回一个新的Array:

var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
arr.slice(0, 3); // 从索引0开始,到索引3结束,但不包括索引3: ['A', 'B', 'C']
arr.slice(3); // 从索引3开始到结束: ['D', 'E', 'F', 'G']

如果不给slice()传递任何参数,它就会从头到尾截取所有元素。利用这一点,我们可以很容易地复制一个Array

var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
var aCopy = arr.slice();
aCopy; // ['A', 'B', 'C', 'D', 'E', 'F', 'G']
aCopy === arr; // false

push和pop

push()向Array的末尾添加若干元素,pop()则把Array的最后一个元素删除掉:

var arr = [1, 2];
arr.push('A', 'B'); // 返回Array新的长度: 4
arr; // [1, 2, 'A', 'B']
arr.pop(); // pop()返回'B'
arr; // [1, 2, 'A']
arr.pop(); arr.pop(); arr.pop(); // 连续pop 3次
arr; // []
arr.pop(); // 空数组继续pop不会报错,而是返回undefined
arr; // []

unshift和shift

如果要往Array的头部添加若干元素,使用unshift()方法,shift()方法则把Array的第一个元素删掉:

var arr = [1, 2];
arr.unshift('A', 'B'); // 返回Array新的长度: 4
arr; // ['A', 'B', 1, 2]
arr.shift(); // 'A'
arr; // ['B', 1, 2]
arr.shift(); arr.shift(); arr.shift(); // 连续shift 3次
arr; // []
arr.shift(); // 空数组继续shift不会报错,而是返回undefined
arr; // []

sort

sort()可以对当前Array进行排序,它会直接修改当前Array的元素位置,直接调用时,按照默认顺序排序:

var arr = ['B', 'C', 'A'];
arr.sort();
arr; // ['A', 'B', 'C']

reverse

reverse()把整个Array的元素给掉个个,也就是反转:

var arr = ['one', 'two', 'three'];
arr.reverse(); 
arr; // ['three', 'two', 'one']

splice

splice()方法是修改Array的“万能方法”,它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素:

var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只删除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不删除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']

concat

concat()方法把当前的Array和另一个Array连接起来,并返回一个新的Array

var arr = ['A', 'B', 'C'];
var added = arr.concat([1, 2, 3]);
added; // ['A', 'B', 'C', 1, 2, 3]
arr; // ['A', 'B', 'C']

join

join()方法是一个非常实用的方法,它把当前Array的每个元素都用指定的字符串连接起来,然后返回连接后的字符串:

var arr = ['A', 'B', 'C', 1, 2, 3];
arr.join('-'); // 'A-B-C-1-2-3'

多维数组

如果数组的某个元素又是一个Array,则可以形成多维数组,例如:

var arr = [[1, 2, 3], [400, 500, 600], '-'];

对象

JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成

var xiaoming = {
    name: '小明',
    birth: 1990,
    school: 'No.1 Middle School',
    height: 1.70,
    weight: 65,
    score: null
};

JavaScript用一个{...}表示一个对象,键值对以xxx: xxx形式申明,用,隔开

JavaScript规定,访问不存在的属性不报错,而是返回undefined:

var xiaoming = {
    name: '小明'
};
xiaoming.age; // undefined

由于JavaScript的对象是动态类型,你可以自由地给一个对象添加或删除属性:

var xiaoming = {
    name: '小明'
};
xiaoming.age; // undefined
xiaoming.age = 18; // 新增一个age属性
xiaoming.age; // 18
delete xiaoming.age; // 删除age属性
xiaoming.age; // undefined
delete xiaoming['name']; // 删除name属性
xiaoming.name; // undefined
delete xiaoming.school; // 删除一个不存在的school属性也不会报错

如果我们要检测xiaoming是否拥有某一属性,可以用in操作符:

var xiaoming = {
    name: '小明',
    birth: 1990,
    school: 'No.1 Middle School',
    height: 1.70,
    weight: 65,
    score: null
};
'name' in xiaoming; // true
'grade' in xiaoming; // false

in操作符并不准确,因为访问的属性可能是当前对象继承而来的

要判断一个属性是否是xiaoming自身拥有的,而不是继承得到的,可以用hasOwnProperty()方法:

var xiaoming = {
    name: '小明'
};
xiaoming.hasOwnProperty('name'); // true
xiaoming.hasOwnProperty('toString'); // false

条件判断

JavaScript使用if () { ... } else { ... }来进行条件判断

var age = 20;
if (age >= 18) { // 如果age >= 18true,则执行if语句块
    alert('adult');
} else { // 否则执行else语句块
    alert('teenager');
}

请永远都是写上{ }

多行条件判断

如果还要更细致地判断条件,可以使用多个if...else...的组合:

var age = 3;
if (age >= 18) {
    alert('adult');
} else if (age >= 6) {
    alert('teenager');
} else {
    alert('kid');
}

循环

JavaScript的循环有两种,一种是for循环,通过初始条件、结束条件和递增条件来循环执行语句块:

var x = 0;
var i;
for (i=1; i<=10000; i++) {
    x = x + i;
}
x; // 50005000

for循环最常用的地方是利用索引来遍历数组:

var arr = ['Apple', 'Google', 'Microsoft'];
var i, x;
for (i=0; i<arr.length; i++) {
    x = arr[i];
    alert(x);
}

for...in

for循环的一个变体是for ... in循环,它可以把一个对象的所有属性依次循环出来:

var o = {
    name: 'Jack',
    age: 20,
    city: 'Beijing'
};
for (var key in o) {
    alert(key); // 'name', 'age', 'city'
}

要过滤掉对象继承的属性,用hasOwnProperty()来实现:

var o = {
    name: 'Jack',
    age: 20,
    city: 'Beijing'
};
for (var key in o) {
    if (o.hasOwnProperty(key)) {
        alert(key); // 'name', 'age', 'city'
    }
}

由于Array也是对象,而它的每个元素的索引被视为对象的属性,因此,for ... in循环可以直接循环出Array的索引:

var a = ['A', 'B', 'C'];
for (var i in a) {
    alert(i); // '0', '1', '2'
    alert(a[i]); // 'A', 'B', 'C'
}

while

while循环只有一个判断条件,条件满足,就不断循环,条件不满足时则退出循环

var x = 0;
var n = 99;
while (n > 0) {
    x = x + n;
    n = n - 2;
}
x; // 2500

do ... while

do { ... } while()循环,它和while循环的唯一区别在于,不是在每次循环开始的时候判断条件,而是在每次循环完成的时候判断条件:

var n = 0;
do {
    n = n + 1;
} while (n < 100);
n; // 100

Map和Set

JavaScript的默认对象表示方式{}可以视为其他语言中的MapDictionary的数据结构,即一组键值对

但JavaScript的对象中的键必须是字符串,实际上它可以是Number或其他数据类型

为了解决这个问题,ES6引入了新的数据类型Map,下面的代码可以测试浏览器是否支持

'use strict';
var m = new Map();
var s = new Set();
alert('你的浏览器支持Map和Set');

Map

Map是一组键值对的结构,具有极快额查找速度

在JavaScript中实现一个Map结构如下:

var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael');        //95

初始化Map需要一个二维数组,或者直接初始化一个空的Map,下面是它具有的方法:

var m = new Map();            //初始化一个空的Map
m.set('Adam', 67);            //添加新的key-value
m.set('Bob', 59);
m.has('Adam');                //判断是否存在key:‘Adam’,返回true
m.get('Adam');                //67
m.delete('Adam');             //删除key:'Adam'
m.get('Adam');                //undefined

一个key只能对应一个value,所以,多次给一个key赋值,会把前面的覆盖掉

var m = new Map();
m.set('Adam', 67);
m.set('Adam', 88);
m.get('Adam');         //88

Set

SetMap类似,也是一组key的集合,但不存储value,它里面没有重复的key

要创建一个Set,需要提供一个Array并输入,或者可以直接定义一个空的Set

var s1 = new Set([1, 2, 3]);
var s2 = new Set();

重复的key会在Set中被自动过滤掉,使用add和delete方法来给Set添加和删除元素

var s = new Set();
s.add(4);
var s = new Set([1, 2, 3]);
s;        //Set {1, 2, 3}
s.delete(3);
s;        //Set {1, 2}

Iterable

ES6引入了新的iterable类型,Array,Map,Set都属于iterable类型

具有iterable类型的集合可以通过新的for...of循环来遍历,它是ES6引入的新语法

通过下面的代码来测试你的浏览器是否支持

'use strict';
var a = [1, 2, 3];
for(let x of a) {}

alert('你的浏览器支持for...of语法');

for...of循环遍历集合

var a = ['A', 'B', 'C'];
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
var s = new Set(['A', 'B', 'C']);
for(let x of a) {        //遍历Array
  console.log(x);
}

for(let x of s) {        //遍历Set
  console.log(x);    
}

for(let x of m) {        //遍历Map
  console.log(x[0] + '=' + x[1]);
}

for...offor...in有什么区别呢?

for...in循环由于历史问题,实际上它遍历的是对象的属性名称,那么Array也是一种对象,Array的每个元素的下标被视为属性,当我们手动给Array添加了额外的元素后,for...in循环会出现额外的情况

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for(var x in a) {
  console.log(x);        //0, 1, 2, name
}

for...of循环解决了这个问题,它只遍历集合本身的元素

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for(var x of a) {
  console.log(x);        //'A','B','C'
}

在iterable中,还有一个内置方法forEach,它接收一个函数,每次迭代就自动回调该函数

var a = ['A', 'B', 'C'];
a.forEach(function(element, index, array) {
    //element:指向当前元素的值
    //index: 指向当前索引
    //arrya: 指向Array对象本身
    console.log(element);
});

forEach方法是ES5.1标准引入的。

SetArray类似,但Set没有索引,因此回调函数的前两个参数都是元素本身

var s = new Set(['A', 'B', 'C']);
s.forEach(function(element, sameElement, set) {
  console.log(element);
});

Map的回调参数依次为valuekeymap本身

var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function(value, key, map) {
  console.log(value);
});

forEach的回调函数中的参数不必全部写完,如只需要Array的元素值

var a = ['A', 'B', 'C'];
a.forEach(function(element) {
  console.log(element);
});
from: http://www.jianshu.com/p/80b612534691
展开阅读全文

没有更多推荐了,返回首页