一、复习
函数一定是对象,对象不一定是函数
二、apply 和 call
都可以让函数或方法调用,传参和调用的写法不同,效果一样
改变this 指向,指向传入的这个对象
f1.apply(对象,[10,20 ]) == f1(10,20)
f1.call (对象,10 , 20 ) this 指向stu ,获取到的属性都是stu的
apply 和 call 方法都包含在Function 的prototype 中,故可以直接调用
三、bind :用来复制
复制的时候改变this的指向
方法.bind(对象2,[参数1,.....参数n]); this 指向对象2
在func1 中实用的this 指向对象2 返回复制后的方法
函数名字.bind(对象,参数1,......参数n) 返回复制后的函数
若bind里有this ,则this 代表 方法/函数名 指向的对象
关键理解 bind(对象) 里这个对象的指向,对于this 的指向可以看看调用它的对象的指向
//通过对象,调用方法,产生随机数
function ShowRandom() {
//1-10的随机数
this.number=parseInt(Math.random()*10+1);
}
//添加原型方法
ShowRandom.prototype.show1=function () {
//改变了定时器中的this的指向了,本来应该是window,现在是实例对象了
// this.show2 指向的是实例对象,而不是window,故每次都会调用 实例对象
window.setInterval(this.show2.bind(this),1000);
};
//添加原型方法
ShowRandom.prototype.show2=function () {
//显示随机数--
console.log(this.number);
};
//实例对象
var sr=new ShowRandom();
//调用方法,输出随机数字
//调用这个方法一次,可以不停的产生随机数字
sr.show1();
四、函数成员
函数默认带有
function.name 函数名
function.arguments 实参的个数
function.lenght 定义时,形参的个数
function.caller 该函数的调用者(输出调用者的结构)
函数作为参数
函数作为参数的时候,如果是命名函数,那么只传入命名函数的名字,没有括号
函数作为返回值
返回一个函数,接收参数作为函数使用 typeof 获取类型 instanceof 判断类型
获取某个对象的数据类型的样子
Object.prototype.toString.call (对象) // 得到这个对象类型的样子
获取某对象的类型是不是你传入的样子
五、闭包
function f1() {
var num=parseInt(Math.random()*10+1);
return function () {
console.log(num);
}
}
var ff=f1();
ff();
ff();
ff();
* 闭包的概念:
函数闭包:
函数A中,有一个函数B,函数B中可以访问函数A中定义的变量或者是数据,此时形成了闭包
对象闭包:
函数中有一个对象,对象可以使用函数里的值
* 闭包的模式:函数模式的闭包,对象模式的闭包
* 闭包的作用:缓存数据,延长作用域链
如果想要缓存数据,就把这个数据放在外层的函数和里层的函数的中间位置。局部变量的使用作用域链就会被延长
* 闭包的优点和缺点:缓存数据(优点也是缺点)
使用后不会及时释放
六、沙箱
自调用函数就相当于一个沙箱,一个虚拟的环境
自调用函数里定义的变量,与外部变量不冲突,且在函数内部可以使用,小环境里可以访问大环境里的变量。函数都在自调用函数里,因此可以避免冲突(当函数与变量名冲突时,沙箱很有用)
<div>这是div</div>
<div>这是div</div>
<div>这是div</div>
<p>这是p</p>
<p>这是p</p>
<p>这是p</p>
<script>
var getTag = 10;
var dvObjs = 20;
var pObjs = 30;
(function () {
//根据标签名字获取元素
function getTag(tagName) {
return document.getElementsByTagName(tagName)
}
//获取所有的div
var dvObjs = getTag("div");
for (var i = 0; i < dvObjs.length; i++) {
dvObjs[i].style.border = "2px solid pink";
}
//获取所有的p
var pObjs = getTag("p");
for (var i = 0; i < pObjs.length; i++) {
pObjs[i].style.border = "2px solid pink";
}
}());
console.log(getTag);
console.log(dvObjs);
console.log(pObjs);
七、浅拷贝+深拷贝
浅拷贝:直接复制内容到另一个对象。(两个变量指向相同的内容,地址不同)
var obj1={
age:10,
sex:"男",
car:["奔驰","宝马","特斯拉","奥拓"]
};
//另一个对象
var obj2={};
//写一个函数,作用:把一个对象的属性复制到另一个对象中,浅拷贝
//把a对象中的所有的属性复制到对象b中
function extend(a,b) {
for(var key in a){
b[key]=a[key];
}
}
extend(obj1,obj2);
console.dir(obj2);//开始的时候这个对象是空对象
console.dir(obj1);//有属性
深拷贝:
在另一个对象中开辟空间。比浅拷贝增加判断数据类型(对象还是数组)
八、遍历DOM树
遍历出页面上所有的节点
var root=document.documentElement; // html 节点
function forDom(root){
var children=root.children;
forchildren(children);
}
function forchildren(children){
for(var i=0;i<children.length;i++){
var child=children[i];
console.log(child.nodeName);
child.children&&forDom(child);
}
}
forDom(root);
九、正则表达式
元字符/ 限定符 组成的式子。作用匹配字符串
两种创建方式:
1、构造函数
var reg=new RegExp(/正则表达式/);
2、字面量
var reg=/\d{1,5}/ reg.test("asdasd:123");
. 除了\n 以外的任意字符 [] 范围:100到200: [1][0-9][0-9] [0~9a~zA~Z] 数字或字母中的任意一个
| 或 ()分组/优先级 * :任意次 ? : 0~1次 + :1次到多次 {0,}=== * {1, } === + {0,1} === ? {5 , 10 } 5 次到10次
^[0-9] 以什么开头 [^0-9 ] 非0~9 $ 表示的是以什么结束 [0-9][a-z]$ 必须以小写字母结束
^[0-9][a-z]$ 相当于是严格模式 "3f2432e" ^[0-9][a-z]$:"4f"
\d 数字中的任意一个,== [0-9] \D 非数字中的一个
\s 空白符中的一个 \S 非空白符
\w 非特殊符号 有_ \W 特殊符号
\b 单词的边界
邮箱的正则:
[0-9a-zA-Z_.-]+[@][0-9a-zA-Z_.-]+([.][a-zA-Z]+){1,2}
验证密码的强度
中文的正则:
var reg=/^[\u4e00-\u9fa5]{2,6}$/;
//g 全局匹配 //i 忽略大小写
var str="shuaiyangtaishuaile@126.com.cn";
var array=str.match(/([0-9a-zA-Z_.-]+)[@]([0-9a-zA-Z_-]+)(([.][a-zA-Z]+){1,2})/);
RegExp.$1/$2/$3 获取第一部分+第二部分+第三部分
str.match(正则表达式); str.replace(正则表达式/正则对象,要替换的元素);
var reg=/\d{5}/g;
var result=reg.exec(str);
while(result!=null){
console.log(result);
result=reg.exec(str);
}
十一、数组和伪数组
正常的数组可以使用 length 、 forEach 等方法,长度可变
伪数组:长度不可变。典型的是 一个对象作为数组,如果伪数组里没有设对应下标的值,则拿不到