W3CAPI 在线教程 | 菜鸟教程_LOGO
文档目录
文档目录
我的书签
 

JavaScript

JavaScript 入门教程

JavaScript是一门Web编程语言,用来实现网页的交互功能,它和HTML、CSS共同组成了个Web开发的基础工具集合,也是前端开发者必备的技能;学习JavaScript教程可以了解它在网页开发中的所有特性和相关概念,让我们能够更加快速的去开发Web应用。

W3CAPI
1
2020-06-18 07:05:48

JavaScript 函数

JavaScript:函数

什么是函数?

在编程中,函数是程序中执行特定功能的一个独立模块。从这个意义上说,函数属于一类过程或例程。在某些编程语言中,过程与函数存在明显差异:函数会返回一个值,而过程仅执行操作但不返回值。在大多数编程语言和脚本语言中,存在预置于库中的内置函数。此外,您还可以编写自定义函数(称为"用户自定义函数"或UDF)来实现特定任务。

JavaScript 函数

与其他编程和脚本语言类似,函数是JavaScript中的基本构建单元。函数在程序中重复使用,能够有效节省网页开发时间。要使用函数,必须在其所调用作用域内的某处进行定义。在JavaScript中定义自定义函数是一项简单的任务。

语法:JavaScript 函数

function functionName(argument1,argument2..argumentN)
{
  // block of code in JavaScript
}
执行一下

函数声明始终以关键字function开头,后接

  • 新创建函数的名称
  • 函数接受的参数列表,由圆括号包裹并以逗号分隔。
  • 包裹在花括号{}中的JavaScript代码块,将在函数被调用时执行。
  • 左花括号({)标志函数代码的开始,右花括号(})标志函数的结束。

声明JavaScript函数

例如,要声明一个计算所传入参数立方的函数,可通过以下两种方式之一实现:

注:在算术与代数中,数n的立方即其三次幂——该数自乘两次的结果:n3 = n × n × n。

示例 - 1:

function cube(n)
{
return n*n*n;
}
执行一下

示例 - 2:

var cube = function(n)
{
return n*n*n;
};
执行一下

函数"cube"接受一个名为n的参数。函数体内仅包含一条JavaScript语句,该语句指示将函数的参数(n)自乘两次后返回计算结果。此处返回语句用于返回运算后的数值。

风格指南:函数声明

优先使用函数声明而非函数表达式,因为函数声明具有名称标识,在调用堆栈中更易追溯。此外,函数声明的整体会被提升(hoisted),而函数表达式仅引用被提升,这可能导致与typeof检查相关的错误。当需要条件式声明时仍应选择函数表达式。箭头函数适用于需要词法this绑定的场景,但需注意其没有prototype属性且无法通过new实例化。

// bad
const foo = function () {
};

// good
function foo() {
}

执行一下

切勿在非函数块(如 if、while 等)中声明函数,而应将其赋值给一个变量。
ECMA-262 将块定义为语句列表。函数声明并非语句。

// bad
if (currentUser) {
  function test() {
    console.log('Nope.');
  }
}

// good
let test;
if (currentUser) {
  test = () => {
    console.log('Yup.');
  };
}

执行一下

调用JavaScript函数

我们已了解如何定义函数。定义函数仅为函数命名并指定其被调用时执行的操作。

调用函数将使用指定参数实际执行函数内部编写的指令。

函数的参数不仅限于字符串和数值,您还可以向函数传递完整的对象。

例如,名为abc()的函数可按如下方式调用。

abc();
执行一下

无论是之前的示例一还是示例二,你均可通过如下所示的类似代码行来调用该函数:

cube(2);
执行一下

示例 - 1:

函数的作用域为其所声明的上级函数(也就是在声明它的函数内部有效),若声明于顶层则为整个程序。您可以在调用位置之后声明函数,但仅在严格遵循函数声明语法(而非函数表达式)的情况下生效。函数 funcName(){}格式。以下函数有效:

alert(cube(2));
cube = function (n)
{
return n*n*n;
};

执行一下

以下代码无法运行。

alert(cube(2));
var cube = function(n)
{
return n*n*n;
};

执行一下

函数作用域

函数可被访问的源位置称为函数作用域。当您在函数内部定义变量时,这些变量仅存在于该函数作用域内,因此无法在函数外部访问这些变量。在全局作用域中定义的函数能够访问全局作用域内定义的所有变量。在另一个函数内部定义的函数还能访问其父函数中定义的所有变量,以及父函数能够访问的任何其他变量。参考以下示例:

