apply()和call()
apply使用语法:
函数名/方法名.apply(对象,[参数1,参数2...]);
call使用语法:
函数名/方法名.call(对象,属性1,属性2...)
作用:
可以改变this的指向
不同点:
参数传递方式不同
只要是想使用别的对象的方法,并且希望这个方法是当前对象的,那么就可以使用apply或者是call的方法改变this的指向
其他对象.方法名.apply(对象,[...]);
apply和call方法中如果没有传入参数,或者是传入的是null,那么调用该方法的函数对象中的this就是默认的window
apply和call都可以让函数或者方法来调用,传入参数和函数自己调用的写法不一样,但是效果是一样的
bind():
bind是复制一个方法或者函数
bind 返回的是对应函数,便于稍后调用;apply 、call 则是立即调用 。
xw.say.call(xh);
xw.say.apply(xh);
xw.say.bind(xh)(); // call和apply都是对函数的直接调用,而bind方法返回的仍然是一个函数,即函数末尾加()
注:
Math.random( ) 返回介于 0(包含) ~ 1(不包含) 之间的一个随机数
函数:
函数中几个属性(了解):
name:函数名,只读(不可修改)
arguments:实参(调用该函数时传入的具体参数)个数
length:形参(函数声明时的变量)个数
caller:函数的调用者(f1函数在f2中调用,则f2为调用者)
备注:
例:
function add(a,b) {
return a + b
};
add(1,2); //声明函数add时,a,b就是形参。调用函数add(1,2) 1,2就是实参
1.函数可作为参数使用
function f1(fn) {
console.log("f1的函数");
fn();//此时fn当成是一个函数来使用的
}
fn是参数,最后作为函数使用了,函数是可以作为参数使用的
例:数组排序
var arr = [40,100,1,5,25,10];
方法一:
arr.sort(function(a,b){return a-b});//输出结果:1,5,10,25,40,100
方法二:
arr.sort(function(a,b){
if(a>b){
return 1;
}else if(a==b){
return 0;
}else{
return -1;
}
});
console.log(arr);
2.函数可作为返回值
function f1(){
return function(){
console.log("函数是作为返回值使用的");
}
}
var ff=f1();
ff();
3.匿名函数
f1(function () {
console.log("我是匿名函数");
});
4.命名函数
function f2() {
console.log("f2的函数");
}
f1(f2);
注意:函数作为参数的时候,如果是命名函数,那么只传入命名函数的名字,没有括号
typeof:获取变量的数据类型
instenceof:判断这个对象是不是某个数据类型
获取某个对象的数据类型:[object Object/Array/Date...]
Object.prototype.toString.call(对象);
函数的作用域:
函数的变量分为局部变量和全局变量
注:函数中定义的是局部变量
函数的作用域就是变量的使用范围
注:js中没有块级作用域(一对括号中定义的变量,这个变量可以在大括号外面使用)
作用域链:
变量的使用,从里向外,层层的搜索,搜索到了就可以直接使用了;
若层层搜索,搜索到0级作用域的时候,如果还是没有找到这个变量,结果就是报错
var num=10; //作用域链 级别:0
function f1() {
var num=20;//作用域链 级别:1
function f2() {
var num=30;//作用域链 级别:2
console.log(num);
}
f2();
}
f1();
预解析:
就是在浏览器解析代码之前,把变量的声明和函数的声明提前(提升)到该作用域的最上面
闭包:
概念:
函数A中有一个函数B,函数B中可以访问函数A中定义的变量或者是数据,此时形成了闭包(不严谨)
模式:
1.函数模式的闭包(函数中有一个函数);
2.对象模式的闭包(函数中有一个对象)。
作用:
缓存数据,延长作用域链
优缺点:
缓存数据,是优点也是缺点,因为数据没有及时释放
注意:
局部变量是在函数中,函数使用结束后,局部变量就会被自动的释放
闭包后,里面的局部变量的使用作用域链就会被延长
沙箱:
就是一个环境,也可以叫黑盒,在这个环境中模拟外面真实的开发环境,完成需求,效果和外面的真实的开发环境是一样的;
沙箱可以避免命名冲突
递归:
在函数中调用自己,但一定要有结束的条件,否则就是死循环。
应用: 遍历;递归不轻易使用,效率很低
浅拷贝:把一个对象的地址给了另一个对象,其指向相同(浅拷贝只改变指向);
深拷贝:
获取键值对:
for(var key in obj1){
console.log(key);//获取key
console.log(obj1[key]);//获取value
}
正则表达式:
作用:匹配字符串
创建正则表达式对象:
1.通过构造函数创建对象
2.字面量方式创建对象
1.正则表达式创建对象
var reg=new RegExp(/\d+/);
var str="我的电话号码是100649";
var flag=reg.test(str);//调用字符串验证是否匹配
console.log(flag);
2.字面量方式创建对象
var reg1=/\d{2,5}/;
var flag1=reg.test("小涵的幸运数字是369");
console.log(flag1);
简写:
console.log(/\d{2,5}/.test("小涵的幸运数字是9"));
伪数组:(类数组)
无法直接调用数组方法或期望length属性有什么特殊的行为,不具有数组的push,pop等方法,但仍可以对真正数组遍历方法
来遍历它们。
典型的是函数的argument参数,还有像调用getElementsByTagName,document.childNodes之类的,它们都返回NodeList
对象都属于伪数组。
可以使用Array.prototype.slice.call(fakeArray)将数组转化为真正的Array对象。
这里把符合以下条件的对象称为伪数组:
1.具有length属性
2.按索引方式存储数据
3.不具有数组的push,pop等方法