In JavaScript, functions are very powerful. In addition to the basic knowledge about functions, mastering some advanced functions and applying them will not only make the JS code look more streamlined, but also improve performance. This article is summarized by the editor. Some commonly used and important functions
In JavaScript, functions are very powerful. They are first-class objects that can also be used as methods of another object, can also be passed as parameters to another function, and not only that, they can also be returned by a function! It can be said that in JS, functions are everywhere and omnipotent, comparable to Monkey King! When you use the function well, it can help you learn the West and make the code elegant and concise. When you use it poorly, you will suffer disaster and make trouble~
In addition to the basic knowledge related to functions In addition, mastering some advanced functions and applying them will not only make the JS code look more streamlined, but also improve performance. The following are some commonly used and important advanced functions summarized by the editor, plus some personal insights, which are hereby recorded. If you are a JS beginner, don't be scared by the word "advanced", because the article intersperses some basic knowledge such as prototypes and this, and I believe it is not difficult to understand. If you are a JS expert, you can also use this article to find and fill in gaps.
Text
Scope-safe constructor
function Person(name,age){ this.name = name; this.age = age; } var p1 = new Person("Claiyre",80);
I believe you are familiar with the above constructor The function must be familiar, but what will happen if a careless programmer forgets to add new when calling this constructor?
var p3 = Person("Tom",30); console.log(p3); //undefined console.log(window.name); //Tom
Due to the use of an unsafe constructor, the above code accidentally changes the name of the window, because the this object is bound at runtime, and when the constructor is called using new, this points to the newly created object. For objects, when new is not used, this points to window.
Since the name attribute of window is used to identify the link target and frame, accidental overwriting of this attribute here may lead to other errors.
The scope-safe constructor will first confirm that this object is an instance of the correct type before making changes, as follows:
function Person(name,age){ if(this instanceof Person){ this.name = name; this.age = age; } else { return new Person(name,age); } }
This avoids accidentally changing or setting properties on the global object .
Implementing this safe mode is equivalent to locking the environment in which the constructor is called, so problems may arise when borrowing the constructor inheritance mode. The solution is to use a combination of the prototype chain and the constructor mode, that is, combined inheritance.
If you are a JS library or framework developer, I believe that scope-safe constructors must be very useful to you. In projects where multiple people collaborate, in order to prevent them from accidentally changing the global object, scope-safe constructors should also be used.
Lazy loading function
Due to behavioral differences between browsers, there may be many if statements in the code that detect browser behavior. But if the user's browser supports a certain feature, it will always support it, so these if statements only need to be executed once. Even the code with only one if statement is faster than none.
Lazy loading means that the branch of function execution will only be executed once. There are two ways to implement lazy loading. The first is to process the function when the function is called for the first time and use the detected result. Rewrite the original function.
function detection(){ if(//支持某特性){ detection = function(){ //直接用支持的特性 } } else if(//支持第二种特性){ detection = function(){ //用第二种特性 } } else { detection = function(){ //用其他解决方案 } } }
The second way to implement lazy loading is to specify the appropriate function when declaring the function.
var detection = (function(){ if(//支持某特性){ return function(){ //直接用支持的特性 } } else if(//支持第二种特性){ return function(){ //用第二种特性 } } else { return function(){ //用其他解决方案 } } })();
The advantage of lazy loading function is that it only sacrifices a little performance during the first execution, and then There will be no more unnecessary consumption of performance.
Function binding scope
In JS, the scope of a function is dynamically bound when the function is called, that is It is said that the point of the this object of a function is variable, but in some cases, we need to make the execution scope of a certain function fixed and always point to a certain object. What to do at this time?
Dangdang~~You can use functions to bind scope functions
function bind(fn,context){ return function(){ return fn.apply(context,arguments); } }
Usage:
var person1 = { name: "claiyre", sayName: function(){ alert(this.name); } } var sayPerson1Name = bind(person1.sayName,person1); sayPerson1Name(); //claiyre
The call function and the apply function can temporarily change the scope of the function, use bind The function can get a scope-bound function
Function curry(curry)
The concept of curry is simple: just pass Call a function with some arguments, and then have the function return another function to handle the remaining arguments. It can be understood as giving the function the ability to "load".
Many js libraries encapsulate the curry function, and the specific use can be like this.
var match = curry(function(what,str){ return str.match(what) }); var hasNumber = match(/[0-9]+/g); var hasSpace = match(/\s+/g) hasNumber("123asd"); //['123'] hasNumber("hello world!"); //null hasSpace("hello world!"); //[' ']; hasSpace("hello"); //null console.log(match(/\s+/g,'i am Claiyre')); //直接全部传参也可: [' ',' ']
Once a function is curried, we can call it passing some parameters first, and then get a more specific function. This more specific function helps us remember the parameters passed for the first time through closure, and finally we can use this more specific function to do whatever we want~
A simpler way to implement curry:
function curry(fn){ var i = 0; var outer = Array.prototype.slice.call(arguments,1); var len = fn.length; return function(){ var inner = outer.concat(Array.prototype.slice.call(arguments)); return inner.length === len?fn.apply(null,inner):function (){ var finalArgs = inner.concat(Array.prototype.slice.call(arguments)); return fn.apply(null,finalArgs); } } }
debounce function
debounce function, also known as "debounce function". Its function is also very simple and direct, which is to prevent a certain function from being called continuously, causing the browser to freeze or crash. Usage is as follows:
var myFunc = debounce(function(){ //繁重、耗性能的操作 },250); window.addEventListener('resize',myFunc);
像窗口的resize,这类可以以较高的速率触发的事件,非常适合用去抖函数,这时也可称作“函数节流”,避免给浏览器带来过大的性能负担。
具体的实现时,当函数被调用时,不立即执行相应的语句,而是等待固定的时间w,若在w时间内,即等待还未结束时,函数又被调用了一次,则再等待w时间,重复上述过程,直到最后一次被调用后的w时间内该函数都没有被再调用,则执行相应的代码。
实现代码如下:
function debounce(fn,wait){ var td; return function(){ clearTimeout(td); td= setTimeout(fn,wait); } }
once函数
顾名思义,once函数是仅仅会被执行一次的函数。具体实现如下:
function once(fn){ var result; return function(){ if(fn){ result = fn(arguments); fn = null; } return result; } } var init = once(function(){ //初始化操作 })
在被执行过一次后,参数fn就被赋值null了,那么在接下来被调用时,便再也不会进入到if语句中了,也就是第一次被调用后,该函数永远不会被执行了。
还可以对上述once函数进行改进,不仅可以传入函数,同时还可以给传入的函数绑定作用域u,同时实现了bind和once。
function once(fn,context){ var result; return function(){ if(fn){ result = fn.apply(context,arguments); fn = null; } return result; } }
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
The above is the detailed content of How to use advanced functions in JavaScript. For more information, please follow other related articles on the PHP Chinese website!