// The following variables are defined in the global scope
var x = 12, y = 25;

// This function is defined in the global scope
function add(){
  return (x + y);
}

add(); // Returns 37

执行一下

在上述示例中,x、y 和 add() 均在全局作用域中声明。因此 add() 函数可访问 x 和 y 的值,并返回 (x+y) 的计算结果。

// The following variables are defined in the global scope
var x = 12, y = 25;

// This function is defined in the global scope
function add(){
  return (x + y);
}

add(); // Returns 37

执行一下

在第二个示例中,存在名为calculation()的函数,其内部嵌套了add()函数。因此add()能够访问其父函数中定义的所有变量,并返回(x+y)的计算结果。

重新审视参数

传递给函数的参数可分为两类:原始数据类型参数和非原始数据类型参数。原始数据类型是预定义的数据类型,例如整数、字符和字符串均属于原始数据类型。非原始数据类型由用户创建,有时被称为"引用变量"或"对象引用",因为它们指向存储数据的内存地址。例如用户自定义对象、数组都属于非原始数据类型。

如果将基本类型参数按值传递给函数,且函数内部修改了该参数的值,这种变更不会在全局作用域或调用函数中体现。请参考以下示例:

    
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Primitive Parameters</title>
</head>
<body>
    <script type="text/javascript">
        function primitive_parameter(a)
        {
           a = 100;
           console.log("Inside the function a is: " + a);
        }
        var a = 20;
        console.log("Before calling the function a is: " + a);
        primitive_parameter(a);
        console.log("After calling the function a is: " + a);
    </script>
</body>
    

若将对象作为非原始参数传入函数,且该函数修改了该对象的属性,则这些变更将在全局范围内生效,即这些变更在函数外部可见。参考以下示例:

    
// 定义对象
let car = { color: '红色', model: 'ABC' };
// 定义修改对象属性的函数
function changeColor(carObj) {
carObj.color = '蓝色';
}
// 调用函数
changeColor(car);
// 输出 'car' 颜色
console.log(car.color); // 输出: "蓝色"
    

function student(theObject)
{
   theObject.name = "Sara";
}

var student1= {name: "Scott", standard: "V", roll_no: 1};
var x,y;
x = student1.name;     // x gets the value "Scott"
student(student1);
y = student1.name;     // y gets the value "Sara"
// (the name property was changed by the function)

执行一下

若向参数重新赋值一个新对象,在函数外部不会产生任何影响,因为这更改的是参数本身的值而非对象属性的值。参考以下示例:

function student(theObject)
{
  theObject = {name: "Sara", standard: "VI", roll_no: 1};
}

var student1= {name: "Scott", standard: "V", roll_no: 1};
var x, y;

x = student1.name;  // x gets the value "Scott"
student(student1);
y = student1.name;  // y still gets the value "Scott"

执行一下

第一种情况下,对象 student1 被传递给 student 函数进行处理。该函数修改了其 name 属性,这个变更在全局作用域可见。第二种情况下,函数未修改对象本身的任何属性,而是创建了一个同名的新局部变量,尽管接收的参数与全局对象同名,但实际上不会对传入的全局对象产生任何影响。

风格指南:函数形参

切勿将参数命名为arguments。这会覆盖赋予每个函数作用域的arguments对象。

// bad
function nope(name, options, arguments) {
  // ...stuff...
}

// good
function yup(name, options, args) {
  // ...stuff...
}

执行一下

始终将默认参数置于末尾:

// bad
function handleThings(opts = {}, name) {
  // ...
}

// good
function handleThings(name, opts = {}) {
  // ...
}

执行一下

禁止使用Function构造函数创建新函数。通过此方式创建函数会以类似eval()的方式解析字符串,从而引发安全漏洞。

    
const riskyFunc = new Function('x', 'return x * 2;'); // 等价于 (x) => x * 2
    

// bad
function handleThings(opts = {}, name) {
  // ...
}

// good
function handleThings(name, opts = {}) {
  // ...
}

执行一下

函数签名中的间距:

// bad
const f = function(){};
const g = function (){};
const h = function() {};

// good
const x = function () {};
const y = function a() {};

执行一下

Closures(闭包)

