1.JavaScript是什么?
JavaScript是一门运行在浏览器端的脚本语言。
2.javaScript的类型
分为:基本数据类型 :number string boolean undefined null
引用类型: object(array function)
强制转换
使用Boolean()、Number()、String()或Object函数
在转换数值的时候,parseInt()和parseFloat()函数更加灵活。
在使用Boolean(),Number(),String()函数时,函数的首字母必须大写
3.对象
new Date()
Math.... Math.floor()向下取整 Math.ceil()向上取整 Math.round() 四舍五入 Math.random()随机数
4.数组
添加: push() unshift() 返回值为都新数组的长度
删除: pop() shift() 返回值为删除的元素
截取: slice(0, 3) 从0-2
搜索: indexOf 搜索指定的元素的位置 一旦找不到返回-1
排序: sort(gg) function gg(a,b) { return b-a}
连接: join() 将数组中的元素连接成一个字符串
倒置: reverse()
合并: concat( ) arr1.concat(arr2)
万能: splice(开始位置, 个数,添加的内容)
5.字符串
toUpperCase()
把一个字符串全部变为大写
toLowerCase()
把一个字符串全部变为小写
ü 字符串连接 -- concat
ü 查找 -- charAt、charCodeAt、indexOf、lastIndexOf、search
ü 截取 -- substr、substring、slice
substr(start, length), 第一个参数表示开始位置,第二个参数表示截取的长度
substring(start, stop), 第一个参数表示开始位置,第二个参数表示结束位置
slice(0, 3) 从0-2ü 大小写转换 -- toLowerCase、toUpperCase、
ü 替换 -- replace
ü 转数组 -- split s4.split(',')
6.对象
JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成
如果我们要检测xiaoming
是否拥有某一属性,可以用in
操作符
要判断一个属性是否是xiaoming
自身拥有的,而不是继承得到的,可以用hasOwnProperty()
方法
7.map set
Map
是一组键值对的结构,具有极快的查找速度。
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95
Set
和
Map
类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在
Set
中,没有重复的key。
通过add(key)
方法可以添加元素到Set
中, 通过delete(key)
方法可以删除元素
遍历Array
可以采用下标循环,遍历Map
和Set
就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable
类型,Array
、Map
和Set
都属于iterable
类型。
具有iterable
类型的集合可以通过新的for ... of
循环来遍历。
var a = ['A', 'B', 'C'];
a.forEach(function (element) {
alert(element);
});
8.事件
JavaScript还有一个免费赠送的关键字arguments
,它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。
arguments
类似Array
但它不是一个Array。
rest参数只能写在最后,前面用...
标识,从运行结果可知,传入的参数先绑定a
、b
,多余的参数以数组形式交给变量rest
,所以,不再需要arguments
我们就获取了全部参数。
如果传入的参数连正常定义的参数都没填满,也不要紧,rest参数会接收一个空数组
9.高阶函数ES6标准引入了新的关键字const
来定义常量,const
与let
都具有块级作用域
在一个对象中绑定函数,称为这个对象的方法。
apply
虽然在一个独立的函数调用中,根据是否是strict模式,this
指向undefined
或window
,不过,我们还是可以控制this
的指向的!
要指定函数的this
指向哪个对象,可以用函数本身的apply
方法,它接收两个参数,第一个参数就是需要绑定的this
变量,第二个参数是Array
,表示函数本身的参数。
另一个与apply()
类似的方法是call()
,唯一区别是:
-
apply()
把参数打包成Array
再传入; -
call()
把参数按顺序传入。
比如调用Math.max(3, 5, 4)
,分别用apply()
和call()
实现如下:
Math.max.apply(null, [3, 5, 4]); // 5
Math.max.call(null, 3, 5, 4); // 5
利用apply()
,我们还可以动态改变函数的行为。
JavaScript的所有对象都是动态的,即使内置的函数,我们也可以重新指向新的函数。
现在假定我们想统计一下代码一共调用了多少次parseInt()
,可以把所有的调用都找出来,然后手动加上count += 1
,不过这样做太傻了。最佳方案是用我们自己的函数替换掉默认的parseInt()
:
var count = 0;
var oldParseInt = parseInt; // 保存原函数
window.parseInt = function () {
count += 1;
return oldParseInt.apply(null, arguments); // 调用原函数
};
// 测试:
parseInt('10');
parseInt('20');
parseInt('30');
count; // 3
由于map()
方法定义在JavaScript的Array
中,我们调用Array
的map()
方法,传入我们自己的函数,就得到了一个新的Array
作为结果:
function pow(x) {
return x * x;
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce
再看reduce的用法。Array的reduce()
把一个函数作用在这个Array
的[x1, x2, x3...]
上,这个函数必须接收两个参数,reduce()
把结果继续和序列的下一个元素做累积计算,其效果就是:
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x + y;
}); // 25
要把[1, 3, 5, 7, 9]
变换成整数13579,reduce()
也能派上用场:
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x * 10 + y;
}); // 13579
filter也是一个常用的操作,它用于把Array
的某些元素过滤掉,然后返回剩下的元素。
和map()
类似,Array
的filter()
也接收一个函数。和map()
不同的是,filter()
把传入的函数依次作用于每个元素,然后根据返回值是true
还是false
决定保留还是丢弃该元素。
例如,在一个Array
中,删掉偶数,只保留奇数,可以这么写:
var arr = [1, 2, 4, 5, 6, 9, 10, 15];
var r = arr.filter(function (x) {
return x % 2 !== 0;
});
r; // [1, 5, 9, 15]
10.闭包
返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量
如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变
function count() {
var arr = [];
for (var i=1; i<=3; i++) {
arr.push((function (n) {
return function () {
return n * n;
}
})(i));
}
return arr;
}
var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
f1(); // 1
f2(); // 4
f3(); // 9
闭包就是携带状态的函数,并且它的状态可以完全对外隐藏起来。
11.箭头函数
var fn = x => x * x;
(x, y) => x * x + y * y
如果要返回一个对象,就要注意,如果是单表达式
x => ({ foo: x })
12.generator
generator(生成器)是ES6标准引入的新的数据类型。一个generator看上去像一个函数,但可以返回多次
function* fib(max) {
var
t,
a = 0,
b = 1,
n = 1;
while (n < max) {
yield a;
t = a + b;
a = b;
b = t;
n ++;
}
return a;
}
直接调用试试:
fib(5); // fib {[[GeneratorStatus]]: "suspended", [[GeneratorReceiver]]: Window}
调用generator对象有两个方法,一是不断地调用generator对象的
next()
方法:
var f = fib(5);
f.next(); // {value: 0, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 2, done: false}
f.next(); // {value: 3, done: true}
第二个方法是直接用for ... of
循环迭代generator对象,这种方式不需要我们自己判断done
:
for (var x of fib(5)) {
console.log(x); // 依次输出0, 1, 1, 2, 3
}
generator还有另一个巨大的好处,就是把异步回调代码变成“同步”代码。
12.正则
\d
可以匹配一个数字,\w
可以匹配一个字母或数字 \s 匹配空格
用*
表示任意个字符(包括0个),用+
表示至少一个字符,用?
表示0个或1个字符,用{n}
表示n个字符,用{n,m}
表示n-m个字符:
^
表示行的开头,^\d
表示必须以数字开头。
$
表示行的结束,\d$
表示必须以数字结束。
JavaScript的正则表达式还有几个特殊的标志,最常用的是g
,表示全局匹配
还可以指定i
标志,表示忽略大小写,m
标志,表示执行多行匹配
var re = /^\d{3}\-\d{3,8}$/;
re.test('010-12345'); // true
re.test('010-1234x'); // false
re.test('010 12345'); // false
'a b c'.split(/\s+/); // ['a', 'b', 'c']
'a,b;; c d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd']
分组
除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()
表示的就是要提取的分组(Group)。比如:
^(\d{3})-(\d{3,8})$
分别定义了两个组,可以直接从匹配的字符串中提取出区号和本地号码:
var re = /^(\d{3})-(\d{3,8})$/;
re.exec('010-12345'); // ['010-12345', '010', '12345']
re.exec('010 12345'); // null
贪婪匹配
需要特别指出的是,正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。举例如下,匹配出数字后面的0
:
var re = /^(\d+)(0*)$/;
re.exec('102300'); // ['102300', '102300', '']
由于\d+
采用贪婪匹配,直接把后面的0
全部匹配了,结果0*
只能匹配空字符串了。
必须让\d+
采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0
匹配出来,加个?
就可以让\d+
采用非贪婪匹配:
var re = /^(\d+?)(0*)$/;
re.exec('102300'); // ['102300', '1023', '00']
13.JSON
JSON是JavaScript Object Notation的缩写,它是一种数据交换格式
JSON还定死了字符集必须是UTF-8,表示多语言就没有问题了。为了统一解析,JSON的字符串规定必须用双引号""
,Object的键也必须用双引号""
。
序列化
var xiaoming = {
name: '小明',
age: 14,
gender: true,
height: 1.65,
grade: null,
'middle-school': '\"W3C\" Middle School',
skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};
JSON.stringify(xiaoming); // '{"name":"小明","age":14,"gender":true,"height":1.65,"grade":null,"middle-school":"\"W3C\" Middle School","skills":["JavaScript","Java","Python","Lisp"]}'
JSON.stringify(xiaoming, null, ' ');
第二个参数用于控制如何筛选对象的键值,如果我们只想输出指定的属性,可以传入Array
:
JSON.stringify(xiaoming, ['name', 'skills'], ' ');
{
"name": "小明",
"skills": [
"JavaScript",
"Java",
"Python",
"Lisp"
]
}
反序列化
拿到一个JSON格式的字符串,我们直接用JSON.parse()
把它变成一个JavaScript对象: