我们知道,js函数有多种写法,函数声明 ,函数表达式,Function式构造函数,自执行函数,包括Es6的箭头函数,Class类写法,高阶函数,函数节流/函数防抖,下面我就开始讲关于上面几种类型的最基本用法。

函数声明式写法

这种写法是最基本的写法 ,使用关键字 function 定义函数,函数声明后不会立即执行,会在我们需要的时候调用到。这种函数是全局的,如果有两个同名的声明式函数存在,那么第二个会覆盖第一个。

   function   Test(){

    } 

有个面试题如下,问输出:

function  test1(){
alert('test1')
} ;
test1() ;
function test1(){
alert('test2')
} ;

答案是:'test2'

函数表达式写法

定义一个变量,指向一个函数,其实可以看做是一个匿名函数。这种函数在声明之后才能调用,在声明之前调用会报错。

      var   test=function(){

     }

有个面试题如下,问输出:

var test=function(){ alert('test1')  } ;

test() ; 

var test=function(){ alert('test2')  } ;  

答案是:test1

Function式构造函数

通过 JavaScript 函数构造器(Function())实例化来定义函数,前面定义各种变量,最后定义函数的返回值或者是输出,这种函数不太常用。

var test= new Function("a", "b", "return a * b");

test();

自执行函数

这种函数没有名称,只有声明体,实际上是一个 匿名自我调用的函数。这种函数的好处是保持变量独立,不被外部变量污染,形成一个封闭的函数执行环境。

写法如下:

(function(){

})();
这种写法比较常见,比如Jquery框架里面就用到这种写法:
‘use strict’; ;(function(context,win){

})(Jquery||undefined,window)

  

还有像闭包的写法,经常会遇到像下面类似的面试题的写法:

var divs=tr.getElementsByTagName("div");
for(var i=0;i<divs.length;i++){
(function(div){
div.onclick=function(){
alert(this.innerHTML);
}
})(divs[i]) }

  

 箭头函数

这种声明方式是Es6引入的写法,箭头函数是简写形式的函数表达式,并且它的内部的this指向的不是自己,指向的是当前执行环境的顶级对象(如window,react组件中指向的是当前组件的class父级组件),箭头函数总是匿名的。写法如下:

const   test=()=>{
}

 

比如下面的函数中的this指向的是window

const  test={
array:[1,2],
show:()=>{
console.log(this. array)
}
}
test.show();//undefined

  

而下面react组件的onSearch中的this指向的是Test这个组件,通过this可以找到Test组件下面定义的函数或者state,props。注意constructor中注释的代码是为了将onSearch的this指向Test组件,和箭头函数是两个不同写法,但是有同等效果。

		import  {Button}  from 'antd'
class Test extends Component {
constructor(props) {
super(props);
//this.onSearch = this.onSearch.bind(this)
}
//onSearch(){
console.log(this);
//}
onSearch=()=>{
console.log(this);
}
render() {
return ( < div >
<Button onClick={this.onSearch}>测试</Button>
< /div>
)
}
}

  

Class类写法

Js之前是没有类的概念的,之前都是将一些属性挂载在函数的实例上或者通过原型来实现基于函数的类的概念。就比如下面的写法

function  Test (){

this.name=’’;

//this.show=function(){

//}

}

Test.prototype.show=function(){

   Console.log(this.name)

}

new Test().show();

ES6引入了Class(类)这个概念,作为对象的模板,通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法.

基本写法:

class   test {
//第一种
Show() {
alert('show');
}
//第二种
//Show=()=>{
//}
}
var test1 = new test();
var test2= new test();

  

注意这个类中的这两种方法的写法是有区别的

第一种声明的方法会指向test的原型prototype上

test1. Show=== test2.Show//true

第二种声明的方法会指向test的实例,每次实例化都会生成一个Show方法。

test1. Show=== test2.Show//false

继承写法如下,这样newTest  就会继承test中的Show

class    newTest  extends   test{
Show() {
super. Show();
alert('newshow');
}
}
var test=new newTest ();
test. Show()

  

如果newTest  中没有声明Show方法,就会调用父类test中的Show方法,如果申明了就会调用newTest  的Show方法。子级调用父级的方法用super关键字访问如

super. Show();

  • 高阶函数

高阶函数英文叫Higher-order function。JavaScript的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。简单的说法就是“高阶函数就是可以把函数作为参数,或者是将函数作为返回值的函数。”,其实最典型的应用就是回调函数了。

高阶函数大致有下面几个场景

1.函数回调

$.get(‘’,{},function(data){

})

var   test=function(callback){
callback.apply(this,arguments) }

2函数柯里化

在一个函数中首先填充几个参数(然后再返回一个新函数)的技术称为柯里化(Currying),这个定义可能有点难理解,先看下一个简单的函数柯里化的实现:

      var currency=function(fn){
var self=this;
var arr=[];
return function(){
if(arguments.length==0){
return fn.apply(this,arr );
}
else{
[].push.apply(arr,arguments);
return arguments.callee;
}
}
}

然后再看一下调用:

var  sum=function(){
var total=0;
var argArr=arguments;
for (var i = 0; i < argArr.length; i++) {
total+=argArr[i];
}
return total;
}
var test= currency(sum);
test(100,200);
test(300)
alert(test());

其实简单的解释就是currency函数里面定义一个局部变量arr数组,然后返回一个函数,返回的函数体里对变量arr进行了赋值,每次当函数传入参数的时候都会将参数push到arr里面,然后返回函数体,形成了一个闭包。当没有参数传入的时候就直接执行传入的sum函数,然后执行函数sum传入的的参数就是arr.

3.函数扩展

函数扩展一般是通过原型来扩展,传入一个回调函数,比如给Array扩展一个函数Filter代码如下:

Array.prototype.Filter=function(callback){
…..
}

做过react 开发的都知道有高阶组件的概念,其实高阶组件是通过高阶函数演变的,只不过传入的参数是组件,然后返回值是一个组件,来看下面的一段代码  

export default simpleHoc(Usual);
import React, { Component } from 'react'; const simpleHoc = WrappedComponent => {
console.log('simpleHoc');
return class extends Component {
render() {
return <WrappedComponent {...this.props}/>
}
}
}
export default simpleHoc;           

函数节流/函数防抖

一般做前端时间比较长的人对这个概念比较熟了,但是刚接触的人估计会有点懵逼。

这两个概念都是优化高频率执行js代码的一种手段,来看下他们的基本概念

函数节流:函数在设定的时间间隔内最多执行一次

应用场景:高频率点击事件

var  isEnable=true;

document.getElementById("testSubmit").onclick=function(){
if(!isEnable){
return;
}
isEnable=false;
setTimeout(function(){
console.log("函数节流测试");
isEnable = true;
}, 500);
}

函数防抖:函数在一段时间内不再被调用的时候执行

应用场景:onresize onscroll事件,oninput事件

Var  timer=null;

Window. onscroll=function(){
clearTimeout(timer);
timer = setTimeout(function(){
console.log("函数防抖测试");
}, 500);
}

  

从上面两个事件可以看出来区别:

函数节流在第一次操作之后的500毫秒内再次点击就只执行一次,不会重置定时器,不会重新计时

函数防抖是在持续触发onscroll事件的时候会重置重置定时器,重新计时,直到不触发事件的500毫秒之后执行一次

上面讲的是函数最常见基本的用法,个人表述有不恰当的地方请指正