闭包是JavaScript的重要特性之一。JavaScript允许函数的嵌套,即可以在一个函数内部声明另一个函数。JavaScript赋予内部函数完全访问外部函数内部定义的所有变量和函数,以及外部函数所能访问的其他变量和函数的权限。但外部函数无法访问内部函数内部定义的变量和函数,这为内部函数的变量提供了某种安全性。当内部函数以某种方式对外部函数以外的任何作用域可用时,就会创建一个闭包。示例如下:

    
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Closure Example</title>
</head>
<body>
    <script>
        function w3r_outer() {
            var str;
            str = "w3resource";
            function w3r_inner() {
                console.log(str);
            }
            w3r_inner();
        }
        w3r_outer();
    </script>
</body>
    

使用arguments对象

通过arguments对象,您可以用多于形参数量的实参调用函数,这在提前未知传入参数数量时非常实用。arguments对象中包含的各个参数可通过访问数组元素的相同方式被检索。您可通过以下形式访问每个参数:

arguments[i]
执行一下

其中i表示参数的位置或序号,从零开始计数。因此传递给函数的参数依次为arguments[0]、arguments[1]、arguments[2]...以此类推。arguments对象的length属性包含传递给函数的参数总数。

以下示例演示了arguments属性的用法。传入任意数量的数值作为参数,该函数将累加所有数字并返回结果。

    
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JavaScript arguments Example</title>
</head>
<body>
    <script>
        function adding_numbers(numbers) {
           var result = 0, i;

           // iterate through arguments
           for (i = 0; i < arguments.length; i++) {
              result += arguments[i];
           }
           return result;
        }
        console.log(adding_numbers(1,2,3,-4));
    </script>
<body>
    

JavaScript:递归函数

JavaScript 函数甚至可以递归,即函数能调用自身。以下网页文档接收数字并计算阶乘:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript: Recursive function.</title>
<script type="text/javascript">
function factorial(n)
{
if ((n==0) || (n==1))
return 1;
else
facn = (n * factorial(n-1))
return facn;
}
</script>
</head>
<body>
<h1 style="color: red">JavaScript Recursive function example</h1>
<hr />
<script type="text/javascript">
function factcal()
{
n=document.form1.text1.value;
result = factorial(n);
alert(" Factorial of "+n+" = "+result);
}
</script>
<form name="form1" action="#">
Input a number :
<input type="text" name="text1" size="5" />
<br />
<input type="button" value="Result" onclick="factcal()" />
</form>
</body>
</html>

执行一下

在浏览器中查看示例

完整示例:求数字的立方值

以下网页文档接收用户输入的数字,并通过值传递方式将其传递给函数cube(),返回该数字的立方。函数内部通过正则表达式验证输入值是否为数字:若为数字则计算其立方并通过alert()显示结果;若非数字则通过alert()显示错误信息。

HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Cube of a Number</title>
<link rel='stylesheet' href='form-style.css' type='text/css' />
</head>
<body onload='document.form1.text1.focus()'>
<div class="mail">
<h2>Input a number and get it's Cube</h2>
<form name="form1" action="#">
<ul>
<li><input type='text' name='text1'/></li>
<li>&nbsp;</li>
<li><input type="submit" name="submit" value="Submit" onclick="cube(document.form1.text1)" /></li>
<li>&nbsp;</li>
</ul>
</form>
</div>
<script src="cube-number.js"></script>
</body>
</html>

执行一下

CSS代码

li {list-style-type: none;
font-size: 16pt;
}
.mail {
margin: auto;
padding-top: 10px;
padding-bottom: 10px;
width: 400px;
background : #D8F1F8;
border: 1px soild silver;
}
.mail h2 {
margin-left: 38px;
}
input {
font-size: 20pt;
}
input:focus, textarea:focus{
background-color: lightyellow;
}
input submit {
font-size: 12pt;
}
.rq {
color: #FF0000;
font-size: 10pt;
}

执行一下

JavaScript代码

function cube(inputtxt)
    {
      var numbers = /^[-+]?[0-9]+$/;
	  var x;
	  if(inputtxt.value.match(numbers))
      {
      alert('Cube of '+inputtxt.value+' is '+inputtxt.value*inputtxt.value*inputtxt.value);
      document.form1.text1.focus();
      return true;
      }
      else
      {
      alert('Please input numeric characters only');
      document.form1.text1.focus();
      return false;
      }
    }

执行一下

在浏览器中查看示例

上一篇:JavaScript:const 声明
下一篇:JavaScript:eval() 函数

相关提问
敬请期待