6.递归
6.1什么是递归
递归:如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。简单理解:函数内部自己调用自己, 这个函数就是递归函数
注意:递归函数的作用和循环效果一样,由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件return。
<body>
<script>
// 递归函数 : 函数内部自己调用自己, 这个函数就是递归函数
var num = 1;
function fn() {
console.log('我要打印6句话');
if (num == 6) {
return; // 递归里面必须加退出条件
}
num++;
fn();
}
fn();
</script>
</body>
<body>
<script>
// 利用递归函数求1~n的阶乘 1 * 2 * 3 * 4 * ..n
function fn(n) {
if (n == 1) {
return 1;
}
return n * fn(n - 1);
}
console.log(fn(3));
console.log(fn(4));
// 详细思路 假如用户输入的是3
//return 3 * fn(2)
//return 3 * (2 * fn(1))
//return 3 * (2 * 1)
//return 3 * (2)
//return 6
</script>
</body>
<body>
<script>
// 利用递归函数求斐波那契数列(兔子序列) 1、1、2、3、5、8、13、21...
// 用户输入一个数字 n 就可以求出 这个数字对应的兔子序列值
// 我们只需要知道用户输入的n 的前面两项(n-1 n-2)就可以计算出n 对应的序列值
function fb(n) {
if (n === 1 || n === 2) {
return 1;
}
return fb(n - 1) + fb(n - 2);
}
console.log(fb(3));
console.log(fb(6));
</script>
</body>
<body>
<script>
// 浅拷贝只是拷贝一层, 更深层次对象级别的只拷贝引用.
// 深拷贝拷贝多层, 每一级别的数据都会拷贝.
var obj = {
id: 1,
name: 'andy',
msg: {
age: 18
}
};
var o = {};
// for (var k in obj) {
// // k 是属性名 obj[k] 属性值
// o[k] = obj[k];
// }
// console.log(o);
// o.msg.age = 20;
// console.log(obj);
console.log('--------------');
Object.assign(o, obj);
console.log(o);
o.msg.age = 20;
console.log(obj);
</script>
</body>
<body>
<script>
// 深拷贝拷贝多层, 每一级别的数据都会拷贝.
var obj = {
id: 1,
name: 'andy',
msg: {
age: 18
},
color: ['pink', 'red']
};
var o = {};
// 封装函数
function deepCopy(newobj, oldobj) {
for (var k in oldobj) {
// 判断我们的属性值属于那种数据类型
// 1. 获取属性值 oldobj[k]
var item = oldobj[k];
// 2. 判断这个值是否是数组
if (item instanceof Array) {
newobj[k] = [];
deepCopy(newobj[k], item)
} else if (item instanceof Object) {
// 3. 判断这个值是否是对象
newobj[k] = {};
deepCopy(newobj[k], item)
} else {
// 4. 属于简单数据类型
newobj[k] = item;
}
}
}
deepCopy(o, obj);
console.log(o);
var arr = [];
console.log(arr instanceof Object);
o.msg.age = 20;
console.log(obj);
</script>
</body>
2.正则表达式在js中的使用
2.1正则表达式的创建
<body>
<script>
// 正则表达式在js中的使用
// 1. 利用 RegExp对象来创建 正则表达式
var regexp = new RegExp(/123/);
console.log(regexp);
// 2. 利用字面量创建 正则表达式
var rg = /123/;
// 3.test 方法用来检测字符串是否符合正则表达式要求的规范
console.log(rg.test(123));
console.log(rg.test('abc'));
</script>
</body>
3.2边界符
正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符
<body>
<script>
// 边界符 ^ $
var rg = /abc/; // 正则表达式里面不需要加引号 不管是数字型还是字符串型
// /abc/ 只要包含有abc这个字符串返回的都是true
console.log(rg.test('abc'));
console.log(rg.test('abcd'));
console.log(rg.test('aabcd'));
console.log('---------------------------');
var reg = /^abc/;
console.log(reg.test('abc')); // true
console.log(reg.test('abcd')); // true
console.log(reg.test('aabcd')); // false
console.log('---------------------------');
var reg1 = /^abc$/; // 精确匹配 要求必须是 abc字符串才符合规范
console.log(reg1.test('abc')); // true
console.log(reg1.test('abcd')); // false
console.log(reg1.test('aabcd')); // false
console.log(reg1.test('abcabc')); // false
</script>
</body>
3.3字符类
字符类表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内。
<body>
<script>
//var rg = /abc/; 只要包含abc就可以
// 字符类: [] 表示有一系列字符可供选择,只要匹配其中一个就可以了
var rg = /[abc]/; // 只要包含有a 或者 包含有b 或者包含有c 都返回为true
console.log(rg.test('andy'));
console.log(rg.test('baby'));
console.log(rg.test('color'));
console.log(rg.test('red'));
var rg1 = /^[abc]$/; // 三选一 只有是a 或者是 b 或者是c 这三个字母才返回 true
console.log(rg1.test('aa'));
console.log(rg1.test('a'));
console.log(rg1.test('b'));
console.log(rg1.test('c'));
console.log(rg1.test('abc'));
console.log('------------------');
var reg = /^[a-z]$/; // 26个英文字母任何一个字母返回 true - 表示的是a 到z 的范围
console.log(reg.test('a'));
console.log(reg.test('z'));
console.log(reg.test(1));
console.log(reg.test('A'));
// 字符组合
var reg1 = /^[a-zA-Z0-9_-]$/; // 26个英文字母(大写和小写都可以)任何一个字母返回 true
console.log(reg1.test('a'));
console.log(reg1.test('B'));
console.log(reg1.test(8));
console.log(reg1.test('-'));
console.log(reg1.test('_'));
console.log(reg1.test('!'));
console.log('----------------');
// 如果中括号里面有^ 表示取反的意思 千万和 我们边界符 ^ 别混淆
var reg2 = /^[^a-zA-Z0-9_-]$/;
console.log(reg2.test('a'));
console.log(reg2.test('B'));
console.log(reg2.test(8));
console.log(reg2.test('-'));
console.log(reg2.test('_'));
console.log(reg2.test('!'));
</script>
</body>
3.3.2量词符
量词符用来设定某个模式出现的次数。
<body>
<script>
// 量词符: 用来设定某个模式出现的次数
// var reg = /^a$/;
// console.log(reg.test('a'));
// console.log(reg.test('aa'));
// 1. * 相当于 >= 0 可以出现0次或者很多次
// var reg = /^a*$/;
// console.log(reg.test(''));
// console.log(reg.test('a'));
// console.log(reg.test('aa'));
// console.log(reg.test('aaaaaa'));
// 2. + 相当于 >= 1 可以出现1次或者很多次
// var reg = /^a+$/;
// console.log(reg.test(''));
// console.log(reg.test('a'));
// console.log(reg.test('aa'));
// console.log(reg.test('aaaaaa'));
// 3. ? 相当于 1 || 0
// var reg = /^a?$/;
// console.log(reg.test(''));
// console.log(reg.test('a'));
// console.log(reg.test('aa'));
// console.log(reg.test('aaaaaa'));
// 4. {3 } 就是重复3次
// var reg = /^a{3}$/;
// console.log(reg.test(''));
// console.log(reg.test('a'));
// console.log(reg.test('aa'));
// console.log(reg.test('aaaaaa'));
// console.log(reg.test('aaa'));
// 5. {3, } 大于等于3
var reg = /^a{3,}$/;
console.log(reg.test(''));
console.log(reg.test('a'));
console.log(reg.test('aa'));
console.log(reg.test('aaaaaa'));
console.log(reg.test('aaa'));
// 6. {3, 16} 大于等于3 并且 小于等于16
var reg = /^a{3,16}$/;
console.log(reg.test(''));
console.log(reg.test('a'));
console.log(reg.test('aa'));
console.log(reg.test('aaaaaa'));
console.log(reg.test('aaa'));
console.log(reg.test('aaaaaaaaaaaaaaaaaaaaa'));
</script>
</body>
3.3.3用户名表单验证
功能需求:
1.如果用户名输入合法, 则后面提示信息为: 用户名合法,并且颜色为绿色
2.如果用户名输入不合法, 则后面提示信息为: 用户名不符合规范, 并且颜色为红色
<body>
<input type="text" class="uname"> <span>请输入用户名</span>
<script>
// 量词是设定某个模式出现的次数
var reg = /^[a-zA-Z0-9_-]{6,16}$/; // 这个模式用户只能输入英文字母 数字 下划线 短横线但是有边界符和[] 这就限定了只能多选1
// {6,16} 中间不要有空格
// console.log(reg.test('a'));
// console.log(reg.test('8'));
// console.log(reg.test('18'));
// console.log(reg.test('aa'));
// console.log('-------------');
// console.log(reg.test('andy-red'));
// console.log(reg.test('andy_red'));
// console.log(reg.test('andy007'));
// console.log(reg.test('andy!007'));
var uname = document.querySelector('.uname');
var span = document.querySelector('span');
uname.onblur = function() {
if (reg.test(this.value)) {
console.log('正确的');
span.className = 'right';
span.innerHTML = '用户名格式输入正确';
} else {
console.log('错误的');
span.className = 'wrong';
span.innerHTML = '用户名格式输入不正确';
}
}
</script>
</body>
3.3.4 括号总结
1.大括号 量词符. 里面表示重复次数
2.中括号 字符集合。匹配方括号中的任意字符.
3.小括号表示优先级
<body>
<script>
// 中括号 字符集合.匹配方括号中的任意字符.
// var reg = /^[abc]$/;
// a 也可以 b 也可以 c 可以 a ||b || c
// 大括号 量词符. 里面表示重复次数
// var reg = /^abc{3}$/; // 它只是让c重复三次 abccc
// console.log(reg.test('abc'));
// console.log(reg.test('abcabcabc'));
// console.log(reg.test('abccc'));
// 小括号 表示优先级
var reg = /^(abc){3}$/; // 它是让abcc重复三次
console.log(reg.test('abc'));
console.log(reg.test('abcabcabc'));
console.log(reg.test('abccc'));
</script>
</body>
案例:验证座机号码
<body>
<script>
// 座机号码验证: 全国座机号码 两种格式: 010-12345678 或者 0530-1234567
// 正则里面的或者 符号 |
// var reg = /^\d{3}-\d{8}|\d{4}-\d{7}$/;
var reg = /^\d{3,4}-\d{7,8}$/;
</script>
</body>
3.5正则替换replace
replace() 方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则表达式。
<body>
<textarea name="" id="message"></textarea> <button>提交</button>
<div></div>
<script>
// 替换 replace
// var str = 'andy和red';
// // var newStr = str.replace('andy', 'baby');
// var newStr = str.replace(/andy/, 'baby');
// console.log(newStr);
var text = document.querySelector('textarea');
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.onclick = function() {
div.innerHTML = text.value.replace(/激情|gay/g, '**');
}
</script>
</body>