Home > Web Front-end > JS Tutorial > body text

A brief discussion on the usage of call(), apply(), and bind() in javascript_javascript skills

WBOY
Release: 2016-05-16 15:14:36
Original
950 people have browsed it

Function in JavaScript is not only a language feature similar to methods in Java, it can also exist as an object. This article will explore some special uses of functions in JavaScript, including the three prototype methods of call, apply, and bind.
1. Function basics
A function in JavaScript is a language feature similar to a method in Java, but it can be defined independently of a class.

Functional programming: Because JavaScript supports anonymous functions, functions can be used as objects. Therefore, JavaScript not only supports procedural programming (object-oriented is also a type of procedural programming), but also supports functional programming.
Context

Each call to a function will have a special value - the context of this call - this is the value of the this keyword. If a function is mounted on an object as a property of the object, it is called a method of the object. When a function is called through this object, the object is the context of the call, which is the value of this of the function.

It should be noted that this is a keyword, not a variable or an attribute name. JavaScript syntax does not allow assigning a value to this.

A function is a kind of object

The biggest difference between functions in JavaScript and methods in Java or functions in C language is that functions in JavaScript are also objects. But this does not mean that all objects are functions. A function is a special object that contains executable code and can be called by other code.

Unlike variables, the keyword this has no scope restrictions, and nested functions do not inherit this from the function that calls it. - If a nested function is called as a method, its this value points to the object that called it. - If the nested function is called as a function, the value of this is either the global object (in non-strict mode) or undefined (in strict mode).

Many people mistakenly believe that when calling a nested function, this will point to the context of the outer function. If you want to access the this value of this external function, you need to save the value of this in a variable. This variable and the internal function are both in the same scope. For example:

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
  }
 }
}
Copy after login

Closure

JavaScript functions can be defined nested within other functions so that they can access any variables in the scope in which they are defined. This means that JavaScript functions form a closure, which brings very powerful programming capabilities to JavaScript.

as a function of value
In JavaScript, a function is not only a syntax, but also a value. That is to say, a function can be assigned to a variable, stored in an object's properties or an element of an array, passed into another function as a parameter, etc.

bind, call, apply
Each function contains a prototype attribute, which is a reference to an object. This object is called a "prototype object". Each function contains a different prototype object. When using a function as a constructor, the newly created object inherits properties from the prototype object.

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

call() and apply() can be regarded as methods of an object, and functions are called indirectly by calling methods. Their first parameter is the parent object of the function to be called, which is the calling context, and a reference to it is obtained through this in the function body. The apply() method has the same effect as the call() method, except that the method of function transfer is different. Its actual parameters are all placed in an array.

For example, to call function f() as a method of object o and pass in two parameters, you can use code like this:

var o = {};

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

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

Give another example, use the call method to call an anonymous function:

In the for loop body in the following example, we create an anonymous function, and then execute the anonymous function by calling the call method of the function, using each array element as the specified this value. The main purpose of this anonymous function is to add a print method to each array element object. This print method can print out the correct index number of each element in the array. Of course, it is not necessary to pass the array elements into the anonymous function as this value (normal parameters are enough). The purpose is to demonstrate the usage of 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);
}

Copy after login

Function.prototype.bind()

bind() is a new method in ES5. As can be seen from the name, the main function of this method is to bind a function to an object. When calling the bind() method on function f() and then passing in an object o as a parameter, this method will return a new function: (in the form of a function call) calling the new function will replace the original function f() Called as a method of o. For example:

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

var o = {
 x: 1
};

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

Copy after login

In fact, we can easily implement the bind() method:

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

Copy after login

二、函数式编程
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);

Copy after login

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,每个函数都是奇数

Copy after login

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

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

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!