首页 web前端 js教程 浅谈javascript的call()、apply()、bind()的用法_javascript技巧

浅谈javascript的call()、apply()、bind()的用法_javascript技巧

May 16, 2016 pm 03:14 PM
javascript

JavaScript中的函数不仅是一种类似于Java中方法的语言功能,它还可以作为对象而存在。 本文将要探讨JavaScript中函数的一些特殊用法,包括call、apply、bind三个原型方法。
一、函数基础
JavaScript中的函数是一种类似于Java中方法的语言功能,不过它可以独立于类进行定义。

函数式编程:由于JavaScript支持匿名函数,因此可以将函数作为对象来使用, 所以JavaScript不仅支持过程式编程(面向对象也是过程式编程的一种),还支持函数式编程。
上下文

函数的每次调用都会拥有一个特殊值——本次调用的上下文(context)——这就是this关键字的值。 如果函数挂载在一个对象上,作为对象的一个属性,就称它为对象的方法。当通过这个对象来调用函数时,该对象就是此次调用的上下文, 也就是该函数的this的值。

需要注意,this是一个关键字,不是变量,也不是属性名。JavaScript的语法不允许给this赋值。

函数是一种对象

JavaScript中的函数和Java中的方法或C语言中的函数最大不同在于,JavaScript中的函数也是一种对象。 但这并不意味着,所有的对象都是函数。函数是一种包含了可执行代码,并能够被其他代码调用的特殊的对象。

和变量不同,关键字this没有作用域的限制,嵌套的函数不会从调用它的函数中继承this。 - 如果嵌套函数作为方法调用,其this的值指向调用它的对象。 - 如果嵌套函数作为函数调用,其this的值不是全局对象(非严格模式下)就是undefined(严格模式下)。

很多人误以为调用嵌套函数时this会指向掉i用外层函数的上下文。如果你想访问这个外部函数的this值, 需要将this的值保存都在一个变量中,这个变量和内部函数都同在一个作用域内。例如:

var o = {
 m: function() {
  var self = this;
  console.log(this==o); // true
  f();
  
  function f() {
   console.log(this === o); // false,this的值是全局对象或undefined
   console.log(self === o); // true
  }
 }
}
登录后复制

闭包

JavaScript的函数可以嵌套在其他函数中定义,这样它们就可以访问它们被定义时所处的作用域中的任何变量。 这意味着JavaScript函数构成了一个闭包(closure),它给JavaScript带来了非常强劲的编程能力。

作为值的函数
在JavaScript中,函数不仅是一种语法,也是值,也就是说,可以将函数赋值给变量,存储在对象的属性或数组的元素中, 作为参数传入另外一个函数等。

bind、call、apply
每一个函数都包含一个prototype属性,这个属性是指向一个对象的引用,这个对象称作“原型对象”。 每一个函数都包含不同的原型对象。当将函数用作构造函数的时候,新创建的对象会从原型对象上继承属性。

Function.prototype.call()Function.prototype.apply()

call()和apply()可以看作为某个对象的方法,通过调用方法的形式来间接调用函数。 它们的第一个参数是要调用函数的母对象,它是调用上下文,在函数体内通过this来获得对它的引用。 apply()方法和call()方法的作用相同,只不过函数传递的方式不一样,它的实参都放入在一个数组中。

举个例子,以对象o的方法的形式调用函数f(),并传入两个参数,可以使用这样的代码:

var o = {};

function f(a, b) {
 return a + b;
}

f.call(o, 1, 2);    // 将函数f作为o的方法,实际上就是重新设置函数f的上下文
f.apply(o, [1, 2]);
登录后复制

再举一个例子,使用call方法调用匿名函数:

在下例中的for循环体内,我们创建了一个匿名函数,然后通过调用该函数的call方法,将每个数组元素作为指定的this值执行了那个匿名函数。 这个匿名函数的主要目的是给每个数组元素对象添加一个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);
}

登录后复制

Function.prototype.bind()

bind()是在ES5中新增的方法,从名字可以看出,这个方法的主要作用就是将函数绑定到某个对象。 当在函数f()上调用bind()方法并后窜入一个对象o作为参数,这个方法将返回一个新函数: (以函数调用的方式)调用新的函数将会把原始的函数f()作为o的方法来调用。例如:

function f(y) {
 return this.x + y;
}

var o = {
 x: 1
};

var g = f.bind(o); // 通过调用 g(x) 来调用 o.f(x)
g(2); // 3

登录后复制

其实我们可以轻松的实现bind()方法:

// 返回一个函数,通过调用它来调用o中的方法f(),传递它所有的实参
function bind(f, o) {
 if (f.bind) return f.bind(o); // 如果bind()方法存在,使用bind()方法
 else return function () {
  return f.apply(o, arguments);
 }
}

登录后复制

二、函数式编程
JavaScript并非函数式编程语言,但在JavaScript中可以像操控对象一样操控函数,也就是说可以在JavaScript中应用函数式编程技术。

使用函数处理数组

假设有一个数组,数组元素都是数字,我们想要计算这些元素的平均值和标准差。

var data = [1, 1, 3, 5, 5];
var sum = function(x, y) {
 return x + y;
};
var square = function(x) {
 return x * x;
};

var mean = data.reduce(sum)/data.length;
var deviations = data.map(x => x - mean);

登录后复制

var stddev = Math.sqrt(deviations.map(square).reduce(sum)/(data.length - 1));
高阶函数

高阶函数就是操作函数的函数,它接收一个或多个函数作为参数,并返回一个新函数。举个例子:

function not(f) {
 return function () {
  var result = f.apply(this, arguments);
  return !result;
 };
}

// 判断x是否为偶数的函数
var even = function(x) {
 return x % 2 === 0;
};

var odd = not(even);      // 一个新函数,所做的事情和even()相反
[1, 1, 3, 5, 5].every(odd);   // true,每个函数都是奇数

登录后复制

函数not()是个高阶函数,因为它返回一个新的函数,这个新函数将它的实参传入f(),并返回f的返回值的逻辑非。

以上就是关于javascript的call()、apply()、bind()的用法,希望对大家的学习有所帮助。

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统 如何使用WebSocket和JavaScript实现在线语音识别系统 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术 WebSocket与JavaScript:实现实时监控系统的关键技术 Dec 17, 2023 pm 05:30 PM

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何利用JavaScript和WebSocket实现实时在线点餐系统 如何利用JavaScript和WebSocket实现实时在线点餐系统 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

如何使用WebSocket和JavaScript实现在线预约系统 如何使用WebSocket和JavaScript实现在线预约系统 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

JavaScript和WebSocket:打造高效的实时天气预报系统 JavaScript和WebSocket:打造高效的实时天气预报系统 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

简易JavaScript教程:获取HTTP状态码的方法 简易JavaScript教程:获取HTTP状态码的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

javascript中如何使用insertBefore javascript中如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用于在DOM树中插入一个新的节点。这个方法需要两个参数:要插入的新节点和参考节点(即新节点将要被插入的位置的节点)。

JavaScript和WebSocket:打造高效的实时图像处理系统 JavaScript和WebSocket:打造高效的实时图像处理系统 Dec 17, 2023 am 08:41 AM

JavaScript是一种广泛应用于Web开发的编程语言,而WebSocket则是一种用于实时通信的网络协议。结合二者的强大功能,我们可以打造一个高效的实时图像处理系统。本文将介绍如何利用JavaScript和WebSocket来实现这个系统,并提供具体的代码示例。首先,我们需要明确实时图像处理系统的需求和目标。假设我们有一个摄像头设备,可以采集实时的图像数

See all articles