javascript函数定义以及常见用法的更多相关文章

  1. JavaScript 函数定义方法

    JavaScript 函数定义方法. 函数声明 在之前的教程中,你已经了解了函数声明的语法 : function functionName(parameters) { 执行的代码 } 函数声明后不会立 ...

  2. 深入理解javascript函数定义与函数作用域

    最近在学习javascript的函数,函数是javascript的一等对象,想要学好javascript,就必须深刻理解函数.本人把思路整理成文章,一是为了加深自己函数的理解,二是给读者提供学习的途径 ...

  3. JavaScript函数定义和调用 变量作用域

     本文是笔者在看廖雪峰老师JavaScript教程时的个人总结   JavaScript中函数定义可以是这样的格式 function 函数名(参数) {     函数体 } 也可以是这样的格式     ...

  4. javascript函数定义表达式和函数声明的区别

    在javascript中,函数有两种定义写法,函数定义表达式和函数声明,其例子分别如下所示: var test = function(x){ return x; } function test(x){ ...

  5. [转]javascript函数定义表达式和函数声明的区别

    在javascript中,函数有两种定义写法,函数定义表达式和函数声明,其例子分别如下所示: var test = function(x){ return x; } function test(x){ ...

  6. JavaScript 函数定义

    JavaScript 使用关键字 function 定义函数. 函数可以通过声明定义,也可以是一个表达式. 函数声明 在之前的教程中,你已经了解了函数声明的语法 : function function ...

  7. JavaScript函数定义 ,参数调用

    一.JavaScript函数函数: 函数就是一种封装,由事件驱动的或者当它被调用时执行的可重复使用的代码块.定义函数:function 函数名(){函数体;}数不会自动执行,需要被调用才可以执行函数名 ...

  8. JavaScript 函数定义和调用

    普通的函数定义方法: function abs(x):{ if (x >= 0){ return x; }else { return -x ; } } 两种方法是等价的 var abs = fu ...

  9. js基础之javascript函数定义及种类-普通涵数-自执行函数-匿名函数

    普通函数 1.不带参数 function fucname(){ alert("hello"); } funcname() 2.带参数 function funcname(arg){ ...

随机推荐

  1. sencha touch list tpl 监听组件插件(2013-9-15)

    插件代码 /* *list tpl模版加入按钮监控 *<div class="x-button-normal x-button x-iconalign-center x-layout- ...

  2. Windows下Visual Studio 2013编译Lua 5.2.3

    1.创建一个Visual C++的Empty Project,如果需要支持Windows XP将Platform Toolset设置为Visual Studio 2013 - Windows XP ( ...

  3. 算法题目-记hulu失败的实习面试

    1.对于数组A[0,1,2,3,4,...,k],求得0<=i < j < k,且使得A[j] - A[i]为最大值. 最简单也最容易想到的搜索两遍,即可得到答案.i的位置从起始至倒 ...

  4. 【咸鱼教程】Wing动画编辑器创建精美(一般-_-)开场动画

    游戏中会用着一些简单的动画,公司一般使用的dragonbones制作,导出二进制格式或者MC来使用.感觉一些简单动画直接使用动画编辑器更加简便些. 引擎版本:5.0.14wing版本:4.1.0 一 ...

  5. 【JSP】EL表达式语言

    EL简介 EL语言原本是JSTL1.0中的技术(所以EL和JSTL配合如此亲密和默契也就是自然的了),但是从JSP2.0开始(JSTL1.1)就分离出来纳入了JSP的标准了.因此EL不需要任何jar包 ...

  6. poj3347 Kadj Squares【计算几何】

    Kadj Squares Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 3594   Accepted: 1456 Desc ...

  7. R数据可视化手册学习简单的绘制常见的图形

    1.绘制散点图 # 使用ggplot2 library(ggplot2) ggplot(data = mtcars, aes(x = wt, y = mpg)) + geom_point() 2.绘制 ...

  8. 11.20 HTML及CSS

    <div>用于分组HTML元素的块级元素HTML表单,用于收集不同类型的用户输入<input type='radio'>:定义了表单的单选框按钮<input type=' ...

  9. UVA - 11624 Fire! bfs 地图与人一步一步先后搜/搜一次打表好了再搜一次

    UVA - 11624 题意:joe在一个迷宫里,迷宫的一些部分着火了,火势会向周围四个方向蔓延,joe可以向四个方向移动.火与人的速度都是1格/1秒,问j能否逃出迷宫,若能输出最小时间. 题解:先考 ...

  10. Oracle安装部署之linux OS install oracle database安装脚本

    #!/bin/bash#Purpose:Create and config oracle install.#Usage:Log on as the superuser('root') #1.creat ...