In the article on the first emperor in JavaScript, the author has a point:
Object.prototype is the real first emperor, and any prototype is derived from it; and Function.prototype is second only to Object.prototype, it is the creator of the built-in constructor, and any constructor is derived from it
Therefore, the prototype of Function has a certain importance. Function (constructor) and Function.prototype (prototype) are in a relationship. From the constructor level, it is already more important than Array, String, Number, etc., although it is not comparable to Object, but also second only to its existence
Not only that, but functions can do a lot more. First of all, it is an object, which we explained in everything is an object, so it has properties like objects, and can also be assigned to variables. In addition, functions can be passed themselves as parameters, and also have the characteristics of returning a value.
In short, the object can do everything it can do, it also has its own characteristics, can do more things (for example: can be passed as a parameter, has a return value)
Before explaining the characteristics of a function, let's understand its properties and methods
properties and methods
speak by example
function func() {}
console.dir(func)
We create a normal function func in the form of a function declaration, print it. Although we did not perform any assignment operation on it, it comes with various properties. Obviously, Function does not have static methods. It only has instance properties and instance methods, both of which inherit from Function.prototype.我们看到函数func 上有arguments
、 caller
、 length
、 name
func.__proto__
You can find the same attribute in func.__proto__
---, the secret is Function.__proto__ === Function.prototype
, see the first emperor in JavaScript for details
instance properties
-
Function.prototype.arguments
: corresponds to the parameter array passed to the function -
Function.prototype.constructor
: points to the constructor -
Function.prototype.length
: Number of parameters
instance method
-
Function.prototype.apply(thisArg [, argsArray])
: call a function and set itsthis
value to the provided parameter, the second parameter is passed in as an array object -
Function.prototype.call(thisArg [, arg1, arg2, ...argN])
: call a function and set itsthis
value to the provided parameter, optionally passing new parameters -
Function.prototype.bind(thisArg[, arg1[, arg2[, ...argN]])
: Creates a new function that, when called, will set this to the providedthisArg
. When calling a newly bound function, an optional parameter sequence ([, arg1[, arg2[, ...argN]]]
) is prepended to the parameter sequence -
Function.prototype.toString()
: Returns a string representing the function source code. Overrides theObject.prototype.toString
method
More information can be viewed onMDN
After understanding the instance properties and methods of Function, let's see how to create a function
create function
There are four ways to create functions: function constructors, function declarations, function expressions, and arrow functions
// 函数构造函数:最后一个参数为函数逻辑,之前的都是参数
var add = new Function('x', 'y', 'return x + y');
// 函数声明
function add2(x, y) {
return x + y;
}
// 函数表达式
var add3 = function (x, y) {
return x + y;
};
// 箭头函数
var add4 = (x, y) => x + y
It should be noted here that in normal development, function constructors are basically not used. Function declarations, function expressions, and arrow functions are mostly used in development, so what is the difference between the three?
Compare function declarations and function expressions first
- Function declarations cause function hoisting (and take precedence over variable hoisting)
Contrast arrow functions with ordinary functions again
- Without this, the this in the function body needs to be looked up in the external lexical environment
- no arguments
- Cannot be used as a constructor. That is, arrow functions cannot use the new command, otherwise an error will be thrown
- no super
- The yield command cannot be used, so arrow functions cannot be used as Generator functions
- When returning an object, you must put parentheses around the object
This is the case with creating functions, how do you create functions to call them?
Call functions
In different scenarios, the calling function is different, the following are the ways to call the function
- as a function
- as a method
- as a constructor
- use call/apply/bind
- self-invoking function
// 作为函数
var func1 = function () {
return 'foo';
};
console.log(func1); // foo
// 作为方法,即对象中的函数被称为方法
var obj1 = {
func2: function () {
return 'bar';
},
};
console.log(obj1.func2()); // bar
// 作为构造函数
function Person() {
this.name = 'johnny'
this.age = 28;
this.gender = 'female';
this.getName = function () {
return this.name;
};
}
var cody = new Cody(); // 调用构造函数
console.log(cody);
// 使用 call/apply 调用
var obj2 = {
sayHello: function () {
console.log(this.name, arguments[0], arguments[1]);
},
};
var johan = { name: 'johan' };
var elaine = { name: 'elaine' };
// 在 johan 对象上调用 sayHello
obj2.sayHello.call(johan, 'foo', 'bar'); // johan, foo, bar
obj2.sayHello.apply(elaine, ['foo', 'bar']); // elaine, foo, bar
// 自调用
(function() {
console.log('自调用函数');
})();
Whether it is creating a function or calling a function, what is the use of it, can it prove that the function is a first-class citizen?
Why are functions first class citizens?
Next, let's explain why functions are said to be first-class citizens?
First, functions are objects, which means that functions can be stored in a variable, array, or object. Second, because it is an object, it also has the properties of an object, that is, it has properties. In addition to the object's characteristics, as the function itself, it can be passed as a parameter or returned as a return value. In this way, these factors make a function a "first-class citizen" in JavaScript
// 作为变量保存变量、数组、对象
var funcA = function () {} // 作为变量
var funcB = [function(){}] // 作为数组变量
var funcC = { method: function() {} } // 作为对象方法
// 函数也是对象,意味着可以拥有属性
var funcD = function () {}
funcD.name = 'funcD' // 赋值name
console.log(funcD.name) // funcD
// 作为参数
var funcE = function(func) {
func()
}
funcE(function () {
console.log('函数作为参数传递')
})
// 作为函数返回值
var funcF = function (x, y) {
return x + y // 函数特性,有返回值
}
console.log(funF(1,2)) // 3
PS: The so-called first-class citizen, that is, first-class function, is also called first-class function. The introduction to it on Wikipedia is:
Functions can be used as arguments to other functions, the return value of functions, assigned to variables, or stored in data structures
In the same way, MDN also introduces the same
Among them, functions are passed as parameters and have the characteristics of returning values, making it the basis of functional programming
Because functions not only have the ability of objects, but also have the unique characteristics of parameter passing and return value, which makes it a first-class citizen. Not only that, but the function has other features
Other properties of functions
Function scope: The scope in JavaScript is divided into global scope, function scope and block-level scope. Block-level scope is a feature that emerged after ES6 to solve design defects such as variable coverage and variable pollution in variable promotion. Before that, there were only global scope and function scope, and there was only one global scope to understand. Function scope is an important knowledge point to understand JavaScript - the basis of closures. For knowledge points about scope, you can read this article - scope (updated in subsequent articles)
this: what is this, when writing prototypes and constructors, we used this in constructors, and when new instantiates it, saying that the new keyword will point this in the constructor to the new object and execute the constructor code in , so what does this have to do with it?
It is a bit similar to the scope, but it is not exactly the same. It is bound to the execution context. We will talk about this keyword first (subsequent article updates), and then we will derive the three generals call, apply, and bind (subsequent articles). renew) . Let’s look back at the execution context, but before talking about it, let’s clarify the lexical environment (updated in subsequent articles), and then talk about the execution context and execution stack (updated in subsequent articles)
When we talk about scope, a scope chain is derived. Talking about the this keyword will lead to the execution context. The combination of the two will explain the closure (subsequent article update). Closure is a difficult point in JavaScript. If the prototype is "Girl Killer", then the closure is "Mother Killer"
There are various forms of functions, such as IIFE, which means that the function is executed immediately (updated in subsequent articles), why does it do this, and it is done to avoid variable pollution. Then AMD/CMD, the modularization in ES, is to make the code independent and not affected by other files
In short, functions have many characteristics, because of these characteristics, functions can become "characters" in JavaScript
Summarize
We start with the properties and methods of functions, and introduce the built-in properties and methods of Function, which are convenient for developers to call. Then we introduce how to create a function, introduce four methods, call the function after the function is created, and introduce it in five cases. Finally, we introduce why functions are first-class citizens. Become a first-class citizen, firstly because it is an object and has the "ability" of an object, and secondly, it has some characteristics that make it unique, such as being able to be passed as a parameter and having a return value, both of which are functional programming Base
Do you think functions are that simple? Then you underestimate the function
Function features also function scope, relative to global scope, block-level scope, the actual usefulness of function scope is as high as 90%; there is also this, call/apply/bind in Function's prototype method exists to modify this Yes, it means that modifying the this pointer is a high-frequency operation. The interpretation of this will lead to the execution context, and combined with the scope chain in the scope, the closure behavior can be explained. Closures can also derive lexical environments, execution contexts, and call stacks, as well as application anti-shake, throttling, and currying of closures. garbage collection mechanism, etc.
In short, the status of functions in JavaScript is very high
References
series of articles
- Deep understanding of JavaScript - the beginning
- Deep understanding of JavaScript - what is JavaScript
- Deep understanding of JavaScript - what JavaScript consists of
- Deep understanding of JavaScript - everything is an object
- Deep understanding of JavaScript-Object (object)
- In-depth understanding of what JavaScript-new does
- Deep understanding of JavaScript-Object.create
- Deep understanding of JavaScript - the secret of copying
- Deep understanding of JavaScript - prototype
- Deep understanding of JavaScript - Inheritance
- Deep understanding of JavaScript - the first emperor in JavaScript
- In-depth understanding of JavaScript-instanceof - looking for ancestry
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。