为了账号安全,请及时绑定邮箱和手机立即绑定

深入JavaScript函数的注意点

前言

函数是一段可以反复调用的代码块。函数还能接受输入的参数,不同的参数会返回不同的值。
JavaScript 语言将函数看作一种值,与其它值(数值、字符串、布尔值等等)地位相同。凡是可以使用值的地方,就能使用函数。比如,可以把函数赋值给变量和对象的属性,也可以当作参数传入其他函数,或者作为函数的结果返回

函数参数

函数运行的时候,有时需要提供外部数据,不同的外部数据会得到不同的结果,这种外部数据就叫参数。分为以下两种:

  • 形参:函数定义的参数
  • 实参:函数调用时实际传递的参数。
function square(x) {
  return x * x;
}

square(2) // 4
square(3) // 9

上式的x就是square函数的形参。每次运行的时候,需要提供这个值,否则得不到结果。
参数匹配是从左向右进行匹配,如果实参个数少于形参,后面的参数对应赋值undefined。
实参的个数如果多于形参的个数,可以通过arguments访问。

function f(a, b) {
  return a;
}
f(1, 2, 3) // 1
f(1) // 1
f() // undefined
f.length // 2

函数内部的变量提升

与全局作用域一样,函数作用域内部也会产生“变量提升”现象。var命令声明的变量,不管在什么位置,变量声明都会被提升到函数体的头部

function foo(x) {
  if (x > 100) {
    var tmp = x - 100;
  }
}

// 等同于
function foo(x) {
  var tmp;
  if (x > 100) {
    tmp = x - 100;
  };
}

按值传递还是按引用传递?

  • 函数的参数如果是简单类型,会将一个值类型的数值副本传到函数内部,函数内部不影响函数外部传递的参数变量

  • 如果是一个参数是引用类型,会将引用类型的地址值复制给传入函数的参数,函数内部修改会影响传递参数的引用对象。

var a = 9, // 简单类型,值类型
  b = { name: 'laoma', age: 18 } // 引用类型
function demo(c1, c2) {
  c1 = 29 // 对c1做了更改。
  c2.name = '6666' // 更改了c2引用类型的顺序name
}
demo(a, b) // 调用函数执行
console.log(a) // a => 9;
console.log(b) // b.name => '6666'

break、continue和return区别

  • break语句用于跳出代码块或循环

  • continue语句用于立即终止本轮循环,返回循环结构的头部,开始下一轮循环。

  • 使用return可以结束整个函数

function fun () {
  for (var i = 0; i < 5; i++) {
    if (i == 2) {
      //break;  0 1 “执行完了”
      //continue; 0 1 3 4 “执行完了”
      return;//  0 1
    }
    console.log(i);
  }
  console.log("函数执行完了");
}
fun();

return返回值类型

返回值可以是任意的数据类型,也可以是一个对象,也可以是一个函数。

function fun2 () {
  return { name: "沙和尚" };//返回一个对象
}
var a = fun2();
function fun3 () {
  function fun4 () {//在函数内部再声明一个函数
    alert("我是fun4");
  }
  return fun4;//将fun4函数对象作为返回值返回
}
a = fun3();
a(); //"我是fun4"	
fun3()(); //"我是fun4"

立即调用的函数表达式

有时,我们需要在定义函数之后,立即调用该函数。这时,你不能在函数的定义之后加上圆括号,这会产生语法错误。而是写成如下形式:

(function(){ /* code */ }());
// 或者
(function(){ /* code */ })();

上面两种写法都是以圆括号开头,引擎就会认为后面跟的是一个表示式,而不是函数定义语句,所以就避免了错误。这就叫做“立即调用的函数表达式”(Immediately-Invoked Function Expression),简称 IIFE。
它的目的有两个:一是不必为函数命名,避免了污染全局变量;二是 IIFE 内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。

// 写法一
var tmp = newData;
processData(tmp);
storeData(tmp);

// 写法二
(function () {
  var tmp = newData;
  processData(tmp);
  storeData(tmp);
}());

上面代码中,写法二比写法一更好,因为完全避免了污染全局变量。

参考文章

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 1
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消