JavaScript(二)函数

函数定义

函数也存在提升,与变量提升相同

  • 函数声明

function func_name(param1,param2){
...;
return {};
}
  • 声明不定长参数,使用...

function foo(a, b, ...args) {
  console.log('a = ' + a);
  console.log('b = ' + b);
  console.log(args);
}
  • 声明默认值参数,同python

function multiply(a, b = 1) {
return a * b;
}
  • 关键字参数。同python

function multiply(a, b) {
return a * b;
}
multiply(a=1, b=2)
  • 参数关键字arguments,它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。arguments类似Array但它不是一个Array

变量作用域

JavaScript默认有一个全局对象window全局变量会绑定到window上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,并且很难被发现。

减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局变量中。例如:

// 唯一的全局变量MYAPP:
var MYAPP = {};
// 其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;

把自己的代码全部放入唯一的名字空间MYAPP中,会大大减少全局变量冲突的可能。

解构赋值

解构赋值直接对多个变量同时赋值,可用于对象的属性或方法。

const [p1,p2,p3]= [1,2,3]
const {对象的属性,对象的方法} = 对象
// 变量名和属性名不一致
const {k1,k2:new_k2}=对象

apply()和call()

一个函数内部调用了this

  • 如果是一个对象调用此函数,this指向这个对象

  • 直接调用此函数(即顶层对象window调用此函数),this指向window

要指定函数的this指向哪个对象,可以用函数本身的apply方法,它接收两个参数,第一个参数就是需要绑定的this变量,第二个参数是Array,表示函数本身的参数。

function add(){...}

add.apply(obj1,[p1,p2,p3])
add.apply(null,[p1,p2,p3]) //传入的对象是null,普通函数调用,无this

另一个与apply()类似的方法是call(),唯一区别是:

  • apply()把参数打包成Array再传入;

  • call()把参数按顺序传入。

闭包

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回

function lazy_sum(arr) {
    var sum = function () {
        return arr.reduce(function (x, y) {
            return x + y;
        });
    }
    return sum;
}
//调用lazy_sum()时,返回的并不是求和结果,而是求和函数
var f = lazy_sum([1, 2, 3, 4, 5]); // function sum()
//调用函数f时,才真正计算求和的结果
f(); // 15

在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力

返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

匿名函数

定义,由于JavaScript语法解析的问题,定义匿名函数并调用 需要用括号把整个函数定义括起来

// 定义
var fn1 = function(x,y) {return x+Y}; 
// 定义并调用
(function (x) { return x * x }) (3);

在面向对象的程序设计语言里,比如Java和C++,要在对象内部封装一个私有变量,可以用private修饰一个成员变量。

在没有class机制,只有函数的语言里,借助闭包,同样可以封装一个私有变量

箭头函数

箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式:

  • 一种只包含一个表达式,连{ ... }return都省略掉了

var fn = x => x * x;
  • 还有一种可以包含多条语句,这时候就不能省略{ ... }return

x => {
    if (x > 0) {
        return x * x;
    }
    else {
        return - x * x;
    }
}
  • 参数不止一个,就需要用括号()括起来

// 两个参数:
(x, y) => x * x + y * y

// 无参数:
() => 3.14

// 可变参数:
(x, y, ...rest) => {
    var i, sum = x + y;
    for (i=0; i<rest.length; i++) {
        sum += rest[i];
    }
    return sum;
}
  • 返回一个对象,对象需要用括号()括起来

x => ({ foo: x })

箭头函数看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this作用域,由上下文确定,总是指向外层调用者obj

generator

一个generator看上去像一个函数,但可以返回多次

generator和函数不同的是,generator由function*定义(注意多出的*号),并且,除了return语句,还可以用yield返回多次。类似python

 

 

 

posted @ 2023-07-03 20:10  huiyii  阅读(3)  评论(0编辑  收藏  举报