目录
一、严格模式
Ⅰ.开启严格模式
可以应用到整个脚本或个别函数中,因此使用时,我们可以将严格模式分为脚本开始模式和为函数开启严格模式两种情况
1.为脚本开启严格模式
①为整个脚本文件开启严格模式,需要在所有语句之前放一个特定语句”use strict”;(或 ‘use strict’;)
②将整个脚本文件放在一个立即执行的匿名函数之中,这样独立创建一个作用域而不影响其他script脚本文件
2.为函数开启严格模式
要给某个函数开启严格模式,需要把”use strict”;(或 ‘use strict’;)声明放在函数体所有语句之前
Ⅱ.严格模式的变化
1.变量规定
①在正常模式中,如果一个变量没有声明就赋值,默认是全局变量,严格模式禁止这种用法,变量都必须先用var命令声明,然后再使用
②严禁删除已经声明变量,例如,delete x ;语法是错误的
2.严格模式下this指向问题
①以前在全局作用域函数中的this指向window对象,严格模式下全局作用域中函数中的this是undefined
②以前构造函数时不加new也可以调用当普通函数,this指向全局对象,严格模式下,构造函数不加new调用,this会报错
③new实例化的构造函数指向创建的对象实例
④在严格模式下,定时器的this还是指向window
⑤事件、对象还是指向调用者
3.函数变化
①函数不能有重名的参数
②函数必须声明在顶层,不允许在非函数的代码块内声明函数
二、高阶函数
① 对其他函数进行操作的函数,它接收函数作为参数或将函数作为返回值输出
②函数也是一种数据类型,同样可以作为参数,传递给另一个参数使用。最典型的就是作为回调函数
1. 变量作用域
全局变量和局部变量
- 函数内部可以使用全局变量
- 函数外部不可以使用局部变量
- 当函数执行完毕,本作用域内的局部变量会销毁
2. 闭包
有权访问另一个函数作用域中的变量的函数
一个作用域可以访问另一个函数内部的局部变量
作用:延伸了变量的作用范围
// 闭包应用-点击li输出当前li的索引号
//立即执行函数也称为小闭包,因为立即执行函数里面的任何一个函数都可以使用它的i这个变量
var lis = document.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
//利用for循环创建了4个立即执行函数
(function(i) {
lis[i].onclick = function() {
console.log(i);
}
})(i)
}
//bind使用-三秒钟之后,打印所有li元素的内容
var lis = document.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
setTimeout(function(i) {
console.log(lis[i].innerHTML);
}.bind(null, i), 3000)
}
//闭包应用-三秒钟之后,打印所有li元素的内容
var lis = document.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
(function(i) {
setTimeout(function() {
console.log(lis[i].innerHTML);
}, 3000)
})(i);
}
//思考题1
var name = 'The Window';
var object = {
name: 'My Object',
getNameFunc: function() {
return function() {
return this.name;
}
}
};
console.log(object.getNameFunc()()); //The Window
//分析
//var f=object.getNameFunc();
// var f=function(){
// return this.name
// }
//f();
// (function() {
// return this.name; //立即执行函数的this指向window
// })()
//思考题2
var name = 'The Window';
var object = {
name: 'My Object',
getNameFunc: function() {
var that = this; //对象的方法里面this指向对象
return function() {
return that.name; //that指向对象那个
}
}
};
console.log(object.getNameFunc()()); //My Object
3.递归
如果一个函数在内部可以调用其本身,那么这个函数就是递归函数
由于递归很容易发生栈溢出错误,所以必须要加退出条件return
//利用递归求:根据id返回对应的数据对象
var data = [{
id: 1,
name: '家电',
goods: [{
id: 11,
gname: '冰箱'
}, {
id: 12,
gname: '洗衣机'
}]
}, {
id: 2,
name: '服饰',
goods: [{
id: 21,
gname: '上衣'
}, {
id: 22,
gname: '下衣'
}]
}];
// 我们想要输入id号,就可以返回的数据对象
//使用foreach方法
var obj = {}; //obj不声明也可以,这样函数里面的obj默认是全局变量
function getID(json, id) {
json.forEach(function(val, i, array) {
if (val.id === id) {
obj = val;
} else if (val.goods && val.goods.length > 0) {
obj = getID(val.goods, id);
}
});
return obj;
}
// 我们想要输入id号,就可以返回的数据对象
// 使用some方法 方法一
var obj={}; //obj不声明也可以,这样函数里面的obj默认是全局变量
function getID(json, id) {
json.some(function(val, i, array) {
if (val.id === id) {
obj = val;
return true;
} else if (val.goods && val.goods.length > 0) {
obj = getID(val.goods, id);
}
});
return obj;
}
// 使用some方法 方法二
function getID(json, id) {
var obj = null;
json.some(function(val, i, array) {
if (val.id === id) {
obj = val;
return true;
} else if (val.goods && val.goods.length > 0) {
obj = getID(val.goods, id);
if (obj != null) { //防止前面找到后,再循环覆盖前面的赋值的obj
return true;
}
}
});
return obj;
}
console.log(getID(data, 1));
console.log(getID(data, 2));
console.log(getID(data, 11));
console.log(getID(data, 12));
console.log(getID(data, 21));
console.log(getID(data, 22));
4.深拷贝和浅拷贝
深拷贝 拷贝多层,每一级别的数据都会拷贝
浅拷贝 只是拷贝一层,更深层次对象级别的只拷贝引用
Object.assign(target,...sources) es6新增方法可以浅拷贝
var obj = {
id: 1,
name: 'andy',
msg: {
age: 18
},
color: ['pink', 'red']
};
var o = {};
//浅拷贝
for (var k in obj) {
o[k] = obj[k];
}
//es6浅拷贝
Object.assign(o, obj)
//深拷贝
function deepCopy(newobj, oldobj) {
for (var k in oldobj) {
//判断我们的属性值属于哪种数据类型
// 1.获取属性值
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;
}
}
}
三、正则表达式
1.创建正则表达式
①调用RegExp对象的构造函数创建
var 变量名=new RegExp(/表达式/);
②通过字面量创建
var 变量名=/表达式/;
正则表达式里面不需要加引号,不管是数字型还是字符串型
2.测试正则表达式test
test()正则对象方法,用于检测字符串是否符合该规则,该对象会返回true或false,其参数是测试字符串
regexobj.test(str)
regexobj:写的正则表达式
str:测试的文本
就是检测str文本是否符合我们写的正则表达式规范
var reg=/abc/; //要求字符串中有a、b、c字符并且三者的位置是abc
console.log(reg.test("abc")); //true
console.log(reg.test("abcd")); //true
console.log(reg.test("aabcd"));//true
console.log(reg.test("abdc"));//false
3.边界符
一个正则表达式可以由简单的字符构成,比如/abc/,也可以是简单和特殊字符的组合,其中特殊字符也称为元字符,在正则表达式中是具有特殊意义的专有符号,如^、$、+等
^ 表示匹配行首的文本(以谁开始)
$ 表示匹配行尾的文本(以谁结束)
如果^和$在一起,表示必须是精确匹配
var reg1=/^abc/; //要求是以abc开头的字符
console.log(reg1.test("aabc"));//false
var reg2=/abc$/; //要求是以abc结尾的字符串
console.log(reg2.test("abcc")); //false
var reg3=/^abc$/; //要求必须是abc字符串
console.log(reg3.test("abbc"));//false
4.字符类
[]表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内
var rg = /[abc]/; //只要包含有a或者包含有b或者包含有c都返回true
var rg1 = /^[abc]$/ //三选一,只有a或者b或则c才返回true
[-] 方括号内部范围符-
如果[]里面有^表示取反
5.量词符
用来设定某个模式出现的次数
* 重复零次或更多次
+ 重复一次或更多次
?重复零次或一次
{n} 重复n次
{n,}重复n次或更多次
{n,m} 重复n到m次
中括号 字符集合,匹配方括号中的任意字符
大括号 量词符 里面表示重复次数
小括号 表示优先级
var reg = /^abc{3}$/; //它只是让c重复三次
var reg = /^(abc){3}$/; //它让abc重复三次
6.预定义类
某些常见模式的简写方式
\d 匹配0-9之间的任一数字,相当于[0-9]
\D 匹配所有0-9以外的字符,相当于[^0-9]
\w 匹配任意的字母、数字、下划线,相当于[A-Za-z0-9_]
\W 除所有字母、数字、下划线以外的字符、相当于[^A-Za-z0-9_]
\s 匹配空格(包括换行符、制表符、空格符等),相等于[\t\r\n\v\f]
\S 匹配非空格的字符,相当于[^\t\r\n\v\f]
7.正则表达式中的替换
replace替换
replace()方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则表达式
stringObject.replace(regexp/substr,replacement)
第一个参数:被替换的字符串或者正则表达式
第二个参数:替换为的字符串
返回值是一个替换完毕的新字符串
8.正则表达式参数
/表达式/[switch]
switch(也称为修饰符)按照什么样的模式来匹配,有三种值
g:全局匹配
i:忽略大小写
gi:全局匹配和忽略大小写