this总是指向调用某个方法的对象,但是使用call()和apply()方法时,就会改变this的指向。
call方法:
语法:Function.call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj
指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
apply方法:
语法:Function.apply([thisObj[,argArray]])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj,
并且无法被传递任何参数。
call方法跟apply方法并没有明显区别,只是传递参数的形式不一样。
第一个参数是作用域;
call():一个一个的传递参数;
apply():以数组的形式传递。
2.常见用法
2.1. 调用函数
2.2. 将类数组对象转换成数组对象
2.3. 借用别人的方法
2.4. 绑定this指向
2.5. 继承
2.6.实现ES6 扩展运算符功能
2.1 调用函数
function foo() {
console.log(this === window);
}
foo(); // true
foo.call(); // true
foo.apply(); // true
// 在非严格模式下当我们第一个参数传递为null或undefined时,函数体内的this会指向默认的宿主对象,在浏览器中则是window
foo.call(null); // true
foo.call(undefined); // true
2.2 将类数组对象转换成数组对象
运用[].slice.call()让这个aruments类数组有数组方法slice
function person(name, age, high) {
console.log(arguments); // { '0': 'xiaoming', '1': 12, '2': '1.6m' }
var arr = [].slice.apply(arguments);
//[].slice.apply === Array.prototype.apply === [].__proto__.slice
console.log(arr); // ["xiaoming", 12, "1.6m"]
}
person("xiaoming", 12, "1.6m");
2.3 借用别人方法
// 借用Math对象的max方法寻找数组中的最大值
var arr = [1, 2, 3, 4, 5, 6],
max;
max = Math.max.apply(Math, arr);
console.log(max); // 6
2.4 绑定this指向
var foo = {
name: "foo",
showName: function() {
console.log(this.name);
}
}
var bar = {
name: "bar"
}
foo.showName.apply(bar); // bar
2.5 继承
// 定义父类构造函数
var Father = function(name, age) {
this.name = name;
this.age = age;
};
// 定义子类构造函数
var Student = function(name, age, high) {
// 继承父类
Father.call(this, name, age);就是把Father的函数放到this(Student)中运行, name和age是Father的参数。
this.high = high;
};
Student.prototype.message = function() {
console.log("name: " + this.name + ",age: " + this.age + ",high: " + this.high);
}
new Student("xiaoming", 12, "1.6m").message(); // name: xiaoming,age: 12,high: 1.6m
2.6 实现ES6 扩展运算符功能
(_console = console).log.apply(_console, [1, 2, 3]);
2.7 改变函数执行上下文;将函数 fn 的执行上下文改为 obj 对象
***函数中的this指针将被替换为call或者apply的第一个参数。将函数 fn 的执行上下文改为 obj 对象,只需要将obj作为call或者apply的第一个参数传入即可。
1、function speak(fn, obj) {
return fn.call(obj,obj) //Hello, Rebecca!!!
}
speak(
function () {return this.greeting + ', ' + this.name + '!!!';},
{greeting: 'Hello',name: 'Rebecca'})
2、function partial(fn, str1, str2) {
return function (str3) {
return fn.call(this,str1,str2,str3)// Hello, Ellie!!!
}
}
var sayIt = function(greeting, name, punctuation) {
return greeting + ', ' + name + (punctuation || '!');
};
partial(sayIt, 'Hello', 'Ellie')('!!!');