大纲
- filter去重
- filter筛选数组中素数
- sort()函数复习
- Array对象
- 函数闭包
- 箭头函数
- generator对象
- 正则表达与Date对象
- Jason
filter去重
var r,
arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];
r = arr.filter(function (element, index, self) {
return self.indexOf(element) === index;});
//PS:element, index, self只是形式?不知道能不能换!
filter筛选素数
简单的方法可以考虑素数只有1和本身
两个因数,麻烦的可以依据定义写函数
//获得素数函数,可以利用素数只有两个因数,下面的是麻烦的,从定义写的函数!
function get_primes(arr) {
var brr = arr.filter(function(ss){
var jsw = 0;
if (ss == 1) {jsw =1}
else {
for (var i=2; i<ss; i++) {
if( ss%i==0 ){
jsw = jsw +1;
break;}
else{ continue; }
}
}
return !jsw;
});
return brr;
}
//依据因数是否只有2个
arr = arr.filter(function(element, index, self){
var count = 0;//记录因数的数量
for(var i=1;i<=element;i++){
if(element%i===0){
count++;
}
}
if(element===1){
return false;
}
return count<3;
});
console.log(arr)
sort函数
在3w网站学过,快速排序,按照-1,0,1
的顺序,也可以排列有属性的对象
//数字小->大排序;
points.sort(function(a, b){return a - b});
//随机排序数组;
points.sort(function(a, b){return 0.5 - Math.random()});
//排序有属性数组,按照字母排序对象
cars.sort(function(a, b){return a.year - b.year});;
function myFunction() {
var cars = [{type:"BMW", year:2017},{type:"Audi", year:2019},{type:"porsche", year:2018}];
cars.sort(function(a, b){
var x = a.type.toLowerCase();
var y = b.type.toLowerCase();
if (x < y) {return -1;}
if (x > y) {return 1;}
return 0;
});
displayCars();
}
Array
every
var arr = ['Apple', 'pear', 'orange'];
console.log(arr.every(function (s) {
return s.length > 0;
})); // true, 因为每个元素都满足s.length>0
find
查找符合条件的第一个元素,如果找到了,返回这个元素;否则返回undefined
var arr = ['Apple', 'pear', 'orange'];
console.log(arr.find(function (s) {
return s.toLowerCase() === s;
})); // 'pear', 因为pear全部是小写
findIndex
和find
类似,区别:findIndex()
会返回这个元素的索引,如果没有找到,返回-1
;
forEach
forEach()
和map()
类似,但不会返回新数组;
函数闭包
把函数作为结果值返回,返回函数不要引用任何循环变量,或者后续会发生变化的变量:再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:
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
- 用了一个“创建一个匿名函数并立刻执行”的语法:
(function (x) {
return x * x;
})(3); // 9
- 只有函数的语言里,借助闭包,可以封装一个私有变量。我们用JavaScript创建一个计数器:
'use strict';
function create_counter(initial) {
var x = initial || 0;
return {
inc: function () {
x += 1;
return x;
}
}
}
- 使用:
var c1 = create_counter();
c1.inc(); // 1
c1.inc(); // 2
c1.inc(); // 3
var c2 = create_counter(10);
c2.inc(); // 11
c2.inc(); // 12
c2.inc(); // 13
- 闭包可以把多参数的函数变成单参数的函数:
function make_pow(n) {
return function (x) {
return Math.pow(x, n);
}
}
// 创建两个新函数:
var pow2 = make_pow(2);
var pow3 = make_pow(3);
console.log(pow2(5)); // 25
console.log(pow3(7)); // 343
箭头函数
this
的指向与标准function
不同,始终指向词法作用域(还是挺糊涂的,以后遇到实例再说吧);
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = function () {
return new Date().getFullYear() - this.birth; // this指向window或undefined
};
return fn();
}
};
箭头函数修复了this
的指向
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象
return fn();
}
};
obj.getAge(); // 25
generator
generator
由function*
定义,可以用yield
多次返回,也可以和函数一样用return
返回一次。
function* fib2(max){
var a=0, b=1, t;
for (var i = 0; i<max; i++) {
t=a; //也可以直接执行 yield a;
[a,b]=[b,a+b];
yield t;
}
}
//generator的调用,有两种方式
for (var shc of fib2(5)){
console.log(shc);
}
- 也可以用
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: false}
f.next(); // {value: undefined, done: true}
学了AJAX以后可以体会到generator更大的好处,目前只知道可以保存函数的中间状态;
RegExp相关
- 基本知识
\w
可以匹配一个字母或数字,\d
匹配一个数字;
+
表示至少一个字符:\s+
表示至少有一个空格;
*
表示任意个字符,?
表示0个或1个字符;
\d{3,8}
表示3-8个数字,如'1234567'
等;
匹配'010-12345'
,-
是特殊字符,需要转义,所以号码的正则是\d{3}\-\d{3,8}
;
[a-zA-Z\_\$][0-9a-zA-Z\_\$]*
表示由字母或下划线、$开头,后接任意个由一个数字、字母或者下划线、$组成的字符串;
A|B
可以匹配A或B:(J|j)ava(S|s)cript
;
^
表示行的开头,^\d
必须以数字开头;
$
表示行的结束,\d$
必须以数字结束:js
也可以匹配jsp
,但js$
只能匹配js
; - 创建正则表达式:
var re1 = /ABC\-001/;
var re2 = new RegExp('ABC\\-001');
re1; // /ABC\-001/
re2; // /ABC\-001/
- 切分字符串
'a b c'.split(' '); // ['a', 'b', '', '', 'c'];
'a b c'.split(/\s+/); // ['a', 'b', 'c'];
'a,b, c d'.split(/[\s\,]+/); // ['a', 'b', 'c', 'd'];
//至少一个[' '或','或';']
'a,b;; c d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd'];
- 分组
除了匹配外,正则还可以提取字符串,()
表示的就是要提取的分组;
//先匹配字符串
var re = /^(\d{3})-(\d{3,8})$/;
re.exec('010-12345'); // ['010-12345', '010', '12345']
re.exec('010 12345'); // null
exec()
方法在匹配成功后,会返回一个Array
,第一个元素是正则表达式匹配到的整个字符串,后面的字符串表示匹配成功的子串;失败则会返回null
。
var re = /^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$/;
re.exec('19:05:30'); // ['19:05:30', '19', '05', '30']
上述可以识别合法日期。
但是对于日期的识别可能会出问题:
var re = /^(0[1-9]|1[0-2]|[0-9])-(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[0-9])$/;
对于'2-30'
,'4-31'
非法日期正则很难去识别,需要程序实现;
- 贪婪匹配:正则默认贪婪匹配
var re = /^(\d+)(0*)$/;
re.exec('102300'); // ['102300', '102300', '']
导致0*
无法匹配到字符串,可以加个?
来解决(尽可能少匹配):
var re = /^(\d+?)(0*)$/;
re.exec('102300'); // ['102300', '1023', '00']
- 全局匹配
g
,表示全局匹配;i
,表示忽略大小写;m
,表示多行匹配。
var r1 = /test/g;
// 等价于:
var r2 = new RegExp('test', 'g');
全局匹配可以多次执行exec()
方法来搜索一个匹配的字符串,指定g
标志后,每次运行exec()
,正则表达式本身会更新lastIndex
属性,表示上次匹配到的最后索引:
var s = 'JavaScript, VBScript, JScript and ECMAScript';
var re=/[a-zA-Z]+Script/g;
// 使用全局匹配:
re.exec(s); // ['JavaScript']
re.lastIndex; // 10
re.exec(s); // ['VBScript']
re.lastIndex; // 20
re.exec(s); // ['JScript']
re.lastIndex; // 29
re.exec(s); // ['ECMAScript']
re.lastIndex; // 44
re.exec(s); // null,直到结束仍没有匹配到
全局匹配不能使用不能使用/^...$/
Jason学习
学习中看了篇评论区文章,箭头函数不乱用,箭头函数本身无this、arguments等属性,使用箭头函数一定要在外层套一层函数,使this在可见范围内,对象无法分割作用域(对象内的箭头函数无法确定this的指向),定义变量const>let>var尽量依次使用。
创建对象
通过函数创建对象,理解还较浅,注意prototype
与__proto__
以及原型链
function Cat(name) {
this.name = name;
}
Cat.prototype.say = function(){
return 'Hello, ' + this.name + '!';
}
可以用一个createStudent
来内部封装new
function Student(props) {
this.name = props.name || '匿名';
this.grade = props.grade || 1;
}
Student.prototype.hello = function () {
alert('Hello, ' + this.name + '!');
}
function createStudent(props) {
return new Student(props || {})
}
createStudent
的参数非常灵活,可以不传也可以如下:
var xiaoming = createStudent({
name: '小明'
});
xiaoming.grade;