JavaScript之call()理解

Function.prototype.call()

概念

call()方法使用一个指定的this值和单独给出的一个或多个参数来调用一个函数。前端

注意:该方法的语法和做用与 apply()方法相似,只有一个区别,就是call()方法接受的是 一个参数列表,而apply()方法接受的是 一个包含多个参数的数组
JavaScript中的每个Function对象都有一个apply()方法和一个call()方法,它们的语法分别为:

JavaScript Demo: Function.call()面试

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);    // 输出: cheese

浅显易懂的理解,示例中表达式 Product.call(this, name, price)就等价于segmentfault

this.Product(name, price)

this在此处显然指向对象Food,进一步代入this指向对象和参数为数组

Food.Product('cheese', 5)

语法

fun.call(thisArg, arg1, arg2, ...)
语法我的理解为:
fun.call(thisArg, arg1, arg2, …) 就至关于 thisArg.fun(arg1, arg2, …)
而不论this.Arg初始指向对的是否为对象

参数:浏览器

thisArg
在fun函数运行时指定的this值。须要注意的是,指定的this值并不必定是该函数执行时真正的this值,若是这个函数在 [非严格模式]的this值会自动指向全局对象(浏览器中就是 window 对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。

arg1, arg2, …
指定的参数列表。

返回值:app

使用调用者提供的this值和参数调用该函数的返回值。若该方法没有返回值,则返回undefined。

描述:函数

call()容许为不一样的对象分配和调用属于一个对象的函数/方法。
    
call()提供新的this值给当前调用的函数/方法。你可使用call来实现继承:写一个方法,而后让另一个新的对象来继承它(而不是在新对象中再写一次这个方法)。

示例

使用call方法调用父构造函数
在一个子构造函数中,你能够经过调用父构造函数的call方法来实现继承,相似于Java中的写法。下例中,使用Food和Toy构造函数建立的对象实例都会拥有在Product构造函数中添加的name属性和price属性,但category属性是在各自的构造函数中定义的。
function Product(name, price) {
  this.name = name;
  this.price = price;
}

function Food(name, price) {
  Product.call(this, name, price);
  this.category = 'food';
}

function Toy(name, price) {
  Product.call(this, name, price);
  this.category = 'toy';
}

var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);

使用call方法调用匿名函数
在下例中的for循环体内,咱们建立了一个匿名函数,而后经过调用该函数的call方法,将每一个数组元素做为指定的this值执行了那个匿名函数。这个匿名函数的主要目的是给每一个数组元素对象添加一个print方法,这个print方法能够打印出各元素在数组中的正确索引号。固然,这里不是必须得让数组元素做为this值传入那个匿名函数(普通参数就能够),目的是为了演示call的用法。this

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对象。spa

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的值将会被绑定为全局对象。prototype

var sData = 'Wisen';

function display() {
  console.log('sData value is %s ', this.sData);
}

display.call();  // sData value is Wisen
此处的理解是:display.call() 就至关于 this.display() ,非严格模式下,此处this显然指向全局window,也就等价于window.dispaly() ,也就是调用了display()。
严格模式下,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

推荐阅读:
2019年前端面试题-01
2019年前端面试题-02
2019年前端面试题-03
2019年前端笔试题


我是Cloudy,年轻的前端攻城狮一枚,爱专研,爱技术,爱分享。
我的笔记,整理不易,感谢阅读、点赞和收藏。
文章有任何问题欢迎你们指出,也欢迎你们一块儿交流前端各类问题!
相关文章
相关标签/搜索