前言:
最近在前端这块,发现自己生疏了,连最基本的js都忘的差不多了。于是趁着周末,参考了廖雪峰老师的JS教程以及自己对JS的理解,重新梳理了一遍。如果有什么错误还请大家及时指出。
一.js的历史:略过
二.js的规范及版本:
说起javascript,不得不提ECMAScript,ECMA(European Computer Manufacturers Association)组织定制了JavaScript语言的标准,被称为ECMAScript标准。
目前最新版本2017年发布的ES7.0 ,但是现在用的最多的还是ES5.1,以及2015年发布的ES6.0(其实也不多)。我们学习还是以ES5.1为主,附带学习一些ES6.0的新特性。
三.js的位置:理论上可以放在html的任意位置,但常见的有2种放法
1.</head>标签内(不推荐):我们知道,服务器返回一个html文件,浏览器首先会将html文件装载至内存,生成dom tree,然后自上而下解析,遇到<script>标签时,浏览器马上会执行,执行时会阻塞页面后续的内容(包括页面的渲染、其它资源的下载)。因为浏览器需要一个稳定的DOM树结构,而js中很有可能有代码直接改变了DOM树结构,比如使用 document.write 或 appendChild。所以需要重新构建DOM树。不过我们可以在<script>标签上使用defer="defer"属性,告诉浏览器延迟加载js,就不会阻塞页面后续dom的解析。遗憾的是这个属性只有部分浏览器支持。(IE,FireFox)
2.</body>标签前(推荐):这种方式,dom tree 已经解析完毕。此时执行脚本不会改变dom树的原有的结构。
四.js的三大组成部分:
1.ECMAScript:这是JS的核心。很好理解,javascript是ES的一个实现,它遵从ES的标准。ES定义了JS的基本语法,JS的数据类型等等。
2.DOM(文档对象模型):DOM是 HTML 和 XML 的应用程序接口,也就是对节点的操作。
3.BOM(浏览器对象模型):JS是运行在浏览器上,BOM是其对浏览器窗口进行访问和操作接口。
五.JavaScript的数据类型
1.Number(数值型):JavaScript不区分整数和浮点数,统一用Number表示。其中也包含NaN(Not A Number) ,Infinity(无限大)以及十六进制数(0x开头)。
2.字符串(' '," "):被单引号或双引号包含的任意字符。推荐使用双引号。如果要表示',可以使用\进行转义,常见的转义符有:\n表示换行,\t表示制表符。多个字符串之间可以使用+拼接。在ES6标准中,使用了一种模版字符串进行拼接${字符串},类似于java中的El表达式。
JS中,字符串也是不可变的(和java中的String类一样),常用的字符串方法有:
a.toUpperCase():把字符串a全部变为大写
a.toLowerCase():把字符串a全部变为小写
a.indexOf(str):返回字符串str在字符串a的位置,索引从0开始,没有则返回-1
a.substring(index1,[index2]):返回字符串a在index1和indexe2中的子串,索引从0开始,不包含index2.
a.substr(index,[length]):两个参数都为正,返回字符串a从index开始length个的子串。索引从0开始,length参数可选,不写则返回index到a结尾的子串(不推荐)
a.slice(start,end); 两个参数可正可负,正值代表从左截取,负值代表从右截取,返回值:[start,end)的字符串
charAt(index):返回index下标处的字符串;
a.split(separator,limit):字符串分割为数组,参数1指定字符串或正则表达式,参数2指定数组的最大长度(若用于数组);
arr.join(separator):数组连接成字符串,参数为连接符。
str.replace(rgExp/substr,replaceText) 替换字符串,返回替换后的字符串,参数1是替换前的字符串,参数2是替换后的字符串
str.match(rgExp); 匹配给定的正则表达式,返回true或false;
看完发现基本上和java就是一毛一样啊,嗯,oracle估计要将JavaScript团队告上法庭,原因是JS很多方法侵犯了Java的版权(滑稽脸 =.=)
3.Boolean(布尔值):true 和 flase 判断时用
4.null和undefined:表示空和未定义,差别不是很大,我们一般用null就行,判断参数是否传递可以用underfined
5.数组:创建数组可以使用[]和 new Array(),但我们一般都用前者。数组的索引从0开始(同java数组),如果访问超出索引的元素,返回underfined.例:var arr = [1, 2, 3.14, 'Hello', null, true];数组的长度可以用length属性获取。常用的数组方法:
基本方法:
arr.toLocaleString():返回数组的本地字符串形式,用,分开每个元素;
arr.toString():返回数组的字符串形式,用,分开每个元素;
arr.valueOf():返回Array[length];
栈方法(先进后出):
arr.push():向数组末尾添加新的元素,返回的是数组新的长度,不会创建新的数组;
arr.pop():删除数组最后一个元素并且返回该元素。如果数组为空就返回undefined,不会创建新的数组;
队列方法:(先进先出):
arr.shift():删除数组中第一个元素,返回第一个元素的值。该方法会改变原数组的长度,不会创建新的数组
arr.unshift():,向数组头部添加元素,返回的是新数组的长度,不会创建新的数组;
排序方法:
arr.reverse():返回反转的数组;
arr.sort():按照升序排列数组,内部会调用toString()方法;
实例如下:
function compare(value1, value2) {
if (value1 < value2) {
return -1;
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
};
var values = [0, 1, 2, 5, 10, 15];
values.sort(compare);
alert(values); //0,1,5,10,15
操作方法:
arr.concat(arr1):连接2个数组,返回新的连接后的数组;
arr.splice(index,howmany,[element1],.....,[elementX]):可用于插入、删除或替换数组的元素;
具体如下:
删除(index,howmany):要删除的第一项的位置和要删除的项数。
var colors = ["red", "green", "blue"];
var removed = colors.splice(0,1);
console.log(colors); // greeen, blue
console.log(removed); // red
添加(index,howmany,element1):起始位置、0(要删除的项数)和要插入的项
var colors = ["red", "green", "blue"];
var removed = colors.splice(1,0,"yellow", "orange");
console.log(colors); // ["red", "yellow", "orange", "green", "blue"]
console.log(removed); // []
替换(index,howmany,element1.....elementX):起始位置、要删除的项数和要插入的任意数量的项
var colors = ["red", "green", "blue"];
var removed = colors.splice(1,1,"yellow", "orange");
console.log(colors); // ["red", "yellow", "orange", "blue"]
console.log(removed); // ["green"]
arr.indexOf(element):同字符串的indexOf()方法;
arr.slice(index1,index2):同字符串的slice()方法,返回一个新的数组;
arr.join(separator):按照指定的字符串拼接数组元素,返回拼接后的字符串
Tips:多维数组:即数组的元素又是一个数组:例如,
var arr = [[1, 2, 3], [400, 500, 600], '-'];
这时可以通过多个下标进行访问:var one = arr[0][1]//2
6.对象:JS的对象由键—值对组成,key是字符串类型,value可以是任意类型。
例:var person = {
name: 'Bob',
age: 20,
tags: ['js', 'web', 'mobile'],
city: 'Beijing',
hasCar: true,
zipcode: null
};
访问对象的属性可以用对象名.属性名:person.name
JS的对象可以动态赋值,例如:
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; // undefined
7.变量:JS中申明一个变量用var关键字,注意,JS是弱类型语言,变量可以赋不同类型的值,例:var a = 3 ,a = "3"也是可以的。
六.JS的运算符
基本同java, 常见的有:+,-,*,/,%,&&,||,!,==,===
其中:== 和 ===是有一定区别的,
我们如果是仅仅比较String,Number 的值,还是用==,比较对象等高级数据类型,用===.
另外唯一能判断NaN的方法是通过isNaN()函数: NaN===NaN //false
isNaN(NaN)//true
另外:JS把null、undefined、0、NaN和空字符串''视为false,其他值一概视为true;
七:JS中的基本弹框:
alert(); 弹出个提示框 (确定)
confirm(); 弹出个确认框 (确定,取消)
prompt(); 弹出个输入框 让用户输入东西
八.strict模式
这是由于JS的早期的一个BUG,如果申明变量不适用var关键字,该变量是一个全局变量,后来ES对其修复,在JS的第一行写上:'use strict';
现在多数浏览器都支持这个标准,我们最好也按这个来。
九:JS的循环:
1.普通for循环,for(;;)
var x = 0;
var i;
for (i=1; i<=10000; i++) {
x = x + i;
}
x; // 50005000
2.for ... in循环:
1>.循环对象
var o = {
name: 'Jack',
age: 20,
city: 'Beijing'
};
for (var key in o) {
console.log(key); // 'name', 'age', 'city'
}
2>循环数组
var a = ['A', 'B', 'C'];
for (var i in a) {
console.log(i); // '0', '1', '2'
console.log(a[i]); // 'A', 'B', 'C'
}
3.while循环:
var x = 0;
var n = 99;
while (n > 0) {
x = x + n;
n = n - 2;
}
x; // 2500
4.do...while循环:
var n = 0;
do {
n = n + 1;
} while (n < 100);
n; // 100
用法基本同java,没什么好讲的
十.Map(ES6新增):一组键值对的集合,键不能重复
'use strict';
var m = new Map();
var s = new Set();
console.log('你的浏览器支持Map和Set!');
1.Map的创建与基本方法:
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95
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
var m = new Map();
m.set('Adam', 67);
m.set('Adam', 88);
m.get('Adam'); // 88
没什么好说的,代码说话
十一:Set:一组key的集合,key不能重复。
var s1 = new Set(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3
var s = new Set([1, 2, 3, 3, '3']);
s; // Set {1, 2, 3, "3"}
s.add(4);
s; // Set {1, 2, 3, 4}
s.add(4);
s; // 仍然是 Set {1, 2, 3, 4}
var s = new Set([1, 2, 3]);
s; // Set {1, 2, 3}
s.delete(3);
s; // Set {1, 2}
没什么好说的。。。
十二.iterable:(ES6新增):我怎么感觉就是抄袭java的呢?Map,Set,Iterable,就差个List了。。。
for ... of循环(ES6新增):
'use strict';
var a = [1, 2, 3];
for (var x of a) {
}
console.log('你的浏览器支持for ... of');
var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍历Array
console.log(x);
}
for (var x of s) { // 遍历Set
console.log(x);
}
for (var x of m) { // 遍历Map
console.log(x[0] + '=' + x[1]);
}
for...in 与for...of的区别:一个Array数组实际上也是一个对象.
var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
console.log(x); // '0', '1', '2', 'name'
}
var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x of a) {
console.log(x); // 'A', 'B', 'C'
}
forEach()循环(ES5.1):看到这里,我不得不怀疑JS和java的关系了。。。常威,你还说你不会武功!!!
'use strict';
var a = ['A', 'B', 'C'];
a.forEach(function (element, index, array) {
// element: 指向当前元素的值
// index: 指向当前索引
// array: 指向Array对象本身
console.log(element + ', index = ' + index);
});
循环Set:Set没有索引,因此回调函数的前两个参数都是元素本身:
var s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
console.log(element);
});
循环Map:Map的回调函数参数依次为value、key和map本身
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
console.log(value);
});
先写这么多。。。收工ING