Home  >  Article  >  Web Front-end  >  Getting Started with Nodejs Study Notes_node.js

Getting Started with Nodejs Study Notes_node.js

WBOY
WBOYOriginal
2016-05-16 16:03:361037browse

Share the first article, about NodeJS - common knowledge of Javascript and how to transition from Javascript developer to NodeJS developer (the specific framework will not be introduced). Before reading this article, I hope you have some preliminary understanding of javascript.

Javascript is an interpreted language based on prototype models. Interpretation will be discussed later in NodeJS. The prototype chain is one of the object-oriented implementation methods of Javascript before ES6. A new implementation method is added to the class supported in ES6. Everything in Javascript is an object, including "classes". Those who have been exposed to ruby/python metaprogramming may find this very familiar, and Javascript can easily implement a method of dynamically generating classes.

1. Simple "class" implemented based on prototype chain

var Person = function(name){
 this.name = name;
};

Person.staticSay = function(name){
 console.log('Hello ' + name);
};

Person.prototype.sayHi = function(){
 Person.staticSay(this.name);
}

Mention some common specifications, for example, all methods in Javascript are named in camel case, single quotes are preferred, two spaces are used, etc. For more specifications, please refer to https://github.com/airbnb/ javascript.

staticSay in the code is a static method, that is, it can only be called through Person.staticSay. When the above Person generates an instance, for example, var vincent = new Person('vincent');, vincent will automatically inherit all methods of Person.prototype (this in the code refers to the current context, which is the above vincent).

At the same time, you can also dynamically add methods to the object vincent, such as the following code:

var vincent = new Person('vincent')
vincent.tellName = function(){
 console.log('Hi, i\'m am' + this.name)
};

Then when you need to simulate inheritance, you need to work on prototype. For example, Worker.prototype = new Person() is used below to achieve this. All methods and properties of the instance object returned by new Person() are assigned to the prototype, simulating inheritance in disguise. This method ultimately searches for the contents of the prototype layer by layer (because the methods of each instance are in the prototype, going up to Object). Of course, you can also simulate inheritance by assigning values ​​to the prototype through traversal.

2. Context switching

The most intuitive expression of context is this in the code block, which is usually used in object-oriented programming to refer to the corresponding instance generated by the current "class", which is consistent with self in other languages.

Continuing to use the example above, a Person.prototype.sayHi method has been implemented above. Now I have a new object, the code is as follows:

var Cat = function(name){
 this.name = name;
}

var c = new Cat('tomcat');

What if one day I suddenly want the cat to introduce himself like a human being? He doesn’t have the sayHi method. But you can get the human sayHi method through console.log(Person.prototype.sayHi). How can cats also use it?

Javascript has two methods, call and apply. The difference between them is that the parameters are different (Google it yourself), and their function is to switch context. To put it simply, you can change this in the Person.prototype.sayHi function into other objects. Usage: Person.prototype.sayHi.call(c).

Is this practical? For example, the following scenario:

var doSomething = function(){
 var persons = arguments;
};

In the above function, all parameters are obtained through the keyword arguments to support an indefinite number of parameters. Now we want to use some methods that originally belong to the Array type on persons. How to achieve this? Here you can use context switching:

var doSomething = function(){
 var persons = arguments;
 // 使用 Array 的 slice 方法,将 arguments 对象转变为 Array 实例
 var persons_arr = Array.prototype.slice.call(arguments);
};

3. Closure

Let’s start with some common code

for (var i = 0; i < 3; i ++){
 setTimeout(function(){
  console.log(i);
 }, i)
}

What will be the output of this? Output 0 1 2 in sequence? The actual situation is that when setTimeout executes the callback for the first time, the for loop has ended, which means that i is already 3 at this time, resulting in the final output result being 3 3 3.

When you need to protect a variable so that it is not affected by surrounding code, you may need to consider a closure - a block of code with a closed scope.

for (var i = 0; i < 3; i ++){
 +function(i){
  setTimeout(function(){
   console.log(i);
  }, i)
 }(i)
}

Hey, what is it for? If there is any other way to achieve it, please Google it yourself. The scope of i within the closure is a closed scope, so in the end, i within the closure has not been changed by external execution, so 0 1 2 can be successfully output.

Brief introduction to some features of javascript, keyword prototype chain, call and apply, and arguments keyword. For more suggestions, you can read books such as the authoritative guide, or quickly understand the basic types and the characteristics of each type. method. There are some more magical codes, such as getting the string of the current code, and then processing it to get the content you want, using getters and setters to do some special operations when the user gets or assigns values ​​to object properties, etc.

4. The difference between NodeJS and Javascript development

This section mainly introduces the basic knowledge of require loading. First, introduce some code:

// a.js
module.exports = {
 name: "a",
 doSomething: function(){
  return "something";
 }
}

// b.js
var a = require('./a')
global.a_name = a.name;

// c.js
require('./b');
console.log(a_name) // 执行后打印 a 

What happens when we execute node c.js?

require is the nodes keyword. Although NodeJS is famous for being asynchronous, its require is blocking. Otherwise, there will be a situation where the following code has already started to be executed before other modules have been loaded.

The require.resolve() method is used to find out the actual path of the file you reference. After finding out, Nodejs will look in require.cache to see if there is a cache. If not, it will read the file and parse it, so usually In this case, the executed code in a js file will only be executed the first time it is required. (tip. require.cache can be manually deleted if necessary, and then it can be executed multiple times to some extent)

When b.js starts executing, it needs to load a.js first. module.exports tells Nodejs what this file is exposed to the outside world. For example, a.js exposes an object, including the name attribute and the doSomething method. Then the a variable in b.js is actually this object.

After executing to obtain a.js, continue to return to b.js. global.a_name is equivalent to declaring a global variable. This has a similar effect to window.a_name = a.name in the front end.

The final process is completed, and c.js executes the output value.

5. The underlying principle of asynchronous

NodeJS can easily give people an illusion of use, that is, even after writing it for a long time, you may not know how the underlying asynchronous is implemented. (The following understanding mainly comes from the understanding of asyncio in python3.4. If there are any errors, please point them out).

The underlying libev of NodeJS uses IOCP under Window and AIO-based libeio under *nix to achieve asynchronous implementation. Through system-level technology, one goal is finally achieved, that is, the application initiates an asynchronous request. Finally, after the system completes execution, the system notifies the application that the processing is completed. During this process, the application can suspend/push previous processing into the thread pool to wait for execution, and the application can perform other tasks during this period.

The entire operation operates through the system-level event loop. For example, Python provides methods similar to run_until and run_forever to ensure that the program will not end before asynchronous execution. Think of the entire asynchronous operation as a workshop that is always running. The machines in the workshop are responsible for checking the packages and stamping them. The workers get a package, put it in with the corresponding label, and return it to the workshop after it is processed. The worker performs the next step of processing based on the label he previously attached to the package and the label affixed by the workshop. The worker does not need to wait for the package to be inspected before moving on to the next one. He only needs to accept simple processing and then put it into the workshop for inspection. Then he waits for the workshop to return a package to him at a certain time, and then proceeds to the next step.

At present, we mainly only introduce some language-level knowledge, but only these are still some distance away from developing a complete web, which will be introduced later. Including Redis, Nginx, test driver, etc.

The above is the entire content of this article, I hope you all like it.

Statement:
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