In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces what the this in JS points to, the content is very detailed, interested friends can refer to, hope to be helpful to you.
1. The mysteries of this
In many cases, the this in JS is easy to be confused by our beginners. This is powerful, but it takes a lot of effort to understand it.
For Java, PHP, or other standard languages, this represents an instance of the current object in a class method. In most cases, this cannot be used outside the method, so it is less confusing.
The situation is different in J: this represents the current execution context of the function, and there are mainly the following ways to call a function in JS:
Function call: alert ('Hello Worldwide') Method call: console.log ('Hello Worldwide') Constructor: new RegExp ('\\ d') implicit call: alert.call (undefined, 'Hello Worldwaters')
Each call type defines the context in its own way, so it's easy to get confused.
In addition, strict mode also affects the execution context.
The key to understanding this is to clearly understand function calls and how they affect the context.
It mainly explains how the function is called and how it affects this, as well as the common pitfalls of the execution context.
Before we begin, let's know a few terms:
The calling function is executing the code that creates the body of the function, or just calling the function. For example, the parseInt function call is parseInt ('15').
Function call: executes the code that makes up the body of the function: for example, the parseInt function call is parseInt ('15'). The context of the call: refers to the value of this in the body of the function. For example, the calling context of map.set ('key',' value') is map. The scope of a function: a collection of variables, objects, and functions that can be accessed in the body of the function.
2. Function call
When an expression is function after function (, some parameters separated by commas and one), the function call is executed, such as parseInt ('18').
The function call expression cannot be a property call, such as obj.myFunc (), which creates a method call. Another example is [1p5] .join (',') is not a function call, but a method call. This difference needs to be kept in mind.
A simple example of a function call:
Function hello (name) {return 'Hello' + name +'!;} / / function call const message = hello ('World'); console.log (message); / / >' Hello Worldwide'
Hello ('World') is a function call: an hello expression is equivalent to a function, followed by a pair of parentheses and the' World' parameter.
A more advanced example is IIFE (an immediately called function expression)
Const message = (function (name) {return 'Hello' + name +'!;}) ('World'); console.log (message) / / = >' Hello Worldwide'
IIFE is also a function call: the first pair of parentheses (function (name) {...}) is an expression that evaluates to a function object, followed by a pair of parentheses whose argument is "World".
2.1.The this in the function call
This is a global object in a function call
The object of the office is determined by the execution environment. In the browser, this is the window object.
In a function call, the execution context is a global object.
Let's take a look at the context in the following function:
Function sum (a, b) {console.log (this = window); / / > true this.myNumber = 20; / / add the 'myNumber' attribute to the global object return a + b;} / / sum () is invoked as a function// sum () `this` is a global object (window) sum (15,16); / / = > 31 window.myNumber; / / = > 20
When you call sum (15jue 16), JS automatically sets this as a global object, which is window in the browser.
When this is used outside the scope of any function (topmost scope: global execution context), this represents the window object
Console.log (this = window); / / = > truethis.myString = 'Hello Worldworkers' console.log (window.myString); / / > 'Hello Worldships' Console.log (this = window); / / = > true
2.2.What is the function call this in strict mode?
This is undefined in strict mode function calls.
Strict mode was introduced in ECMAScript 5.1, which provides better security and stronger error checking.
To enable strict mode, write the function header to use strict.
When enabled, strict mode affects the execution context, and the value of this is undefined in regular function calls. In contrast to case 2.1 above, the execution context is no longer a global object.
Example of strict mode function call:
Function multiply (a, b) {'use strict'; / / enable strict mode console.log (this = undefined); / / = > true return a * b;} multiply (2,5); / / = > 10
When multiply (2p5) is called as a function, this is undefined.
Strict mode is valid not only in the current scope, but also in the internal scope (for all functions declared internally):
Function execute () {'use strict'; / / turn on strict mode function concat (str1, str2) {/ / strict mode is still valid console.log (this = undefined); / / > true return str1 + str2;} / / concat () calls / / this in concat () is undefined concat (' Hello', 'wordmodes') as a function in strict mode / / = > "Hello World!"} execute ()
'The use strict' is inserted at the top of the execution body, enabling strict mode within its scope. Because the function concat is declared in the scope of the execution, it inherits the strict pattern.
A single JS file may contain strict and non-strict schemas. Therefore, for the same call type, you can have different contextual behaviors in a single script:
Function nonStrictSum (a, b) {/ / non-strict mode console.log (this = window); / / > true return a + b;} function strictSum (a, b) {'use strict'; / / enable strict mode console.log (this = undefined); / / = > true return a + b;} nonStrictSum (5,6); / / > 11strictSum (8,12); / / = > 20
2.3.Trap: when this is in the internal function
A common trap in function calls is to assume that the situation of this in internal functions is the same as that in external functions.
Correctly, the context of an internal function depends only on its call type, not on the context of an external function.
To set this to the desired value, you can modify the context of the internal function through .call () or .apply () or create a binding function using .bind ().
The following example is to calculate the sum of two numbers:
Const numbers = {numberA: 5, numberB: 10, sum: function () {console.log (this = numbers); / / = > true function calculate () {console.log (this = numbers); / / = > false return this.numberA + this.numberB;} return calculate ();}}; numbers.sum (); / / = > NaN
Sum () is a method call on an object, so the context in sum is the numbers object. The calculate function is defined in sum, and you may want to this the number object in calculate ().
Calculate () is a function call (not a method call) that uses this as a global object window (not in strict mode). Even if the external function sum uses the context as a number object, it has no effect in calculate.
The result of the call to sum () is NaN, which is not the expected result of 5 + 10 = 15, all because calculate is not called correctly.
To solve this problem, the context in the calculate function should be the same as in sum so that the numberA and numberB properties can be accessed.
One solution is to manually change the calculate context to the desired context by calling calculator.call (this).
Const numbers = {numberA: 5, numberB: 10, sum: function () {console.log (this = numbers); / / = > true function calculate () {console.log (this = numbers); / / > true return this.numberA + this.numberB;} / / use the .call () method to modify the context return calculate.call (this);}}; numbers.sum (); / / = > 15
Call (this) executes the calculate function as usual, but call modifies the context to the value specified as the first parameter.
This.numberA + this.numberB is now the equivalent of numbers.numberA + numbers.numberB. This function returns the expected result 5 + 10 = 15.
The other is to use the arrow function.
Const numbers = {numberA: 5, numberB: 10, sum: function () {console.log (this = numbers); / / = > true const calculate = () = > {console.log (this = numbers); / / = > true return this.numberA + this.numberB;} return calculate ();}; numbers.sum (); / / = > 15
3. Method call
Method is a function stored in object properties. For example
Const myObject = {/ / helloFunction is a method helloFunction: function () {return 'Hello Worldwaters;}}; const message = myObject.helloFunction ()
HelloFunction is a method of myObject, which can be called like this: myObject.helloFunction.
When an expression is executed in the form of property access, it executes a method call, which is equivalent to a function followed by (, a set of parameters separated by commas and).
Using the previous example, myObject.helloFunction () is a method call to helloFunction on the object myObject. [1, 2] .join (',') or /\ s/.test ('beautiful world') is also considered a method call.
It is important to distinguish between function calls and method calls because they are different types. The main difference is that the method call requires a property accessor form to call the function (obj.myFunc () or obj ['myFunc'] ()), while the function call does not need (myFunc ()).
['Hello',' World'] .join (','); / method call ({ten: function () {return 10;}}). Ten (); / / method call const obj = {}; obj.myFunction = function () {return new Date (). Join (); obj.myFunction (); / / method call const otherFunction = obj.myFunction;otherFunction (); / / function call parseFloat ('16.60') / / function call isNaN (0); / / function call
Understanding the difference between function calls and method calls helps to correctly identify the context.
3.1.What is the this in the method call
In a method call, this is the object that owns the method
When a method on an object is called, the this becomes the object itself.
Create an object that has a method of incrementing numbers
Const calc = {num: 0, increment: function () {console.log (this = calc); / / = > true this.num + = 1; return this.num;}}; / / method invocation. This is calccalc.increment (); / / = > 1calc.increment (); / / = > 2
Call calc.increment () to make the context of the increment function a calc object. So it is valid to use this.num to add the num attribute.
Let's look at another example. The JS object inherits a method from the prototype, and when the inherited method is called on the object, the context of the call is still the object itself
Const myDog = Object.create ({sayName: function () {console.log (this = myDog); / / = > true return this.name;}}); myDog.name = 'Milo';// method call this points to myDogmyDog.sayName (); / / = >' Milo'
Object.create () creates a new object, myDog, and sets its prototype based on the first parameter. The myDog object inherits the sayName method.
Execute myDog. When sayname (), myDog is the context of the call.
In EC6 class syntax, the method call context is also the instance itself
Class Planet {constructor (name) {this.name = name;} getName () {console.log (this = earth); / / = > true return this.name;}} var earth = new Planet ('Earth'); / / method invocation. The context is earthearth.getName (); / / = > 'Earth'
3.2. Trap: separate a method from its object
Method can extract a single variable const alone = myObj.myMethod from the object. When a method is called separately, separated from the original object alone (), you might think that the current this is the object myObject that defines the method.
If the method is called without an object, then the function call occurs, and the this points to the global object window undefined in strict mode.
The following example defines the Animal constructor and creates an instance of it: myCat. Then setTimout () prints the myCat object information after 1 second
Function Animal (type, legs) {this.type = type; this.legs = legs; this.logInfo = function () {console.log (this = myCat); / / > false console.log ('The' + this.type + 'has' + this.legs + 'legs');} const myCat = new Animal (' Cat', 4); / / The undefined has undefined legs setTimeout (myCat.logInfo, 1000)
You might think that when setTimout calls myCat.loginfo (), it should print information about the myCat object.
Unfortunately, the method is separated from the object when passed as a parameter, and setTimout (myCat.logInfo) is equivalent in the following cases:
SetTimout (myCat.logInfo); / / equivalent to const extractedLogInfo = myCat.logInfo;setTimout (extractedLogInfo)
When the detached logInfo is called as a function, this is the global window, so the object information is not printed correctly.
Functions can be bound to objects using the. bind () method, which solves the problem of this pointing.
Function Animal (type, legs) {this.type = type; this.legs = legs; this.logInfo = function () {console.log (this = myCat); / / > true console.log ('The' + this.type + 'has' + this.legs + 'legs');} const myCat = new Animal (' Cat', 4); / / logs "The Cat has 4 legs" setTimeout (myCat.logInfo.bind (myCat), 1000)
MyCat.logInfo.bind (myCat) returns a new function that executes exactly the same way as logInfo, but at this time the this points to myCat, even in a function call.
Another solution is to define the logInfo () method as an arrow function:
Function Animal (type, legs) {this.type = type; this.legs = legs; this.logInfo = () = > {console.log (this = myCat); / / > true console.log ('The' + this.type + 'has' + this.legs + 'legs');} const myCat = new Animal (' Cat', 4); / / logs "The Cat has 4 legs" setTimeout (myCat.logInfo, 1000)
4. Constructor call
When the new keyword is called immediately after the function object, (, a set of comma-separated arguments and), it executes a constructor call such as new RegExp ('\ d').
A Country function is declared and called as a constructor:
Function Country (name, traveled) {this.name = name? Name: 'United Kingdom'; this.traveled = Boolean (traveled);} Country.prototype.travel = function () {this.traveled = true;}; / / Constructor call const france = new Country (' France', false); / / Constructor call const unitedKingdom = new Country;france.travel (); / / Travel to France
New Country ('France', false) is the constructor call to the Country function. The result of its execution is a new object with a name attribute of 'France'. If this constructor calls without arguments, the parentheses can be omitted: new Country.
Starting with ES6, JS allows you to define constructors using the class keyword
Class City {constructor (name, traveled) {this.name = name; this.traveled = false;} travel () {this.traveled = true;}} / / Constructor invocationconst paris = new City ('Paris', false); paris.travel ()
New City ('Paris') is a constructor call. The initialization of this object is handled by a special method constructor in this class. Where this points to the newly created object.
The constructor creates a new empty object that inherits properties from the prototype of the constructor. The function of the constructor is to initialize the object. As you may already know, in this type of call, the context points to the newly created instance.
When the attribute access myObject.myFunction is preceded by a new keyword, the JS executes the constructor call instead of the original method call.
For example, new myObject.myFunction (): it is equivalent to using property access to extract the method extractedFunction = myObject.myFunction, and then using it as a constructor to create a new object: new extractedFunction ().
4.1.The this in the constructor
This points to the newly created object in the constructor call
The context of the constructor call is the newly created object. It uses the parameters of the constructor to initialize new objects, set the initial values of properties, add event handlers, and so on.
Take a look at the context in the following example
Function Foo () {console.log (this instanceof Foo); / / = > true this.property = 'Default Value';} / / Constructor invocationconst fooInstance = new Foo (); fooInstance.property; / / = >' Default Value'
New Foo () is making a constructor call, where the context is fooInstance. Initialize the object within Foo: this.property is assigned to the default value.
The same thing happens when using the class syntax (starting with ES6), except that initialization occurs in the constructor method:
Class Bar {constructor () {console.log (this instanceof Bar); / / = > true this.property = 'Default Value';}} / / Constructor invocationconst barInstance = new Bar (); barInstance.property; / / = >' Default Value'
4.2.Trap: forget to use new
Some JS functions create new objects not only when called as constructors, but also when called as functions, such as RegExp:
Var reg1 = new RegExp ('\\ wicked'); var reg2 = RegExp ('\\ wicked'); reg1 instanceof RegExp; / / = > truereg2 instanceof RegExp; / / = > truereg1.source = reg2.source; / / = > true
JS creates an equivalent regular expression object when new RegExp ('\\ wrought') and RegExp ('\\ wrought') are executed.
There is a potential problem with using function calls to create objects (excluding factory patterns), because some constructors may ignore the logic to initialize objects in the absence of the new keyword.
The following example illustrates this problem:
Function Vehicle (type, wheelsCount) {this.type = type; this.wheelsCount = wheelsCount; return this;} / / forgot to use new const car = Vehicle ('Car', 4); car.type; / / = >' Car'car.wheelsCount / / = > 4car = window / / = > true
Vehicle is a function that sets the type and wheelsCount properties on the context object.
When Vehicle ('Car', 4) is executed, an object Car is returned with the correct properties: Car.type is Car and Car.wheelsCount is 4, which you might think is suitable for creating and initializing new objects.
However, in a function call, this is a window object, so Vehicle ('Car',4) sets properties on the window object. Obviously this is an error, and it does not create a new object.
When you want to call the constructor, make sure you use the new operator:
Function Vehicle (type, wheelsCount) {if (! (this instanceof Vehicle)) {throw Error ('Error: Incorrect invocation');} this.type = type; this.wheelsCount = wheelsCount; return this;} / / Constructor invocationconst car = new Vehicle (' Car', 4); car.type / / = > 'Car'car.wheelsCount / / = > 4car instanceof Vehicle / / = > true// Function invocation. Throws an error.const brokenCar = Vehicle (' Broken Car', 3)
New Vehicle ('Car',4) works fine: create and initialize a new object because the new keyword is used in the constructor call.
A validation this instanceof Vehicle is added to the constructor to ensure that the context of execution is the correct object type. If this is not Vehicle, an error will be reported. Thus, if we execute Vehicle ('Broken Car', 3) (without new), we get an exception: Error: Incorrect invocation.
5. Implicit call
When a function is called using the myFun.call () or myFun.apply () methods, an implicit call is performed.
The function in JS is the first kind of object, which means that the function is the object, and the type of the object is Function. From the list of methods in the function object,. Call () and. Apply () are used to call functions with configurable context.
Method .call (thisArg [, arg1 [, arg2 [,...]) Take the first parameter accepted, thisArg, as the context of the call, arg1, arg2,... These are passed as parameters to the called function. The method .apply (thisArg, [args]) takes the first parameter thisArg as the context of the call and accepts another array-like object [arg1, arg2,...] Passed in as an argument to the called function.
Here is an example of an implicit call
Function increment (number) {return + + number;} increment.call (undefined, 10); / / = > 11increment.apply (undefined, [10]); / / = > 11
Both increment.call () and increment.apply () call this self-incrementing function with the argument 10.
The difference between the two is that .call () accepts a set of parameters, such as myFunction.call (thisValue, 'value1',' value2'). The set of parameters accepted by .apply () must be an array-like object, such as myFunction.apply (thisValue, ['value1',' value2']).
5.1. this in implicit call
In an implicit call to .call () or .apply (), this is the first parameter
Obviously, in an implicit call, this is passed to .call () or .apply () as the first parameter.
Var rabbit = {name: 'White Rabbit'}; function concatName (string) {console.log (this = rabbit); / / > true return string + this.name;} concatName.call (rabbit,' Hello'); / / = > 'Hello White Rabbit'concatName.apply (rabbit, [' Bye']); / / > 'Bye White Rabbit'
Implicit calls are useful when functions should be executed in a specific context. For example, in order to solve the problem of the context of a method call, this is always window or undefined in strict mode. Implicit calls can be used to simulate calling a method on an object.
Function Runner (name) {console.log (this instanceof Rabbit); / / > true this.name = name;} function Rabbit (name, countLegs) {console.log (this instanceof Rabbit); / / = > true Runner.call (this, name); this.countLegs = countLegs;} const myRabbit = new Rabbit ('White Rabbit', 4); myRabbit; / / {name:' White Rabbit', countLegs: 4}
Runner.call (this, name) in Rabbit implicitly calls the function of the parent class to initialize the object.
6. Bind function
A binding function is a function that connects to an object. It is usually created from the original function using the .bind () method. The original function and the bound function share the same code and scope, but the execution context is different.
Method myFunc.bind (thisArg [, arg1 [, arg2 [,...]) Accept the first parameter, thisArg, as the context in which the binding function executes, and it accepts an optional set of parameters arg1, arg2,... As an argument to the called function. It returns a new function bound to thisArg.
Function multiply (number) {'use strict'; return this * number;} const double = multiply.bind (2); double (3); / / = > 6double (10); / / = > 20
Bind (2) returns a new function object double,double bound with the number 2. Multiply and double have the same code and scope.
In contrast to the .apply () and .call () methods, it does not call the function immediately; the .bind () method only returns a new function, which is called later, but the this has been set up in advance.
6.1. this in the binding function
This is the first argument to .bind () when the bind function is called.
The purpose of .bind () is to create a new function that is called with the context as the first argument passed to .bind (). It is a powerful technique that allows us to create a function that defines the value of this.
Let's see how to set this in the binding function.
Const numbers = {array: [3,5,10], getNumbers: function () {return this.array;}}; const boundGetNumbers = numbers.getNumbers.bind (numbers); boundGetNumbers (); / / = > [3,5,10] / / Extract method from objectconst simpleGetNumbers = numbers.getNumbers;simpleGetNumbers (); / / = > undefined (error reported in strict mode)
Numbers.getNumbers.bind (numbers) returns the bind numbers object boundGetNumbers function. The this when boundGetNumbers () is called is a number object and can return the correct array object.
The function numbers.getNumbers can be extracted into the variable simpleGetNumbers without binding. In subsequent function calls, the this of simpleGetNumbers () is window (undefined in strict mode), not a number object. In this case, simpleGetNumbers () does not return the array correctly.
6.2. Tight context binding
.bind () creates a permanent context link and always maintains it. A binding function cannot change its context through .call () or .apply (), even if it is bound again.
Only the constructor call to the bound function can change the bound context, but it is not recommended (the constructor call must use a regular unbound function).
The following example creates a binding function and then tries to change its predefined context
Function getThis () {'use strict'; return this;} const one = getThis.bind (1); / / bind function call one (); / / = > 1 bind / use bind function one.call (2) with .apply () and .call (); / / = > 1one.apply (2); / / = > 1pm / re-bind one.bind (2) (); / / = > 1amp / call binding function new one () as constructor / / = > Object
Only new one () changes the context of the bound function, and this is always equal to 1 in other calls.
7. Arrow function
The arrow function is used to declare the function in a shorter form and to bind the context lexically. It can be used like this.
Const hello = (name) = > {return 'Hello' + name;}; hello ('World'); / / = >' Hello World'// Keep only even numbers [1,2,5,6] .filter (item = > item% 2 = 0); / / = > [2,6]
The arrow function syntax is simple and there is no verbose function keyword. The return keyword can even be omitted when the arrow function has only one statement.
The arrow function is anonymous, which means that the name property is an empty string''. In this way, it has no lexical function name (function name is very useful for recursive, separate event handlers)
At the same time, in contrast to regular functions, it does not provide arguments objects. However, this is fixed in ES6 through rest parameters:
Const sumArguments = (... args) = > {console.log (typeof arguments); / / = > 'undefined' return args.reduce ((result, item) = > result + item);}; sumArguments.name / / = >' sumArguments (5,5,6); / / = > 16
7.1. this in Arrow function
This defines the closed context of the arrow function
Instead of creating its own execution context, the arrow function gets the this from the external function that defines it. In other words, the arrow function binds this lexically.
The following example illustrates this context transparency feature:
Class Point {constructor (x, y) {this.x = x; this.y = y;} log () {console.log (this = myPoint); / / = > true setTimeout () = > {console.log (this = myPoint); / / = > true console.log (this.x +':'+ this.y); / / = > '95155'}, 1000);} const myPoint = new Point (95,165) MyPoint.log ()
SetTimeout calls the arrow function using the same context (myPoint object) as the log () method. As you can see, the arrow function inherits the context from the function that defines it.
If you try a regular function in this example, it creates its own context (window or undefined in strict mode). Therefore, for the same code to use function expressions correctly, you need to manually bind the context: setTimeout (function () {... } .bind (this)). This is lengthy, and using the arrow function is a simpler and shorter solution.
If the arrow function is defined in the topmost scope (outside of any function), the context is always the global object (window in the browser):
Onst getContext = () = > {console.log (this = window); / / = > true return this;}; console.log (getContext () = window); / / = > true
The arrow function is bound to the lexical context once and for all. Even if the context is changed, the this cannot be changed:
Const numbers = [1,2]; (function () {const get = () = > {console.log (this = numbers); / / = > true return this;}; console.log (this = numbers); / / = > true get (); / / = > [1,2] / / Use arrow function with .apply () and .call () get.call ([0]); / / = > [1,2] get.apply ([0]) / / = > [1,2] / / Bind get.bind ([0]) (); / / = > [1,2]}) .call (numbers)
No matter how you call the arrow function get, it always preserves the lexical context numbers. Implicit calls with other contexts (via get.call ([0]) or get.apply ([0])) or rebinding (via .bind ()) will not work.
The arrow function cannot be used as a constructor. Calling it as a constructor (new get ()) throws an error: TypeError: get is not a constructor.
7.2. Trap: define the method with the arrow function
You may want to use the arrow function to declare a method on an object. The definition of the arrow function is much shorter than the function expression: (param) = > {...} instead of function (param) {.}.
To take a look at the example, the format () method is defined on the Period class with the arrow function:
Function Period (hours, minutes) {this.hours = hours; this.minutes = minutes;} Period.prototype.format = () = > {console.log (this = window); / / = > true return this.hours + 'hours and' + this.minutes + 'minutes';}; const walkPeriod = new Period (2,30); walkPeriod.format (); / / = >' undefined hours and undefined minutes'
Because format is an arrow function and is defined in the global context (the topmost scope), this points to the window object.
Even if format is called on an object such as walkPeriod.format () as a method, window is still the context of this call. The reason for this is that the arrow function has a static context and does not change with the way it is called.
The method returns' undefined hours and undefined minutes', which is not the result we want.
Function expressions solve this problem because a regular function does change its context based on the actual call:
Function Period (hours, minutes) {this.hours = hours; this.minutes = minutes;} Period.prototype.format = function () {console.log (this = walkPeriod); / / = > true return this.hours + 'hours and' + this.minutes + 'minutes';}; const walkPeriod = new Period (2,30); walkPeriod.format (); / / >' 2 hours and 30 minutes'
WalkPeriod.format () is a method call on an object whose context is the walkPeriod object. This.hours equals 2 hours and is equal to 30, so this method returns the correct result:'2 method 30 minutes'.
Since function calls have the greatest impact on this, don't ask yourself from now on:
Where did this come from?
But to see.
How is the function called?
For the arrow function, you need to think about
What is this where this arrow function is defined?
These are the right ideas when dealing with this, and they can save you from headaches.
So much for sharing what this points to in JS. I hope the above content can be helpful to you and learn more knowledge. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.