#博学谷IT学习技术支持#
目录
call( )
函数,
apply( )
函数,
bind( )
函数,的作用都是改变
this
的指向,但是在使用方式上是有一定的区别的。
下面我们分别来看一下它们各自的使用方式:
call( )
函数的基本使用
call( )
基本语法如下:
function.call(thisObj,arg1,arg2,...)
function
表示的是:需要调用的函数。
thisObj
表示:
this
指向的对象,也就是
this
将指向
thisObj
这个参数,如果
thisObj
的值为
null
或者是
undefined
,则
this
指向的是全局对象。
arg1,arg2,..
表示:调用的函数需要的参数。
function add(a, b) {
console.log(this);
console.log(a + b);
}
function sub(a, b) {
console.log(a - b);
}
add.call(sub, 3, 1);// 调用add方法,但是add方法中的this指向的是sub,最终的输出结果是4
apply( )
函数的基本使用
apply( )
apply()
函数的作用与
call()
函数的作用是一样的,不同的是在传递参数的时候有一定的差别
语法格式如下:
function.apply(thisObj,[argsArray])
function
表示的是:需要调用的函数。
thisObj
:
this
指向的对象,也就是
this
将指向
thisObj
这个参数,如果
thisObj
的值为
null
或者是
undefined
,则
this
指向的是全局对象。
[argsArray]
:表示的是函数需要的参数会通过数组的形式进行传递,如果传递的不是数组或者是arguments对象,会抛出异常。
function add(a, b) {
console.log(this); // 这里指向的是sub
console.log(a + b);
}
function sub(a, b) {
console.log(a - b);
}
add.apply(sub, [3, 1]);
bind
函数的基本使用
bind
function.bind(thisObj,arg1,arg2,...)
通过上面语法格式,可以看出
bind
函数与
call
函数的参数是一样的。
不同 的是
bind
函数会返回一个新的函数,可以在任何时候进行调用。
function add(a, b) {
console.log(this); // 这里指向的是sub
console.log(a + b);
}
function sub(a, b) {
console.log(a - b);
}
var newFun = add.bind(sub, 3, 1); //bind 返回的是一个新的函数。
newFun();//完成对add函数的调用,同时this指向了sub
三个函数的比较
通过前面对三个函数的基本使用,可以看出,它们共同点就是改变
this
的指向。
不同点:
call()
函数与
apply()
函数,会立即执行函数的调用,而
bind
返回的是一个新的函数,可以在任何时候进行调用。
call()
函数与
bind
函数的参数是一样的,而
apply
函数第二个参数是一个数组或者是
arguments
对象。
应用场景
这里,我们重点看一下,关于
call()
函数,
bind()
函数,
apply()
函数的应用场景。
求数组中的最大值与最小值
var arr = [3, 6, 7, 1, 9];
console.log(Math.max.apply(null, arr));
console.log(Math.min.apply(null, arr));
将
arguments
转换成数组
arguments
function fn() {
var arr = Array.prototype.slice.call(arguments);
arr.push(6);
return arr;
}
console.log(fn(1, 2));
继承的实现
function Person(userName, userAge) {
this.userName = userName;
this.userAge = userAge;
}
function Student(name, age, gender) {
Person.call(this, name, age);
this.gender = gender;
}
var student = new Student("zhangsan", 20, "男");
console.log(
"userName=" +
student.userName +
",userAge=" +
student.userAge +
",gender=" +
student.gender
);
改变匿名函数的
this
指向
this
var person = [
{ id: 1, userName: "zhangsan" },
{ id: 2, userName: "lisi" },
];
for (var i = 0; i < person.length; i++) {
(function (i) {
this.print = function () {
console.log(this.id);
};
this.print();
})(i);
}
具体的实现方式如下:
var person = [
{ id: 1, userName: "zhangsan" },
{ id: 2, userName: "lisi" },
];
for (var i = 0; i < person.length; i++) {
(function (i) {
this.print = function () {
console.log(this.id);
};
this.print();
}.call(person[i], i));
}
手写call、apply及bind函数
call
方法的实现
call
Function.prototype.myCall = function (context) {
var args = [...arguments].slice(1);
context = context || window;
context.fn = this;
var result = context.fn(...args);
return result;
};
function Add(num1, num2) {
console.log(this);
console.log(num1 + num2);
}
function Sub(num1, num2) {
console.log(num1 - num2);
}
Add.myCall(Sub, 6, 3);
apply
函数的实现
apply
Function.prototype.myApply = function (context) {
var result = null;
context = context || window;
context.fn = this;
if (arguments[1]) {
// console.log("arguments=", arguments[1]);// arguments= (2) [6, 3]
result = context.fn(...arguments[1]);
} else {
result = context.fn();
}
return result;
};
function Add(num1, num2) {
console.log(this);
console.log(num1 + num2);
}
function Sub(num1, num2) {
console.log(num1 - num2);
}
Add.myApply(Sub, [6, 3]);
bind
函数的实现
bind
Function.prototype.myBind = function (context) {
// 获取参数
var args = [...arguments].slice(1), // [1,5]
fn = this;
// console.log(this);//Add
return function Fn() {
// console.log(this); //Window
return fn.apply(context, args);
};
};
function Add(num1, num2) {
console.log(this);
console.log(num1 + num2);
}
function Sub(num1, num2) {
console.log(num1 - num2);
}
var newFun = Add.myBind(Sub, 1, 5);
newFun();
<script>
function add(a, b) {
console.log(this); // 这里指向的是sub
console.log(a + b);
}
function sub(a, b) {
console.log(a - b);
}
var newFun = add.bind(sub, 3); //bind 返回的是一个新的函数。
newFun(2); //完成对add函数的调用,同时this指向了sub
</script>
实现关于
myBind
方法参数的模拟
Function.prototype.myBind = function (context) {
// 获取参数
var args = [...arguments].slice(1),
fn = this;
// console.log(this);//Add
return function Fn() {
// console.log(this); //Window
//这里是调用bind函数的时候传递的参数,将其转换成数组
var bindArgs = Array.prototype.slice.call(arguments);
//下面完成参数的拼接
return fn.apply(context, args.concat(bindArgs));
};
};
function Add(num1, num2) {
console.log(this);
console.log(num1 + num2);
return 10;
}
function Sub(num1, num2) {
console.log(num1 - num2);
}
var newFun = Add.myBind(Sub, 1);
console.log(newFun(8));
拓展:为什么函数被称为一等公民?
JavaScript 语言将函数看作一种值,与其它值(数值、字符串、布尔值等等)地位相同。凡是可以使用值的地方,就能使用函数。比如,可以把
函数赋值给变量和对象的属性
,也可以当作
参数传入其他函数
,或者
作为函数的结果返回
。
同时函数还可以作为类的构造函数,完成对象实例的创建。所以说,这种多重身份让
JavaScript
中的函数变得非常重要,所以说函数被称为一等公民。