js中的call 方法,大家应该都有所了解,常用的场景就是实现js的继承 ,但它不只是应用于此,今天就和大家分享一下你不知道的Call方法的使用
(如您已有所了解,可直接挑战面试题,文章最末尾)
01
call 的基本介绍
MDN官方描述:
call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
注意:该方法的语法和作用与 apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组。
语法:
function.call(thisArg, arg1, arg2, ...)
参数
thisArg
可选的。在 function 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
arg1, arg2, ...
指定的参数列表。
返回值
使用调用者提供的 this 值和参数调用该函数的返回值。若该方法没有返回值,则返回
undefined。
02
你知道的call
使用call 方法调用父构造函数在一个子构造函数中,
你可以通过调用父构造函数的 call 方法来实现继承,类似于 Java 中的写法。
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
console.log(new Food('cheese', 5).name);
// expected output: "cheese"03
你不知道的call
使用 call 方法调用匿名函数
这个匿名函数的主要目的是给每个数组元素对象添加一个 print 方法,这个 print 方法可以打印出各元素在数组中的正确索引号。当然,这里不是必须得让数组元素作为 this 值传入那个匿名函数(普通参数就可以),目的是为了演示 call 的用法。
var animals = [
{ species: 'Lion', name: 'King' },
{ species: 'Whale', name: 'Fail' }
];
for (var i = 0; i < animals.length; i++) {
(function(i) {
this.print = function() {
console.log('#' + i + ' ' + this.species
+ ': ' + this.name);
}
this.print();
}).call(animals[i], i);
}使用 call 方法调用函数并且指定上下文的 'this'
在下面的例子中,当调用 greet 方法的时候,该方法的this值会绑定到 obj 对象。
function greet() {
var reply = [this.animal, 'typically sleep between',
this.sleepDuration].join(' ');
console.log(reply);
}
var obj = {
animal: 'cats', sleepDuration: '12 and 16 hours'
};
greet.call(obj);
// cats typically sleep between 12 and 16 hours使用 call 方法调用函数并且不指定第一个参数(argument)
在下面的例子中,我们调用了 display 方法,但并没有传递它的第一个参数。如果没有传递第一个参数,this 的值将会被绑定为全局对象。
var sData = 'Wisen';
function display() {
console.log('sData value is %s ', this.sData);
}
display.call(); // sData value is Wisen注意:在严格模式下,this 的值将会是 undefined。见下文。
'use strict';
var sData = 'Wisen';
function display() {
console.log('sData value is %s ', this.sData);
}
display.call(); // Cannot read the property of 'sData' of undefined今日面试题:
一道call()函数的面试题
function fn1() {console.log(1);}
function fn2() {console.log(2);}
fn1.call(fn2);
fn1.call.call(fn2);
fn1.call.call.call.call(fn2);
fn2.call();
Function.prototype.call(fn2);
Function.prototype.call.call.call(fn2);
Function.prototype.call.call.call(fn1);
//Array.prototype.call([1,2,3]);
// 所以这样调用会报 TypeError 错误,
// Array.prototype.call is not a function( 注:每天的面试题的答案,将在第二天,发在bug收集网站 )