PS:对象要多看几遍,还有闭包等函数要多看几遍。
一、数据类型:
整数、浮点、科学计数法、NaN、Infinity。
//关于NaN
NaN == NaN; //false
NaN === NaN; //false
isNaN(NaN); // true
//关于数组
var arr_1 = []; //空数组
var arr_2 = new Array(); //空数组
var arr1 = ['A', 'B', 'C'];
var arr2 = new Array('A', 'B', 'C'); // 创建了数组['A', 'B', 'C'];
arr2[1]; //'B'
arr1.length; //3
arr1.indexOf('B'); //1, 返回元素的索引。
arr1.slice(1,3); //['B', 'C'], 从索引1开始,到索引3但不包括索引3.
arr1.slice(); //复制数组
arr1.push('D'); //从尾部添加'D'
arr1.unshift('D'); //从头部添加'D'
arr1.pop(); //删除尾部的一个元素,并且返回删除的元素。
arr1.shift(); //从头部删除一个元素,并且返回删除的元素。
arr1.sort(); //排序。
arr1.reverse(); //反转数组的元素。
arr1.splice(2,3,'M','N','P'); //从索引2开始删除3个元素,并且加上'M','N','P'元素。
arr1.splice(1,2); //从索引1开始删除2个元素。并且返回删除的元素组成的数组。
arr1.join('--'); //'A--B--C', 将元素组成字符串,并且用指定字符串连结。
var new_arr1 = arr1.concat([1,2,3,4]); //拼接2个数组,并且赋给新数组,并且arr1数组不变化。
var new_arr1 = arr1.concat([1,2],3,4); //新数组:['A', 'B', 'C',1,2,3,4];, 注意拆分。
//关于对象,数据集合,key-value
var phper = { //对象
job:'PHPer',
age:26,
hasCar:true,
'my-love':'AnHui' //属性名有特殊字符时,使用' '括起来。
};
phper.age; 或者 phper['age']; //26
phper['my-love']; //'AnHui',对于有特殊字符的属性,只能这样。
'Wife' in phper; //false, 检查该对象,以及该对象继承的对象中是否有这个属性,注意所有对象最终都会在原型链上指向object。
phper.hasOwnProperty('Wife'); //检查该对象是否有这个属性,而不是继承来的属性(不考虑继承的对象中是否有这个属性)。
//关于严格模式
'use strict'; //代码第一行写入,表示严格模式。
//关于字符串;
var str = 'Hello, world!';
str.length; //13
str[1]; //'e'
str.toUpperCase(); //'HELLO, WORLD!'
str.toLowerCase(); //'hello, world!'
str.substring(7, 12); //索引从7开始,不包括12, ‘world’
str.substring(7); //索引从7开始到结束,'world!'
二、关于循环:
//for循环
for (var i = 0; i < Things.length; i++) {
Things[i]
}
//for...in...循环:可以用于对象和数组(数组也是一种对象),
//对象循环出属性字符串,数组循环出索引字符串。
var aboutme={
name:'ChenJian',
age:26,
job:'PHPer'
}
for (var key in aboutme){
console.log(key); //'name','age','job'
}
//while循环。
var i = 1;
var x = 0;
while(i<100){
x = x + i;
i+=2;
}
console.log(x); //2500
//do...while..,至少会执行一次。
var x=4;
do{
console.log(x);
x+=1;
}while(x<1)
三、Map
, Set
,iterable
:
Map: JS中对象的属性只支持字符串不支持数字,于是ES6中引入Map。Map也是一对键值对,参数是二位数组。
Set:一组key的集合,但是没有value,且key不能重复。
iterable: Array可以通过下表来遍历,但是Map和Set不可以,于是ES6中引入iterable类型,用来遍历Map和Set。Array
,Map
,Set
都是iterable类型,都可以使用for..of..
来遍历。
forEach():iterable
的内置方法,可以用来遍历Array、Map、Set。接收一个方法,
var map0 = new Map(); //空Map
var map1 = new Map([['Suan',24],['Lucy',25],['Mary',26]]); //参数必须是二维参数
sonsole.log(map1); //Map {"Suan" => 24, "Lucy" => 25, "Mary" => 26}
map1.get('Mary'); //取值
map1.set('Aston', 27); //赋值
map1.has('Lucy'); //检测是否有'Lucy'属性,true Or false
map1.delete('Suan'); //删除某个属性。
var set1 = new Set();
var set2 = new Set([1,2,3,4,4,5]); //key不能重复,参数为一维数组。{1,2,3,4,5}
set2.add(6); //加一个元素
set2.delete(3); //删一个元素
var arr1 = ['A','B','C'];
var set1 = new Set(['A','B','C']);
var map1 = new Map([['Suan',24],['Lucy',25],['Mary',26]]);
for (var a of arr1){
console.log(a); //'A','B','C'
}
for (var s of set1){
console.log(s); //'A','B','C'
}
for (var m of map1){
console.log(typeof m); //Object, ["Suan", 24], ["Lucy", 25], ["Mary", 26]
console.log(m[0]); //String, '24','25','26'
console.log(m[1]); //String,"Suan", "Lucy", "Mary"
}
var arr1 = ['A','B','C'];
var set1 = new Set(['A','B','C']);
var map1 = new Map([['Suan',24],['Lucy',25],['Mary',26]]);
arr1.forEach(function(element,index,arr){
console.log(element);
console.log(index);
console.log(arr);
});
set1.forEach(function(element){
console.log(element); //'A','B','C'
});
map1.forEach(function(value,key,map){
console.log(value);
console.log(key);
console.log(map);
});
四、函数Function。
函数体内有个
arguments
关键字,用来指向传入的参数,类似Array,但不是Array,arguments.length
,arguments[i]
.
函数体内还有个
reset
关键字,接收多余的参数,使用如下:
function sth(a1, a2, ...reset) {
console.log(reset); //["c", "d"]
}
sth('a','b','c','d')
五、window
对象,
1 . JS默认的一个全局变量。
2 .不在任何函数内定义的变量就具有全局作用域。
3 .关于ES6中引入的关键字let
,解决了块级作用域:
for (let i = 0; i < 8; i++) {
console.log(i);
}
console.log(i); //Uncaught ReferenceError: i is not defined
//因为`let i` 声明i为块级的,如果`var i`,那么console.log(i); 就是8.
4 .const
, ES6中引入关键字const
,用来声明常量(不可变)。const PI = 3.14;
5 . this
,关于对象体内的this指向不明问题,尤其是在函数内使用this会导致指向不明,最好先捕获,var that = this;
. 或者使用apply
或者call
来声明,
apply()
, 用于函数,接收2个参数,参数1指向你想指向的对象,参数2是函数要接受的参数数组,可以为空。
call()
,类似apply()
,不同的是函数要接受的参数不是数组了,而是参数顺序。
'use strict';
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var aboutme = {
name: 'ChenJian',
birth: 1990,
age: getAge
};
console.log(aboutme.age()); // 25, 正常输出。
console.log(getAge()); //Uncaught TypeError: Cannot read property 'birth' of undefined
console.log(getAge.apply(aboutme,[])); //使用apply,指定getAge方法的this对象。
或者
console.log(getAge.call(aboutme, 参数1, 参数2, 参数3..));
六、高阶函数(High Order Function): 函数接受另外一个函数为参数。
function other(v) {
return v+'...';
}
function high(a, b, func) {
return func(a)+func(b);
}
console.log(high('chen', 'jian', other)); //chen...jian...
//map():Array.map(function_name);。对每个元素进行处理,组成新的Array。[x1, x2, x3, x4].map(f) = [f(x1), f(x2), f(x3), f(x4)]
var arr = [1,2,3,4,5,6];
function abss(v) {
return v*v;
}
console.log(arr.map(abss)); //[1,4,9,25,36]
//reduce():Array.reduce(function_name);。将x1、x2进行处理,组成新元素再和后继的元素继续处理。[x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)
var arr = [1,2,3];
function add(v, w) {
return v*w;
}
console.log(arr.reduce(add)); //6
//filter():Array.filter(function_name); 过滤Array中的元素。
var arr = ['A', 'B', 2];
function filter_digital(v){
return typeof v != 'number';
}
console.log(arr.filter(filter_digital)); // ['A', 'B']
//sort();给Array排序,原数组会被改变。但是有个坑:会把元素转换为字符串然后排序,导致如下神奇的效果:
var arr = [1, 20, 10, 2];
console.log(arr.sort()); //[1,10,2,20]
function sort_digital(x, y){
if (x > y) {
return true;
}else{
return false;
}
}
console.log(arr.sort(sort_digital)); //正确:[1,2,10,20]
七、闭包。
//返回函数
function lazy_sum(arr) {
var sum = function () {
return arr.reduce(function (x, y) {
return x + y;
});
}
return sum;
}
var arr = [1,2,3,4,5,6];
console.log(lazy_sum(arr)); //function(){....} , 返回函数。
console.log(lazy_sum(arr)()); //21
function count() {
var arr = [];
for (var i=1; i<=3; i++) {
arr.push(function () {
return i * i;
});
}
return arr;
}
console.log(count());
//箭头函数
var y = x => x*x;
console.log(y(3)); //9
八、generator(生成器):ES6中引入的新类型。l类似于函数可以多次返回:
//大致的定义:
function* foo(x) {
yield x + 1;
yield x + 2;
return x + 3;
}
//使用
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;
}
//1.使用next()取出generator里面的值。
var f = fib(5);
console.log(f); //fib {[[GeneratorStatus]]: "suspended", [[GeneratorReceiver]]: Window},创建了generator对象,但是没有执行。
console.log(f.next()); //Object {value: 0, done: false}
console.log(f.next().value); //1
console.log(f.next().value); //1
console.log(f.next().value); //2
console.log(f.next().value); //3
console.log(f.next().value); //undefined
//2.使用for...of..遍历:
for (var x of fib(5)) {
console.log(x); // 依次输出0, 1, 1, 2, 3
}
关于generator的总结:每个yield就返回一个信息,用处很大。
九、标准对象:
//Date()
var date = new Date();
console.log(date.getFullYear());
//RegExp()
\d:数字
\w:字母或者数字。
\s:一个空格或者tab。
. :任意一个字符。
* :任意个字符,包括0个。
+:至少一个字符。
?:0或者1个。
{n}:n个字符。
{n,m}:n至m个字符。
[0-9a-zA-Z\_]:可以匹配一个数字、字母或者下划线;
A|B:可以匹配A或B。
^表示行的开头,^\d表示必须以数字开头。
$表示行的结束,\d$表示必须以数字结束。
//使用1,判断是否符合规则。
var re1 = /ABC\-001/;
var re2 = new RegExp('ABC\\-001');
re1.test('ABC-001'); //true
re2.test('ABC-001'); //true
//使用2,切分字符串
console.log('a,,b,c'.split(',')); // ["a", "", "b", "c"]
console.log('a,,b,c'.split(/,+/)); // ["a", "b", "c"]
//使用3,分组
var re = /^(\d{3})-(\d{3,8})$/;
re.exec('010-12345'); // ['010-12345', '010', '12345']
re.exec('010 12345'); // null
十、JSON:
字符集是UTF-8,字符串要使用双引号,对象中的键值也要使用双引号。
JSON.stringify(对象); //序列化成JSON格式字符串。
JSON.stringify(对象, ['key1', 'key2']); //JSON串,但是只保留key1和key2这2个属性.
JSON.stringify(对象, convert_function); //先用convert_function函数处理属性。
JSON.parse(JSON格式字符串); //反序列化
JSON.parse(JSON格式字符串,func); //反序列化,func可以用来处理属性。
JSON.parse('{"name":"小明","age":14}', function (key, value) {
// 把number * 2:
if (key === 'name') {
return value + '同学';
} return value;}); // Object {name: '小明同学', age: 14}
十一、面向对象编程:
js没有
类
和实例
的概念,而是通过原型(prototype)来实现面向对象编程。
var Student = {
age:12,
job:'PHPer'
}
var AboutMe = {
name:'ChenJian'
}
AboutMe.__proto__ = Student; //将AboutMe的原型指向Student,类似于继承。
//最好使用obj.create(原型对象),来首先创建一个空对象,AboutMe.create(Student).
console.log(AboutMe.job); //'PHPer'
// 创建对象1,原始方法
var me = {...};
// 创建对象2,使用构造方法。JS中万物皆对象。
function me(name){
this.name = name;
}
var aboutme = new me('ChenJian');
// 现在aboutme就是一个对象了,
// 同时此法创建的对象有个constructor属性,指向Student方法。