JavaScript高级之函数

Posted 二木成林

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript高级之函数相关的知识,希望对你有一定的参考价值。

函数概述

javascript中的函数是一组操作的集合体,函数中封装了一组语句。

并且函数是可以执行的,而其他类型的数据是不能执行的。

使用函数的好处

  • 提高代码的复用性
  • 提高代码的可读性

定义函数

JavaScript中定义函数有两种方式:

  • 函数声明
  • 表达式

定义的基本语法如下:

// 函数声明方式定义函数
function 函数名([参数列表]) 
    // 函数体


// 表达式方式定义函数
var 函数名 = function ([参数列表]) 
    // 函数体
;

例如:

// 函数声明方式定义函数
function f1(msg) 
    console.log(msg);

f1('hello f1()...');

// 表达式方式定义函数
var f2 = function (msg) 
    console.log(msg);
;
f2('hello f2()...');

调用函数

JavaScript中调用函数有如下几种方式:

  • 函数名():通过函数名直接调用。
  • 对象名.函数名():通过对象调用。
  • new 函数名():通过new调用。
  • 函数名.call(对象名)函数名.apply(对象名):临时让某方法成为对象的属性进行调用。

函数名()

// 通过函数名直接调用
function hello(msg) 
    console.log(msg);


hello('hello world');

对象名.函数名()

在 JavaScript 中,您可以把函数定义为对象方法。

// 通过对象调用
var obj = 
    name: '张三',
    print: function () 
        console.log(this.name);
    
;
obj.print();

new 函数名()

如果函数调用的前面是new关键字,那么这是一个构造函数调用。

它看起来像你创建一个新的函数,但由于 JavaScript 函数是对象,你实际上创建一个新对象:

// 通过new调用
function hello(name, age) // 这是函数构造器
    this.name = name;
    this.age = age;


// 创建了一个新对象
var h = new hello('tom', 18);
console.log(h.name, h.age);// 可以通过对象访问属性的方式访问函数内的定义的属性

构造器调用会创建新对象。新对象会从其构造器继承属性和方法。

构造器内的 this 关键词没有值。

this 的值会成为调用函数时创建的新对象。

函数名.call(对象名)函数名.apply(对象名)

还可以通过call()apply()方法让需要被调用的函数临时绑定到某个对象来完成调用。

// 临时让某方法成为对象的属性进行调用。
// 1.创建一个对象
var obj = ;
// 2.创建一个方法
var f1 = function () 
    console.log('f1...');
;
// 3.临时让某方法成为对象的属性进行调用
f1.apply(obj);// 或f1.call(obj)

回调函数

概念

JavaScript中的回调函数就是将函数A作为参数传递到函数B中,并且在函数B中进行调用,那么函数A就被称为回调函数。如果没有名称(函数表达式),就叫做匿名回调函数。

// 1.创建普通函数A
function A() 
    console.log('function A()...');


// 2.创建普通函数B,但是传递一个函数fun作为形参,并且在函数B内部调用函数fun
function B(fun) 
    fun();


// 3.将函数A作为实参,传递给函数B
B(A);

回调函数在异步场景中使用较多,如Ajax请求、setTimeout等。

回调函数传参

回调函数如果想要传参有如下两种解决方式:

  • 将回调函数的参数作为与回调函数同级的参数进行传递
// 1.创建普通函数A
function A(msg) // 这里A将作为回调函数,需要传递一个msg参数
    console.log(msg);


// 2.创建普通函数B,但是传递一个函数fun作为形参,并且在函数B内部调用函数fun
function B(fun, msg) // 这里fun作为回调函数、msg作为回调函数的参数,都作为函数B的参数进行传递
    fun(msg);// 在函数体内将msg传递给回调函数fun作为参数


// 3.将函数A作为实参,传递给函数B
B(A, "hello world");// 传递了两个实参:回调函数和回调函数需要的参数

// 这种匿名方式看起来更好点,可以得知给函数B传递的第一个参数是一个函数,就是回调函数;第二个参数是回调函数需要的参数。
B(function (msg) 
    console.log(msg)
, 'hello world');
  • 回调函数的参数在函数内部创建
// 1.创建普通函数A
function A(msg) // 这里A将作为回调函数,需要传递一个msg参数
    console.log(msg);


// 2.创建普通函数B,但是传递一个函数fun作为形参,并且在函数B内部调用函数fun
function B(fun) 
    // 在函数B内部定义一个值作为参数传递给回调函数fun
    var msg = 'hello world';
    fun(msg);


// 3.将函数A作为实参,传递给函数B
B(A);// 传递了一个实参:回调函数

// 使用匿名的方式传递回调函数
B(function (msg) 
   console.log(msg);
);

注意:前者从外向内传递数据;后者从内向外传递数据(即在回调函数中接收数据),node.js的fs模块的很多方法都是这样操作文件的。

IIFE

概念

IIFE全称是Immediately-Invoked Function Expression,叫做立即执行函数,所谓的立即执行函数就是在定义函数中立刻调用该函数。

我们知道在函数名后面跟一对小括号()表示函数调用,那么如下写法就应该可以调用函数:

function hello() 

();

但事实上却会报错:SyntaxError: Unexpected token ')'。所以解决方法是让function不出现在行首,让引擎将其理解成一个表达式,常用的两种方法是:

(function()  /* code */ ());
(function()  /* code */ )();

例如:

// 不传递参数
(function () 
    console.log('hello world');
)();

// 传递参数
(function (msg) 
    console.log(msg);
)('hello world');

作用

立即执行函数作用如下:

  • 隐藏实现
  • 不会污染全局命名空间避免同名冲突
  • 用它来编码js模块
// 函数内定义的变量仅作用在函数内部,不会与全局变量产生同名冲突
(function ()  // 立即执行函数
    var a = 3;
    console.log(a + 3)
)();
var a = 4;
console.log(a);

// 隐藏实现,向外暴露函数
(function () 
    var a = 1;

    function test() 
        console.log(++a)
    

    $ = function ()  // 向外暴露一个全局函数
        return 
            test: test
        
    
)();

$().test(); // 1. $是一个函数 2. $执行后返回的是一个对象

函数中的this

概述

html中任何函数本质上都是通过某个对象来调用的,如果没有直接指定就是Window,所有函数内部都有一个变量this,它的值是调用函数的当前对象。如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test</title>
</head>
<body>
<script type="text/javascript">
    console.log(this);
</script>
</body>
</html>

this的值

在函数中,this的值分为如下几种情况:

  • fun():该函数fun内this的值为Window对象。
  • obj.fun():该函数fun内this的值为调用该函数的对象obj
  • var o = new obj():则this的值为新创建的对象o
  • fun.call(obj):则this的值为传入的对象obj
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test</title>
</head>
<body>
<script type="text/javascript">
    console.log(this);// this是谁?Window对象

    function fun() 
        console.log(this);// this是谁?Window对象
    

    fun();

    function Person(name, age) 
        console.log(this);
        this.name = name;
        this.age = age;
        this.say = function () 
            console.log(this);
            console.log('我是', name, ',今年' + age + '岁。');
        
    

    Person('李四', 20);// this是谁?Window对象

    var p = new Person('张三', 18);// this是谁?p对象
    p.say();// this是谁?p对象

    var obj = ;
    p.say.call(obj);// this是谁?obj对象

    var say=p.say;
    say();// this是谁?Window对象

    function f1() 
        function f2() 
            console.log(this);
        
        f2();// this是谁?Window对象
    
    f1();
</script>
</body>
</html>

参考资料:

以上是关于JavaScript高级之函数的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript高级程序设计笔记之面向对象

JavaScript 之 创建对象

JavaScript高级之闭包

JavaScript高级之函数进阶

JS 高级

JavaScript系列之高级篇