JavaScript:https://developer.mozilla.org/en-US/docs/Web/JavaScrip
ES6:https://es6.ruanyifeng.com/
MDN:https://developer.mozilla.org/zh-CN/
w3School:https://www.w3school.com.cn/
/*
a++:a先创建自身的一个副本,然后a自增1,最后返回副本的值。
a=3;b=a++;
运行后 b=3,a=4
++a:将a自增1并返回a。
a=3;b=++a;
运行后 b=4,a=4 */
let n = 0
console.log(n++) //0
console.log(++n)//2
console.log(n);//2
声明
赋值
?
String字符串类型
Boolean布尔类型:ture 或false
Undefined未定义类型:一个变量声明,但是没有赋值
Null空值:number+null=number本身
typeof xx :返回结果只能有string,number,boolean,undefined,function,object
A instanceof B 可以判断A是不是B的实例 :返回结果true/false
Object.prototype.toString.call(xx)
对象的constructor判断:xx.constructor === Date/Function/Array...
Jquery提供的
jQuery.isArray();是否为数组
jQuery.isEmptyObject();是否为空对象 (不含可枚举属性)。
jQuery.isFunction():是否为函数
jQuery.isNumberic():是否为数字
jQuery.isPlainObject():是否为使用“{}”或“new Object”生成对象,而不是浏览器原生提供的对象。
jQuery.isWindow(): 是否为window对象;
jQuery.isXMLDoc(): 判断一个DOM节点是否处于XML文档中。
String(x)
x.toString(x, 10)
x+‘‘
Number(x)
parseInt(x, 10)
parseFloat(x)
x - 0
+x
Boolean(x)
!!x
0,NaN, ‘‘, null, undefined 转换为布尔型都是false
解释语言和编译语言
内存图
深复制和浅复制
+ ,- ,*, /, %,
a++(a--)是先执行表百达式后再自增,执行表达式时使度用的是a的原值
++a(--a)是先自增再执行表知达示,执行表达式时使道用的是自增后的a
< ,>,>=,<=,,!=,=,!==
&&,||,!
短路与:表达式1&&表达式2:1真返回2,1假返回1 (一旦发现假就结束,返回假的那个表达式)
短命或:一旦发现真就结束,返回真。
=,+=,-=,*=,/=,%=
1)()
2)++ -- !
3)* / % + -
4)> >= < <=
5)== != === !==
6) && ||
7) =
8) ,
if
if-else
if-else if-else
表达式?执行语句1:执行语句2
相当于if-else
switch (key) {
case value:
执行语句1
break;
case value2:
执行语句2
break;
default:
break;
}
for(初始变量;条件表达式;操作符){
循环体
}
while(条件表达式){
循环体
}
先执行一次循环体,再判断条件;如果条件为真,执行循环体,否则就退出
语法:
do {
循环体
} while (条件表达式);
具有数组的length属性
按照索引的方式进行存储
没有真正数组的一些方法如pop(),push()等
内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值 (就近原则)
变量预解析(变量提升):var 变量=值【相当于:var 变量;变量=值】
函数预解析(函数提升):function fn() {}
函数声明:可以先使用再声明
函数表达式:必须先声明再使用
*var 对象名={属性名:属性值,...,方法名:function(){}}*
*var变量名=new Object*
function 构造函数名() {
this.属性名=属性值;
this.方法名=function(){}
}
? 使用构造函数:new 构造函数名()
? 注意:
构造函数名首字母大写
利用构造函数创建对象的过程,就是对象的实例化
? new关键字的执行过程:
1)new构造函数可以在内存中创建一个空的对象
? 2)this就会指向刚才创建的对象
? 3)执行构造函数里面的代码,给这个空对象添加属性和方法
*4)返回这个对象*
对象名.属性名
对象名[‘属性名‘]
for(var k in 对象) {
console.log(k)//属性名,方法名
console.log(对象[k])//属性值和方法
}
? Math.PI
? Math.max(x)
? Math.min(x)
? Math.floor(x) 向下取值,往最小取
? Math.ceil(x) 向上取值,往最大取
? Math.round(x) 四舍五入
? Math.abs(x) 绝对值
? Math.random()*n [0,n)区间的随机数
? Math.floor(Math.random()*(m-n+1))+n [n,m]区间的随机数整数
console.log(new Date());
console.log(new Date(‘2020-4-11 8:8:8‘));
console.log(new Date(2020, 4, 11));
// 获取当前时间戳
console.log(new Date().valueOf());
console.log(new Date().getTime());
console.log(+new Date());
console.log(Date.now());
function formatTime() {
var now = new Date()
var y = now.getFullYear()
var m = (now.getMonth() + 1 + ‘‘).padStart(1, ‘0‘)
var d = (now.getDate() + ‘‘).padStart(1, ‘0‘)
var w = now.getDay()
var wArr = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
var week = wArr[w]
var hh = (now.getHours() + ‘‘).padStart(1, ‘0‘)
var mm = (now.getMinutes() + ‘‘).padStart(1, ‘0‘)
var ss = (now.getSeconds() + ‘‘).padStart(1, ‘0‘)
return `${y}-${m}-${d}-${week} ${hh}:${mm}:${ss}`
}
// setInterval(() => {
// console.log(formatTime());
// }, 1000);
/* 案例:倒计时 */
// 天:n/60/60/24
// 时:n/60/60%24
// 分:n/60%60
// 秒: n%60
function countDown(a) {
var now = Date.now()
var inputTime = +new Date(a)
var time = (inputTime - now) / 1000
var d = (parseInt(time / 60 / 60 / 24) + ‘‘).padStart(2, ‘0‘)
var h = (parseInt(time / 60 / 60 % 24) + ‘‘).padStart(2, ‘0‘)
var m = (parseInt(time / 60 % 60) + ‘‘).padStart(2, ‘0‘)
var s = (parseInt(time % 60) + ‘‘).padStart(2, ‘0‘)
return `${d}天 ${h}:${m}:${s}`
}
console.log(countDown(‘2020-4-13 18:50:00‘));
检查是否是数组:
数组 instanceof Array :返回true/false
Array.isArray(数组):返回true/false
arr.push(xx) 改变原数组,返回新数组的长度
arr.unshift(xx) 改变原数组,返回新数组的长度
arr.pop(xx) 改变原数组,返回删除元素
arr.shift() 改变原数组,返回删除元素
arr.reverse() 改变原数组
arr.sort() 改变原数组 【单位数好使,标准写法用下面】
// 升序
arr.sort(function (a, b) {
return a - b
})
// 降序
arr.sort(function (a, b) {
return a - b
})
arr.indexOf(x,start) 返回数组中第一个x的索引,如果没有返回-1 【正序查找】
arr.lastIndexOf(x) 同上【倒序查找】
arr.toString() 把数组转成字符串,逗号分隔每一项
arr.join(‘xx‘) 把数组转成字符串,xx分隔每一项
arr1.concat(arr2,arr3,...) 连接数组,返回新数组
arr.slice(begin,end) 返回被截取的新数组
arr.splice(start,deleteNumber,add1,add2...) 返回被删除的数组,影响原数组
// 案例:数组去重
function unique(arr) {
var nArr = []
for (var i = 0; i < arr.length; i++) {
if (nArr.indexOf(arr[i]) === -1) {
nArr.push(arr[i])
}
}
return nArr
}
console.log(unique([1, 2, 5, 7, 22, 4, 2, 3, 4]));
str.length
str.indexOf(x,start) 从start开始查找,返回str中x第一次出现的索引,没有返回-1
str.charAt(index) 返回索引为index的字符
str.charCodeAt(index) 返回索引为index的字符的ASCII码
str[index] 返回索引为index的字符
str.concat(str1,str2...) 拼接字符串
str.substr(start, length) 截取字符串,从start截取length个
str.slice(start, end) 截取字符串,从start到end-1,end取不到
str.substring(start,end) 截取字符串,从start到end-1,end取不到。不接受负值
str.replace(‘aa‘,‘bb‘) 用bb替换str中的aa
str.split("xx") 用xx把字符串分割成数组,每一项用xx隔开
str.toLowerCase()
str.toUpperCase()
/* 案例:查找字符串中o出现的位置已经次数 */
var str = ‘1234ididhsidhadjidiii‘
var index = str.indexOf(‘d‘)
var n = 0
var arr = []
// while (index !== -1) {
// arr.push(index)
// index = str.indexOf(‘d‘, index + 1)
// n++
// }
for (var i = 0; i < str.length; i++) {
if (index !== -1) {
arr.push(index)
index = str.indexOf(‘d‘, index + 1)
n++
}
}
console.log(n, arr);
console.log(str.charAt(2));
console.log(str.charCodeAt(2));
console.log(str[2]);
/*案例:判断一个字符串中出现最多次数的字符,统计其次数 */
var obj = {}
for (var i = 0; i < str.length; i++) {
console.log(str.charAt(i));
var chars = str.charAt(i)
if (obj[chars]) {
obj[chars]++
} else {
obj[chars] = 1
}
}
console.log(obj);
var max = 0
var ch
for (var k in obj) {
if (obj[k] > max)
max = obj[k]
ch = k
}
console.log(max, ch);
var str2 = ‘abcdefG‘
console.log(str2.concat(‘1‘, ‘m‘, ‘a‘));
console.log(str2.substr(0, 3));
console.log(str2.slice(0, 3));
console.log(str2.substring(0, 3));
console.log(str2.toLowerCase());
console.log(str2.toUpperCase());
? 这两个属性是可以读写的,可以获取元素里面的内容
设置格式:data-xx
获取:
element.getAttribute(‘data-xx‘)
element.dataset.xx
element.dataset[‘xx‘]
如果自定义属性有多个-连接(data-lis-name),获取时采用驼峰命名法:element.dataset[‘listName‘]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.btnBox {
margin: 20px auto;
width: 100%;
text-align: center;
}
.pink {
background-color: pink;
}
.box {
display: flex;
margin: 0 300px;
border: 4px solid #fff;
}
li {
flex: 1;
list-style: none;
}
img {
width: 100%;
height: 200px;
}
body {
background: url(‘./img/1.jpg‘) no-repeat center top;
}
table {
width: 800px;
margin: 100px auto;
text-align: center;
border-collapse: collapse;
font-size: 14px;
background-color: #fff;
}
thead tr {
height: 30px;
background-color: skyblue;
}
tbody tr {
height: 30px;
}
tbody td {
border-bottom: 1px solid #d7d7d7;
font-size: 12px;
color: blue;
}
.bg {
background-color: pink;
}
.wrap {
width: 300px;
margin: 100px auto 0;
}
.wrap table {
border-collapse: collapse;
border-spacing: 0;
border: 1px solid #c0c0c0;
width: 300px;
}
.wrap th,
.wrap td {
border: 1px solid #d0d0d0;
color: #404060;
padding: 10px;
}
.wrap th {
background-color: #09c;
font: bold 16px "微软雅黑";
color: #fff;
}
.wrap td {
font: 14px "微软雅黑";
}
.wrap tbody tr {
background-color: #f0f0f0;
}
.wrap tbody tr:hover {
cursor: pointer;
background-color: #fafafa;
}
</style>
</head>
<body>
<!-- 点击按钮变色 -->
<div class="btnBox">
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<button>5</button>
</div>
<!-- 百度换肤 -->
<ul class="box">
<li><img src="./img/1.jpg" alt=""></li>
<li><img src="./img/2.jpg" alt=""></li>
<li><img src="./img/3.jpg" alt=""></li>
<li><img src="./img/4.jpg" alt=""></li>
</ul>
<!-- 表格经过变色 -->
<table>
<thead>
<tr>
<th>代码</th>
<th>名称</th>
<th>最新公布净值</th>
<th>累计净值</th>
<th>前单位净值</th>
<th>净值增长率</th>
</tr>
</thead>
<tbody>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
</tbody>
</table>
<!-- 表单全选和取消全选 -->
<div class="wrap">
<table>
<thead>
<tr>
<th>
<input type="checkbox" id="j_cbAll" />
</th>
<th>商品</th>
<th>价钱</th>
</tr>
</thead>
<tbody id="j_tb">
<tr>
<td>
<input type="checkbox" />
</td>
<td>iPhone8</td>
<td>8000</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>iPad Pro</td>
<td>5000</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>iPad Air</td>
<td>2000</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Apple Watch</td>
<td>2000</td>
</tr>
</tbody>
</table>
</div>
<script>
/* 案例:点击按钮变色 */
var btns = document.querySelectorAll(‘button‘)
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
// 去掉其他人,只设置我自己
for (var i = 0; i < btns.length; i++) {
btns[i].className = ‘‘
}
this.className = ‘pink‘
}
}
/* 案例:百度换肤 */
var imgs = document.querySelectorAll(‘img‘)
for (var i = 0; i < imgs.length; i++) {
imgs[i].onclick = function () {
document.body.style.backgroundImage = `url(${this.src})`
console.log(this.src);
}
}
/* 案例:表格经过变色 */
var tbody = document.querySelector(‘tbody‘)
var trs = document.querySelectorAll(‘tr‘)
for (var i = 0; i < trs.length; i++) {
trs[i].onmouseover = function () {
this.className = ‘bg‘
}
trs[i].onmouseout = function () {
this.className = ‘‘
}
}
/* 案例:表单全选和取消全选 */
var all = document.querySelector(‘#j_cbAll‘)
var others = document.querySelector(‘#j_tb‘).querySelectorAll(‘input‘)
all.onclick = function () {
for (var i = 0; i < others.length; i++) {
others[i].checked = this.checked
}
}
for (var i = 0; i < others.length; i++) {
others[i].onclick = function () {
var flag = true
// 检查是否全部都选中,全选中all就是true,否则就是false
for (var i = 0; i < others.length; i++) {
if (!others[i].checked) {
// all.checked = false
flag = false
break
}
}
all.checked = flag
}
}
</script>
</body>
</html>
传统方式【能绑定一个事件】
//注册
element.on事件类型=function(){}
//删除
element.on事件类型=null
监听注册方式【 可以绑定多个事件,常用】
//注册 (第三个参数可有可无,默认false。false在冒泡阶段调用事件处理程序,true在捕获阶段调用事件处理程序)
element.addEventListener(‘事件类型‘, fn,true/false)
function fn() {}
//删除
element.removeEventListener(‘事件类型‘,fn)
只有ie9以前才支持
//注册
element.attachEvent(‘on事件类型‘, fn)
function fn() {}
//删除
element.detachEvent(‘on事件类型‘,fn)
捕获阶段: element.addEventListener(‘事件类型‘, fn,true)
当前目标阶段
冒泡阶段 element.addEventListener(‘事件类型‘, fn,false)或 element.addEventListener(‘事件类型‘, fn)
注意: (1 )S代码只能执行捕获或者冒泡中的一个阶段 。(2)传统方式和attachEvent只能得到冒泡阶段
事件对象的定义:事件对象只有有了事件才会存在,在事件的侦听函数的小括号里面。当成形参看。是系统自动创建的
element.addEventListener(‘事件类型‘, function(event) {
console.log(event)
})
//事件对象的名称是自己命名的,常用e
事件对象常见属性和方法:
1、普通浏览器:
e.target 触发事件的对象
e.preventDefault() 阻止默认行为
2、低版本浏览器:
e.srcElement 触发事件的对象
e.cancelBubble 阻止冒泡
【传统方式return false 也可以阻止默认行为,return后面的代码不执行了】
事件里面的this指向的是事件函数的调用者
this返回的是绑定事件的对象
e.target或e.srcElement 触发事件的对象
click
mouseover(鼠标经过自身盒子会触发,进过子盒子也会触发。会冒泡)
mouseout
mouseenter(只会经过自身盒子触发。不会冒泡)
mouseleave(不会冒泡)
focus
blur
mousemove
mouseup
mousedown
// 禁止鼠标右键菜单
document.addEventListener(‘ contextmenu‘, function (e) {
e.preventDefault()
})
//禁止鼠标选中
document.addEventListener(‘selectstart‘, function (e) {
e.preventDefault()
})
// 键盘事件
document.addEventListener(‘keyup‘, function (e) {
console.log(‘keyup‘);
})
document.addEventListener(‘keydown‘, function (e) {
console.log(‘keydown‘);
})
//keypress不识别功能键,如ctrl,shift等
document.addEventListener(‘keypress‘, function (e) {
console.log(‘keypress‘);
})
//keyup,keydown事件不区分字母大小写
//load事件 是等页面全部加载完毕(包括dom元素,img,flash,css等;
// window.onload=function() {}
window.addEventListener(‘load‘,function() {})
// DOMContentLoaded事件 是dom加载完毕
window.addEventListener(‘DOMContentLoaded‘,function() {})
//window.onresize=function(){}
window.addEventListener(‘resize‘, function () {})
1、 setTimeout
setTimeout(() => {},延迟时间)
clearTimeout(定时器名字) 清除定时器
2、 setInterval
setInterval(() => { }, 间隔时间)
clearInterval(定时器名字) 清除定时器
3、如果第二个时间参数不写,默认是0(单位是毫秒)】
// 判断用户是那个终端打开,实现跳转
if ((navigator.userAgent.match(
/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
))) {
window.location.href = ""; //手机
}else{
window.location.href = ""; //电脑
}
element.scrollTop 【元素被卷去的上侧距离,返回数值】
element.scrollLeft 【元素被卷去的左侧距离,返回数值】
注意:(scrollTop 和scrollLeft一般在scroll事件中获取)
element.scrollWidth 【真正的内容width+padding,返回数值】
element.scrollHeight 【真正的内容height+padding,返回数值】
格式:(function(){})()或(function(){}())
作用:创建一个独立的作用域,避免命名冲突
补充:
//使用fastclick :
//1、引入js
//2、在点击事件之前写入:
if (‘addEventListener‘ in document) {
document.addEventListener(‘DOMContentLoaded‘, function () {
FastClick.attach(document.body);
}, false);
}
//3、正常注册点击事件
element.classList.add(‘className‘) 添加类名 是在后面追加类名不会覆盖以前的类名
element.classList.reomve(‘className‘) 删除类名
element.classList.toggle(‘className‘) 切换类
//类名,首字母大写
class Star {
constructor(uname, age) {
this.uname = uname
this.age = age
}
sing(a) {
console.log("我的作品:", a);
}
}
var wyf = new Star(‘kris‘, 29)
console.log(wyf.uname, wyf.age);
wyf.sing(‘july‘)
// class Son extends Father{} 【Son类继承了Father类里面的方法和属性】
// sper 可以调用父类的构造函数或普通函数;super必须在子类this之前调用
// 继承中的属性和方法查找原则:就近原则
// 类里面共有的属性和方法一定要加this
class Father {
constructor(x, y) {
this.x = x
this.y = y
}
sum() { console.log(this.x + this.y); }
money(a) { console.log(a)}
say() { console.log("我是father")}
}
class Son extends Father {
constructor(x, y) {
super(x, y) //super调用了父类里面的构造函数
this.x = x
this.y = y
}
say() {
console.log("我是son")
super.say() //super调用了父类里面的普通函数
}
substract() { console.log(this.x - this.y); }
}
var ss = new Son(10, 20)
ss.money(100)
ss.sum()
ss.say()
ss.substract()
constructor里面的this指向创建的实例化对象
类中方法的this指向 调用该方法的对象
// 利用构造函数创建对象
function Star(name, age) {
// 实例成员:构造函数内部通过this添加的成员,如name,age等
// 实例成员只能通过实例化的对象来访问
this.name = name
this.age = age
this.sing = function (a) {
console.log(a);
}
}
/* new在执行时会做4件事情:
1、在内存中创建一个新的空对象
2、让this指向这个空对象
3、执行构造函数里面的代码,给这个新对象添加属性和方法
4、返回这个新对象(所以构造函数里面不需要return)
*/
var wyf = new Star(‘kris‘, 29)
console.log(wyf.name, wyf.age);
wyf.sing(‘july‘)
// 静态成员:在构造函数身上直接添加的成员
// 静态成员只能通过构造函数来访问
Star.sex = "男"
console.log(Star.sex);
/* 构造函数原型对象prototype
原型对象的作用:共享方法
公共属性定义到构造函数里面,公共方法放在原型对象身上
对象身上系统自己添加一个__proto__属性,指向构造函数的原型对象【对象.__proto__ === 构造函数.prototype】
方法查找规则:先去对象找,如果没有去构造函数原型对象prototype上找
*/
// console.dir(Star);
Star.prototype.eating = function () {
console.log("我在吃饭");
}
// Star.prototype = {
// constructor:Star,
// movie: function () {
// console.log(‘movie‘);
// },
// drink: function () {
// console.log("drink");
// }
// }
wyf.eating()
console.log(wyf);
console.log(wyf.__proto__ === Star.prototype);
console.log(Star.prototype);
console.log(Star.prototype.__proto__ === Object.prototype);
console.log(Object.prototype.__proto__);
console.log(wyf.toString());
// 扩展内置对象
console.dir(Array.prototype);
Array.prototype.sum = function () {
var sum = 0
for (var i = 0; i < this.length; i++) {
sum += this[i]
}
return sum
}
var arr = [1, 2, 3, 4]
console.log(arr.sum());
// 借用call()继承父类中的属性
function Father(name, age) {
this.name = name
this.age = age
}
function Son(name, age, sex) {
Father.call(this, name, age)
this.sex = sex
}
var son = new Son(‘kris‘, 29, ‘男‘)
console.log(son);
// 借用原型对象继承父类中的方法
Father.prototype.money = function () {
console.log("money");
}
son.prototype=new Father()
Son.prototype.constructor=Son
Son.prototype.home = function () {
console.log("home");
}
Object.defineProperty(对象,‘属性名‘,{
value:属性值,
writable:true, //是否允许重写
enumerable:true,//是否可以被枚举 (默认false,false不允许被遍历)
configurable:true//是否可以被删除或修改特性(默认false,false不允许被删除)
})
fn.call(thisArg,参数1,参数2,...) 调用fn,同时把fn中的this指向thisArg
fn.apply(thisArg,[参数1,参数2,...]) 调用fn,同时把fn中的this指向thisArg,apply只能传递数组(或者伪数组)
fn.bind(this.Arg,参数1,参数2,...) 不调用fn,fn中的this指向thisArg,返回原函数this指向改变之后一个新函数
// 求数组中的最大值
var arr = [1, 33, 4, 6, 7, 9, 10]
console.log(Math.max(...arr));
// apply可以用来求数组中的最大值
console.log(Math.max.apply(Math, arr));
开启严格模式:"use strict" 【放在script的最前面或者函数中的最前面】
变化:
变量必须先声明再使用
已经声明的变量不能删除
全局作用域下函数中的this是undefined
构造函数不加new调用 ,this会报错
函数中不能有重名的形参
不允许在非函数块声明函数
Object.assign(target,...被拷贝对象)
封装函数:
function deepClone(obj) {
let objClone = Array.isArray(obj) ? [] : {};
if (obj && typeof obj === "object") {
for (key in obj) {
// obj.hasOwnProperty("属性")返回true/false,判断obj是否包含特定的自身(非继承)属性
if (obj.hasOwnProperty(key)) {
// 判断 obj 是否是对象,如果是,递归复制
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = deepClone(obj[key]);
} else {
// 如果不是
objClone[key] = obj[key];
}
}
}
}
return objClone
}
function deepClone2(newObj, oldObj) {
for (var k in oldObj) {
var item = oldObj[k]
// 判断属性值的数据类型
if (item instanceof Array) {
newObj = []
deepClone2(newObj[k], item)
} else if (item instanceof Object) {
newObj = {}
deepClone2(newObj[k], item)
} else {
newObj[k] = item
}
}
}
var o2={}
deepClone2(o2,obj)
console.log(o2);
JSON.parse(JSON.stringify(被拷贝对象))
$.extend(true, target, 被拷贝对象);
abc 包含abc就可以
^abc 必须以abc开头
^abc$ 必须是abc
[abc] 包含三个中的任何一个
^[abc]$ 必须是三个中的任何一个
^[a-z]$ 必须是26个小写字母中的任何一个
^[a-zA-Z]$ 必须是26大小写个字母中的任何一个
^[a-zA-Z0-9]$ 必须是26大小写个字母,0-9数字中的任何一个
^[a-zA-Z0-9_-]$ 必须是26大小写个字母,0-9数字,_,- 中的任何一个
^[^a-zA-Z0-9_-]$ 不能是26大小写个字母,0-9数字,_,- 中的任何一个 【中括号里面的^表示取反】
[0-9] 包含0-9中的任何一个
* 重复 >=0次
+ 重复 >=1次
? 重复0或1次
{n} 重复n次
{n,} 重复 >=n次
{n,m} 重复n到m次
\d 就是 [0-9]
\D [^0-9]
\w [a-zA-Z0-9]
\W [^a-zA-Z0-9]
\s [\t\r\n\v\f] 换行符,制表符,空格符
\S [^\t\r\n\v\f]
| 表示或
替换: str.replace(str1或正则表达式,str2)
/表达式/g 全局匹配
/表达式/i 忽略大小写
/表达式/gi 全局匹配+忽略大小写
原文:https://www.cnblogs.com/xiaojimeng/p/12821091.html