当前位置: 首页 > >

JavaScript高阶函数

发布时间:

函数声明和函数表达式的区别
函数声明如果是放在if-else语句中,在IE8浏览器中可能会出现问题,因为IE8浏览器中在预解析的时候会把函数声明提前,如果有同名的函数,那么后面的函数声明会把前面的函数声明覆盖掉以后可以用函数表达式的尽量用函数表达式
函数的调用
普通函数====》直接调用构造函数====》通过new的方式调用对象方法====》通过对象调用
函数中的this指向问题
普通函数中的this=====》window(页面中的所有内容都是window的)对象.方法中的this======》当前的实例对象定时器方法中的this=====》window(window.setInterval())构造函数中的this======》实例对象原型对象方法中的this======》实例对象
严格模式
在需要使用严格模式的代码上面加上 “use strict”; 那么这个语句后面的代码就必须遵循严格模式的规则(比如方法一定要通过对象调用,对象不能省略,每一个语句都要以分号结尾…),否则会报错
函数也是对象
因为函数中既有prototype,也有__ proto__,对象不一定是函数,但是函数一定是对象所有函数实际上都是由Function的构造函数创建出来的实例对象(即函数的__ proto__指向的是Funtion构造函数的原型对象)

数组中可以存储任何类型的数据,也可以存函数


apply和call方法

apply和call都可以调用函数并且 改变函数中this的指向

apply的使用语法


函数名字.apply(对象,[参数1,参数2,参数3,…]);====》传参数的方式是数组方法名字.apply(对象,[参数1,参数2,参数3,…]);

call的使用语法


函数名字.call(对象,参数1,参数2,参数3,…);方法名字.call(对象,参数1,参数2,参数3,…);

两个方法的作用都是改变this的指向,第一个参数就是函数中this,当传进的是null时函数中的this就是默认的window

只要是想使用别的对象的方法,并希望这个方法是当前对象的,那么就可以使用apply或者call方法改变被调用的方法中this的指向

函数也是对象,对象能够调用apply和call方法说明对象中有这两个方法,要么是在对象实例中存在,要么是在对象所在的构造函数的原型对象中存在,事实上所有的函数都是Function构造函数的实例对象,apply和call方法就是Function.prototype中的方法


function f1(x, y) {
console.log((x + y) + this);
}

f1(10, 20);//普通函数中的this是window=====》这是普通函数调用的一般方式

console.log("======================");

f1.apply();//======>NaN[object Window]
f1.call();//======>NaN[object Window]
/**
* apply和call方法也可以实现对函数的调用
* 当不传参数时,f1函数中的this也是window
*/

console.log("======================");

f1.apply(null, [10, 20]);//======>30[object Window]
f1.call(null, 10, 20);//======>30[object Window]
/**
* apply方法有两个参数,第一个是一个对象,第二个是一个数组(参数数组)
* call方法的第一个参数也是一个对象,之后是个数不定的参数列表
* 当apply和call方法的第一个参数是null时,f1函数中的this还是window
* 第一个对象之后的参数是调用f1时传进到f1中的参数====》apply中使用数组,call中不是数组
*/

console.log("======================");

function f2(x, y) {
console.log((x + y) + this);
return "10000";
}

var result1 = f2.apply(null, [10, 20]);
var result2 = f2.call(null, 10, 20);
console.log(result1);//=======>10000
console.log(result2);//=======>10000
/**
* 当函数有返回值时,使用apply和call方法调用函数的返回值就是被调用函数的返回值
*/

console.log("======================");

function f3(x, y) {
console.log("" + (x + y) + this.sex);
}

window.f3(10, 20);//======>30undefined
obj = {
age: 10,
sex: "男"
};
f3.apply(obj, [10, 20]);//======>30男
f3.call(obj, 10, 20);//=====>30男
/**
* 使用apply和call方法调用函数可以改变函数中this的指向
* 将obj对象作为第一个参数,那么被调用的f3方法就不再属于window了,而是属于obj了,f3方法中的this指向的就是obj对象了
*/

console.log("======================");

//apply和call方法实现改变函数中this的指向的作用
function Person(sex) {
this.sex=sex;
}
//通过原型添加方法
Person.prototype.sayHi=function () {
console.log("您好哇:"+this.sex);
};
var per=new Person("男");
per.sayHi();//=======>您好哇:男
function Student(sex) {
this.sex=sex;
}
var stu=new Student("女");
per.sayHi.apply(stu);//因为sayHi函数本来就没有参数,所以只需要把想指向的对象传进去即可=========》您好哇:女====》apply方法改变了sayHi方法中this的指向
per.sayHi.call(stu);//======>您好哇:女

bind方法
bind方法用来把函数复制一份,返回值复制之后的函数bind的使用语法
函数名字.bind(对象,参数1,参数2,…);方法名字.bind(对象,参数1,参数2,…); bind方法的第一个参数就是复制的函数中的this,当传进的是null时this就是默认的window

function f1(x, y) {
console.log((x + y) + "========>" + this);
}

var ff = f1.bind(null, 10, 20);
ff();//30========>[object Window]
/**
* bind方法指的是把调用bind方法的函数复制一份,同时把参数传到复制的函数中去,返回值是一个函数
* 第一个参数是对象(函数中的this,默认是window),之后的参数是要传到函数中的参数列表
*/

var ff = f1.bind(null);
ff(10, 20);//30========>[object Window]
/**
* 参数可以在调用bind复制函数的时候传进去,也可以在复制完之后调用的时候传递
*/

function Student() {

}

Student.prototype.study = function () {
console.log("今天也是开心地学*");
};
var stu = new Student();
var ff = f1.bind(stu);
ff(20, 30);//50========>[object Object],说明复制的时候就把f1函数中的this指向改变了成为stu对象
/**
* apply和call方法是在函数调用的时候改变this的指向
* bind方法是在复制的时候改变函数中this的指向
*/

function ShowRandom() {
this.number = Math.random() * 10 + 1;
}

ShowRandom.prototype.show1 = function () {
// setInterval(function () {
//
// },1000);

window.setInterval(this.show2.bind(this), 1000);//==================》理解这几个this!!!!
};
ShowRandom.prototype.show2 = function () {
console.log(this.number);
};

var sr=new ShowRandom();
sr.show1();

函数中的几个成员
name属性====》这个属性是只读的arguments属性====》f1.arguments.length指的是函数调用时实参的个数length属性====》函数定义时形参的个数caller属性====》函数的调用者,如f1函数是在f2函数调用的,那么f1.caller就是f2

函数是可以作为参数使用的


函数也是可以作为返回值使用的


作用域、作用域链和预解析
变量分局部变量(在函数内使用var声明的变量)和全局变量,作用域就是变量的使用范围作用域分为全局作用域和局部作用域,但是JS中没有块级作用域的概念作用域链:调用一个变量时,从里向外层层搜索,每一层的级别从里向外递减,搜索到0级作用域时如果还没找到变量,那么结果就是报错预解析:指的是浏览器在解析代码之前,会先把变量声明和函数声明提前(提升)到当前作用域的最上面(注意:声明会提升,但是赋值不会提升)



友情链接: