Home  >  Article  >  Web Front-end  >  How to write high-quality JS code (continued)_javascript skills

How to write high-quality JS code (continued)_javascript skills

WBOY
WBOYOriginal
2016-05-16 16:13:201204browse

Continuing the previous article "How to Write High-Quality JS Code", this time I will sort out the knowledge points of javascript functions.

2. Use function

Functions provide programmers with main abstract functions and implementation mechanisms. Functions can independently implement several different features in other languages, such as procedures, methods, constructors, and even classes or modules.

2.1 Understand the differences between function calls, method calls and constructor calls

For object-oriented programming, functions, methods and class constructors are three different concepts.

Usage mode:

1, function call

Copy code The code is as follows:

function hello(username){
Return "hello" username;
}

2, method call

Copy code The code is as follows:

var obj = {
Hello : function(){
          return "hello, " this.username;
},
Username: "floraLam"
};
ohj.hello();//"hello , floraLam"

This variable is bound to the object because the hello method is defined in the obj object. We can also assign the same function reference to another object and get the same answer.

Copy code The code is as follows:

var obj2 = {
Hello: obj.hello(),
Username: "floraLam"
};

3, the constructor uses

Copy code The code is as follows:

function User(name,passwordHash){
This.name = name;
This.passwordHash = passwordHash;
}

Using the new operator to call User is considered a constructor.

Copy code The code is as follows:

var u = new User("floraLam","123");

Different from function calls and method calls, constructor calls use a brand new object as the value of this variable and implicitly return this new object as the call result. The main responsibility of the constructor is to initialize this new object.

2.2 Proficient in high-order functions

Higher-order functions are nothing more than those functions that take a function as a parameter or return a value. Taking a function as a parameter (often called a callback function because the higher-order function "then calls" it) is a particularly powerful and expressive way to Idioms are also widely used in js programs.

Consider the standard sort method for arrays. In order to work for all arrays, the sort method requires the caller to decide how to compare any two elements in the array.

Copy code The code is as follows:

function compareNumber(x,y){
If(x < y){
         return -1;
}
If(x > y){
Return 1;
}
Return 0;
}
[3,1,4,1,5,9].sort(compareNumbers);//[1,1,3,4,5,9]

Copy code The code is as follows:

[3,1,4,1,5,9].sort(function(x,y){
If(x < y){
         return -1;
}
If(x > y){
Return 1;
}
Return 0;
});//[1,1,3,4,5,9]

The above example is further simplified using an anonymous function.

Learning to use higher-order functions often simplifies code and eliminates tedious boilerplate code. We can use a loop to implement a simple conversion of a string array:

Copy code The code is as follows:

var names = ["Fred","Wilma","Pebbles"];
var upper = [];
for(var i = 0,n = names.length ;i< n;i ){
upper[i] = names[i].toUpperCase();
}
upper;//["FRED","WILMA","PEBBLES"];

Using the convenient map method of the array can eliminate loops, and only use a local function to convert elements one by one.

Copy code The code is as follows:

var names = ["Fred","Wilma","Pebbles"];
var upper = names.map(function(name){
Return name.toUpperCase();
});
upper;//["FRED","WILMA","PEBBLES"];

In addition, for example, we want to create several methods to create different strings, with common implementation logic, and each loop creates a string by concatenating the calculation results of each independent part.

Copy code The code is as follows:

function bulidString(n,callback){
var result = "";
for(var i = 0 ; i < n ;i ){
          result = callback(i);
}
Return result;
}
var alphabet = bulidString(26,function(i){
Return String.fromCharCode(aIndex i);
});
alphabet;//"abcdefghijklmnopqrxtuvwxyz";
var digits = buildString(10,function(i){ return i;})
digits;//"0123456789"
var random = buildString(9,function(){
Random = String.fromCharCode(Math.floor(Math.random()*26) aIndex
});
random;//"yefjmcef"(random)

This allows readers to have a clearer understanding of what the code can do without going into implementation details.

Remarks

javascript returns the formula for a random number in the specified range (between m-n): Math.random()*(n-m) m

At the same time, pay attention to the question requirements and whether it is required to return a positive integer

2.3 Calling Mode

Calling a function will pause the execution of the current function and pass control and parameters to the new function. In addition to the formal parameters defined at declaration, each function receives two new additional parameters: this and arguments.

This is a very important parameter, and its value is determined by the calling mode.

The following are 4 important calling patterns in JavaScript:

a. the method invocation pattern
b. the function invocation pattern
c. the constructor invocation pattern
d. Apply the apply invocation pattern

These modes differ in how to initialize the key parameter this

1. The method invocation method

When a function serves as a method of an object, we call the function a method. When a method is called, this is bound to the calling object.

Copy code The code is as follows:

var myObj={
val:0,
increment:function(inc){
This.val =typeof inc ==="number"? inc:1;
},
Get_val:function(){return this.val;}
}
myObj.increment();// 1
myObj["increment"](2);//3

Summary:

1. Methods that can obtain the context of the objects they belong to through this are called public methods

2. When using . or subscript expression to use a function, it is the method calling mode, and this object is bound to the previous object.

3. A function can use this to access the object, so it can retrieve the value of the object or change the value of the object. Binding this to the object occurs at call time.

2. the function invocation pattern

When a function is not a property of an object, then it is called as a function. When a function is called as function calling mode, this is bound to the global object. This was a design mistake in JavaScript that persists.

Copy code The code is as follows:

function add(x,y){
return x y;
}
myObj.double=function(){
var that=this;
var helper=function(){
That.val=add(that.value,that.value);
//The wrong way of writing may be like this, why is it wrong? Because when the function is called as an internal function, this has been bound to the wrong object, and the global object does not have a val attribute, so an incorrect value is returned.
​​​​ //this.val = this.val this.val;
}
​helper();
}
myObj.double();//6 

3. the constructor invocation pattern

JavaScript is a language based on prototypal inheritance, which means that objects can directly inherit properties from other objects, and the language is classless.

If you call a function with new in front of it, you will get a new object that hides the prototype member connected to the function, and this will also be bound to the new object.

The new prefix also changes the behavior of the return statement. This is also not a recommended way of programming.

Copy code The code is as follows:

var Foo = function(status){
This.status = status;
}
Foo.prototype.get_status = function(){
Return this.status;
}
//Construct a Foo instance
var myFoo = new Foo("bar");
myFoo.get_status();//"bar"

4. Apply the apply invocation pattern

Because JavaScript is a functional object-oriented language, functions can have methods.

The Apply method has two parameters, the first is the value that will be bound to this, and the second is the parameter array. In other words, the Apply method allows us to build an array and use it to call the function, which allows us to select this The value also allows us to select the value of the array.

Copy code The code is as follows:

var array = [3,4];
var sum = add.apply(null,array); // 7
var statusObj = {status:"ABCDEFG"};
Foo.prototype.pro_get_status = function(prefix){
Return prefix "-" this.status;
}
var status = Foo.prototype.get_status.apply(statusObj);// "ABCDEFG"
var pro_status = Foo.prototype.get_status.apply(statusObj,["prefix"]);// "prefix -ABCDEFG"

Normally, the receiver of a function or method (the value bound to the special keyword this) is determined by the syntax of the caller. In particular, the method call syntax binds the method object to the this variable. However, sometimes it is necessary to use a custom receiver to call a function. At this time, you need to use the call method or bind method to customize the receiver to call the method

2.4 Use the bind method to extract methods with determined recipients

Since there is no difference between methods and properties whose value is a function, it is also easy to extract the method of the object and extract the function as a callback function and pass it directly to the higher-order function.

But it’s also easy to forget to bind the receiver of the extracted function to the object from which the function was extracted.

Copy code The code is as follows:

var buffer = {
Entries: [],
       add :function(s){
This.entries.push(s);
}  
}
var source = ["867","-","5309"];
source.forEach(butter.add);//error:entries is undefined

At this time, the recipient of butter.add is not the butter object. The receiver of the function depends on how it is called. The forEach method is called in the global scope, so the implementation of the forEach method uses the global object as the default receiver. Since there is no entries attribute in the global object, this code throws An error occurred.

The forEach method allows the caller to provide an optional parameter as the receiver of the callback function.

Copy code The code is as follows:

var source = ["867","-","5309"];
source.forEach(butter.add,butter);

But not all high-order functions are thoughtful enough to provide users with callback function receivers.

There are two solutions:

1) Create a wrapper function that explicitly calls add via a buffer object method. No matter how the wrapped function is called, it is always guaranteed to push its parameters into the target array.

Copy code The code is as follows:

var source = ["867","-","5309"];
source.forEach(function(s){
Butter.add(s);
});

2) The bind method of the function object requires a receiver object and generates a wrapper function that calls the original function using the method call of the receiver object.

Copy code The code is as follows:

var source = ["867","-","5309"];
source.forEach(butter.add.bind(buffer));

Remarks

buffer.add.bind(buffer) creates a new function instead of modifying the buffer.add function:

buffer.add === buffer.add.bind(buffer); //false

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