apply/call/bind/函数

重点:

apply/call 都可以改变 this 的指向
apply 和 call 的使用方法
apply 和 call 方法中如果没有传入参数,或者是传入的是 null,那么调用该方法的函数对象中的 this 就是默认的 window

  • apply 的使用语法
  • 函数名字.apply(对象,[参数 1,参数 2,…]);
  • 方法名字.apply(对象,[参数 1,参数 2,…]);
  • call 的使用语法
  • 函数名字.call(对象,参数 1,参数 2,…);
  • 方法名字.call(对象,参数 1,参数 2,…);
  • 作用:改变 this 的指向
  • 不同的地方:参数传递的方式是不一样的
  • 只要是想使用别的对象的方法,并且希望这个方法是当前对象的,那么就可以使用 apply 或者是 call 的方法改变 this 的指向

bind
bind 是用来复制一份
使用的语法:

  • 函数名字.bind(对象,参数 1,参数 2,…);—->返回值是复制之后的这个函数
  • 方法名字.bind(对象,参数 1,参数 2,…);—->返回值是复制之后的这个方法

函数
函数的值
函数中有一个 name 属性—–>函数的名字,name 属性是只读的,不能修改
函数中有一个 arguments 属性—>实参的个数
函数中有一个 length 属性—->函数定义的时候形参的个数
函数中有一个 caller 属性—->调用(f1 函数在 f2 函数中调用的,所以,此时调用者就是 f2)
函数作为参数的时候,如果是命名函数,那么只传入命名函数的名字,没有括号
函数可作为返回值

练习代码

apply/call

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//案例一
function Person(age,sex) {
this.age=age;
this.sex=sex;
}
//通过原型添加方法
Person.prototype.sayHi=function (x,y) {
console.log("您好啊:"+this.sex);
return 1000;
};
var per=new Person(10,"男");
per.sayHi();

console.log("==============");
function Student(name,sex) {
this.name=name;
this.sex=sex;
}
var stu=new Student("小明","人妖");
var r1=per.sayHi.apply(stu,[10,20]);
var r2=per.sayHi.call(stu,10,20);

console.log(r1);
console.log(r2);

//案例二
function f1() {
console.log(this+":====>调用了");
}
//f1是函数,f1也是对象
console.dir(f1);
//对象调用方法,说明,该对象中有这个方法
f1.apply();
f1.call();
console.log(f1.__proto__==Function.prototype);
//所有的函数都是Function的实例对象
console.log(Function.prototype);//ƒ () { [native code] }
console.dir(Function);
//apply和call方法实际上并不在函数这个实例对象中,而是在Function的prototype中


function Person() {
this.sayHi=function () {
console.log("您好");
};
}
Person.prototype.eat=function () {
console.log("吃");
};

var per=new Person();
per.sayHi();
per.eat();
console.dir(per);

bind

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//通过对象,调用方法,产生随机数

function ShowRandom() {
//1-10的随机数
this.number=parseInt(Math.random()*10+1);
}
//添加原型方法
ShowRandom.prototype.show1=function () {
//改变了定时器中的this的指向了,本来应该是window,现在是实例对象了
window.setInterval(this.show2.bind(this),1000);
};
//添加原型方法
ShowRandom.prototype.show2=function () {
//显示随机数--
console.log(this.number);
};
//实例对象
var sr=new ShowRandom();
//调用方法,输出随机数字
//调用这个方法一次,可以不停的产生随机数字
sr.show1();

函数

函数作为参数使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//案例一
function f1(fn) {
console.log("f1的函数");
fn();//此时fn当成是一个函数来使用的
}
//fn是参数,最后作为函数使用了,函数是可以作为参数使用
//传入匿名函数
f1(function () {
console.log("我是匿名函数");
});
//命名函数
function f2() {
console.log("f2的函数");
}
f1(f2);
//函数作为参数的时候,如果是命名函数,那么只传入命名函数的名字,没有括号


//案例二
function f1(fn) {
setInterval(function () {
console.log("定时器开始");
fn();
console.log("定时器结束");
},1000);
}

f1(function () {
console.log("好困啊,好累啊,就是想睡觉");
});

//案例三
// var arr = [1, 100, 20, 200, 40, 50, 120, 10];
// //排序
// arr.sort();
// console.log(arr);

var arr = [1, 100, 20, 200, 40, 50, 120, 10];
//排序---函数作为参数使用,匿名函数作为sort方法的参数使用,那么此时的匿名函数中有两个参数,
arr.sort(function (obj1,obj2) {
if(obj1>obj2){
return -1;
}else if(obj1==obj2){
return 0;
}else{
return 1;
}
});
console.log(arr);

var arr1=["acdef","abcd","bcedf","bced"];
arr1.sort(function (a,b) {
if(a>b){
return 1;
}else if(a==b){
return 0;
}else{
return -1;
}
});
console.log(arr1);

函数作为返回值使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//案例一
//判断这个对象和传入的类型是不是同一个类型
function getFunc(type) {
return function (obj) {
return Object.prototype.toString.call(obj) === type;
}
}

var ff = getFunc("[object Array]");
var result = ff([10, 20, 30]);
console.log(result);

var ff1 = getFunc("[object Object]");
var dt = new Date();
var result1 = ff1(dt);
console.log(result1);

//案例二
//排序,每个文件都有名字,大小,时间,都可以按照某个属性的值进行排序

//三部电影,电影有名字,大小,上映时间
function File(name, size, time) {
this.name = name;//电影名字
this.size = size;//电影大小
this.time = time;//电影的上映时间
}
var f1 = new File("jack.avi", "400M", "1997-12-12");
var f2 = new File("tom.avi", "200M", "2017-12-12");
var f3 = new File("xiaosu.avi", "800M", "2010-12-12");
var arr = [f1, f2, f3];

function fn(attr) {
//函数作为返回值
return function getSort(obj1, obj2) {
if (obj1[attr] > obj2[attr]) {
return 1;
} else if (obj1[attr] == obj2[attr]) {
return 0;
} else {
return -1;
}
}
}

var ff = fn("name");

//函数作为参数
arr.sort(ff);
for (var i = 0; i < arr.length; i++) {
console.log(arr[i].name + "====>" + arr[i].size + "===>" + arr[i].time);
}
-------------本文结束感谢您的阅读-------------
0%