我们接着上篇文章继续学习后面的知识
上一张的练习题
字符串转json
//将问号后面的字符串转换为对象
let str = "http://item.taobo.com/item.html?a=1&b=2&c=&d=xxx&e";
let obj = {};
let s1 = str.substring(str.indexOf('?') + 1).split('&');
for (let i = 0; i < s1.length; i++) {
let arr = s1[i].split('=');
obj[arr[0]] = arr[1];
}
console.log(obj);
转驼峰
//封装一个函数,将font-size转换为fontSize
function toTf(sty) {
// 分割字符串转数组
let arr = sty.split('-');
let str = '';
// 循环给除了第一个单词外的首字母替换成大写并拼接
for (let i = 1; i < arr.length; i++) {
str += arr[i].replace(arr[i].substring(0, 1), arr[i].substring(0, 1).toUpperCase());
}
// 拼接第一个
return arr[0] + str;
}
let str = prompt('请输入一个非驼峰的东西');
alert(toTf(str));
字符串去重并进行排序
// 把下面的字符串去重, 并去除掉特殊字符按照数字在前字母在后的顺序排序字符串, 最终返回12345fdsarg
// var str = '1233fddfd&3434fdsaff&454545&4545444rfdsfds&545gdsgs';
let str = '1233fddfd&3434fdsaff&454545&4545444rfdsfds&545gdsgs';
let s = '';
let n = '';
for (let i = 0; i < str.length; i++) {
// 既去重又取数字
if ((str[i] >= 0 && str[i] <= 9) && n.indexOf(str[i]) == -1) {
n += str[i];
// 既去重又取字母
} else if ((str.charCodeAt(i) >= 97 && str.charCodeAt(i) <= 122) && s.indexOf(str[i]) == -1) {
s += str[i];
}
}
console.log(n + s);
设置获取固有属性
//在原生js中固有属性一般为class id type value checked等等
//我们可以使用className和input.value等获取固有属性 设置我们可以直接点的形式直接赋值
设置获取自定义属性
//自定义属性在我们开发中是比较常见的
//一种是直接设置的 比如index属性 这种方式不在浏览器标签中显示 但是可以使用,可以直接获取
let div = document.querySelector('.box');
div.index = 1;
div.id = '111';
console.log(div.index);
console.log(div.id);
//另外一种方式是使用setAttribute()设置自定义属性 但是获取必须使用配套的getAttribute()来进行获取
let div = document.querySelector('.box');
// 添加自定义属性
div.setAttribute('index', 1);
// 获取自定义属性
console.log(div.getAttribute('index'));
正则表达式的使用
//一般我们利用new RegExp 和字面量 // 两种方式创建正则表达式
//一般使用正则表达式的时候 我们可以在网上找些表达式进行使用
let str = 'hell o'
// 使用正则
let reg = /\s/
let result = str.replace(reg, "")
console.log(result);
使用相关的API
修饰符:
g:全局匹配
i:不区分大小写
检索方法:
test():满足为true,不满足为false
exec():满足会返回一个数组 不满足则返回一个null
match() 效果等同于exec() 满足会返回一个数组 不满足返回null
search() 查找字符串某个元素 找到的返回索引 找不到返回为-1 等同于字符串中的indexOf()
转义符:
\:当我们需要一些运算符的时候 我们可能没办法直接使用 但是我们可以利用转义符进行匹配,从而满足我们的需求
元字符:
[a-z]:小写英文字符a-z
[A-Z]:大写英文字符A-Z
[0-9]:数字0-9
/\d/:数字0-9
/\D/:非数字
/\w/:数字字母(大小写)和_
/\W/:除了 数字字母(大小写)和_
/\s/:空格 tab
/\S/:出了空格 tab
^:以xxx开头
$:以xxx结尾
?:匹配0或1个
*:匹配0以上
+:匹配1个以上
{m,n}:范围个数 包括m n
常见的表达式就是上面这些,如果我们需要使用的正则表达式进行处理事件的话,我们可以在**Vscode软件中下载any-rule插件** 可以快速帮我们找出需要的正则
JS对DOM节点的操作
//创建节点
let div = document.createElement('div')
//追加节点
appendChild(div) //在末尾添加
inserBefore(div) //在前面添加
removeChild(div) //移除节点
replaceChild(div) //替换节点
cloneNode(div) //克隆节点 里面是true的话是深克隆 默认是浅克隆
函数高级
回调函数callback()
// function a(c) {
// console.log(2);
// // console.log(c);
// c && c();
// }
// function b() {
// console.log(1);
// }
// a(b);
// 回调函数
// 把函数当成参数传给另个函数 不是我们直接调用的 系统调用的
回调函数会带来回调地狱的问题
//立即执行函数
()()
// 立即执行函数 this指向window 匿名函数 每一个立即执行函数结束都要加分号
// (function(形参,...){执行语句})(实参); (function(形参){}(实参))
// (function(a) {
// console.log(a);
// })(10);
闭包函数
function fun() {
let a = 1;
function fun1() {
console.log(a);
}
fun1();
// a = null;
}
fun();
// 闭包:函数嵌套函数 内部函数可以访问外部函数中的变量
// 优点:扩大变量的使用范围 变量私有化
// 缺点:内存泄露 变量一直存在内存中 不会被垃圾回收机制回收掉
// 解决:引用计数 标记清除
闭包常见案例
function fun(n, o) {
console.log(o);
return {
fun: function(m) {
return fun(m, n);
}
}
}
var a = fun(0); //undefined
a.fun(1); //0
a.fun(2); //0
a.fun(3); //0
递归函数
// 递归函数
// 自己调自己
// 递归调用, 是函数本身调用自己。 但是应用递归调用的时候, 我们有必要设置一个条件, 也就是if语句, 目的是能够让这个函数停下来, 否则程序将进入到死循环。
// 阶乘
// !6
// 1*2*3*4*5*6
// function fn(n) {
// if (n <= 1) return 1;
// return n * fn(n - 1)
// }
// console.log(fn(6));
// 兔子函数
// 有一对兔子, 从出生后第3个月起每个月都生一对兔子, 小兔子长到第三个月后每个月又生一对兔子, 假如兔子都不死, 问每个月的兔子总数为多少? 1. 程序分析: 兔子的规律为数列1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144…
// 解析: 定义一个函数, 完成计算每个月兔子总数的功能。
// function fun(n) {
// if (n == 1 || n == 2) {
// return n = 1;
// }
// return fun(n - 2) + fun(n - 1);
// };
// console.log(fun(12));
防抖与节流
// 防抖
// 非立即执行
// 在规定n秒内只执行一次,如果频繁触发事件则重新计算时间
// 窗口缩小放大事件
// 浏览器搜索
// document.querySelector('div').onmousemove = debounce(fun, 1000);
// function fun() {
// console.log(1);
// }
// function debounce(f, time) {
// let timer;
// return function() {
// if (timer) {
// clearTimeout(timer);
// }
// timer = setTimeout(f, time)
// }
// }
// 立即执行
// function debounce(f, time) {
// let timer;
// return function() {
// if (timer) {
// clearTimeout(timer);
// }
// //undefined null 0 '' false NaN
// let flag = !timer; //true
// // 异步
// timer = setTimeout(function() {
// timer = null;
// }, time);
// if (flag) f();
// }
// }
// 节流
// n秒内只执行一次
// 点击
document.querySelector('div').onmousemove = throttle(fun, 2000);
function fun() {
console.log(1);
}
// 时间戳
// function throttle(f, wait) {
// let pervious = 0;
// return function() {
// // 获取当前的事件戳
// let now = Date.now();
// // 获取时间戳的差值 并进行判断 只要差值大于规定的事件 执行函数 并重新更新事件 反之 就不执行
// if (now - pervious > wait) {
// f();
// pervious = now;
// }
// }
// }
// 定时器
// function throttle(f, wait) {
// let timer;
// return function() {
// if (!timer) {
// timer = setTimeout(function() {
// timer = null;
// f();
// }, wait)
// }
// }
// }
// 总结:
// 防抖: 触发高频事件后n秒内函数只会执行一次, 如果n秒内高频事件再次被触发, 则重新计算时间
// 节流: 高频事件触发, 但在n秒内只会执行一次, 节流会稀释函数的执行频率