53.3-箭头函数、传参、作用域和异常处理

当你感到烦恼不断的时候,就走出去多看看沿途的风景。看看不同的风景,接触不同的人和事,你就会知道,你的烦恼有时只是你自己想多了!


总结:

  1. 逗号表达式中不允许出现 return;
  2. 语言区别:Python中根本没有关键字传参这一说;其他语言中关键字传参居多;
  3. JS中一旦出现{},都是对象object;
    • function是函数的定义,是一个独立的作用域,其中定义的变量在函数外不可见。
    • var a = 100 可以提升声明,也可以突破非函数的块作用域。
    • **a = 100 **隐式声明不能提升声明,在“严格模式”下会出错,但是可以把变量隐式声明为全局变量。建议少用。
    • let a = 100 不能提升声明,而且不能突破任何的块作用域。推荐使用。

1. 箭头函数

箭头函数就是匿名函数,他是一种更加简洁的语法;
将上例中的你们函数更改为 箭头函数;它是 ECMAScript 6 标准新增的伟大特性,其来源可能是 CoffeeScript 的函数申明语法

function map(fn,arr){
    let newarr = [];
    for (let i=0;i x+10,[1,2,3,4]))
console.log(map(function(x){return x+10},[1,2,3,4]))
console.log(map((x) => {
    return x + 10 
}, [1, 2, 3, 4]))
#--------------------------------------------------------------------------------------------
[11,12,13,14]
[11,12,13,14]
[11,12,13,14]

我们先来按常规语法定义函数:

function funcName(params) {
    return params + 2;
}
funcName(2);
// 4

该函数使用箭头函数可以使用仅仅一行代码搞定!

var funcName = params => params + 2;
funcName(2);// 4

箭头函数参数
如果一个函数没有参数,使用()
如果只有一个参数,参数列表可以省略小括号()
多个参数不能省略小括号,且使用逗号间隔

箭头函数返回值
如果函数体部分有多行,就需要使用{},如果有返回值使用return。
如果只有一行语句,可以同时省略大括号和return。
只要有return语句,就不能省略大括号。 console.log(map([1,2,3,4], x => {return ++x})) ,有return必须有大括号。

如果只有一条非return语句,加上大括号,函数就成了无返回值了,例如 console.log(map([1,2,3,4], x =>{x2})); 加上了大括号,它不等价于 x =>{return x2} 。因此,记住 x => x*2 这种正确的形式就行了。

2. 函数参数

普通参数
一个参数占一个位置,支持默认参数,他没有关键字传参

function add(x,y){
    console.log(x+y)
}

add (4,5)

const add1 = (x=5, y=5) => console.log(x + y)
add1(10,11)
console.log('-----------------------------')
console.log(add1(4, 6));
console.log(add1(4));
#-------------------------------------------------------------
9
21
-----------------------------
10
undefined
9
undefined
Info: End process (上午9:05:30)

上面add2的调用结果分别为
NaN、NaN、5

为什么?
1、JS中并没有Python中的关键字传参
2、JS只是做参数位置的对应
3、JS并不限制默认参数的位置;

add2()相当于add(6, undefined) // NAN
add2(1)相当于add(1, undefined)
add2(y=2,z=3)相当于add2(2,3),因为JS没有关键字传参,但是它的赋值表达式有值,y=2就是2,z=3就是3
建议,默认参数写到后面,这是一个好的习惯。

可变参数(rest parameters剩余参数)

JS使用...表示可变参数(Python用*收集多个参数)

const sum = function (...args) {
    let result = 0;
    for (let x in args) {
        result += args[x];
    }
    return result;
};
console.log(sum(3, 6, 9))
#-------------------------------------------------------------
Info: Start process (上午9:13:03)
18
Info: End process (上午9:13:03)
arguments对象

函数的所有参数会被保存在一个arguments的键值对字典对象中。
在箭头函数中就不要 用 arguments对象;

const add1 = function(x=4,...y){
    let s = 0;
    s += x;
    console.log(x);
    console.log(y);
    console.log('~~~~~~~~~~~~',arguments)
    for (let a of y){
        s += a
    }
    console.log(s);
}

add1(5,6,7,8,9)
#---------------------------------------------------------
Info: Start process (上午9:23:10)
5
[ 6, 7, 8, 9 ]
~~~~~~~~~~~~ { '0': 5, '1': 6, '2': 7, '3': 8, '4': 9 }
35
Info: End process (上午9:23:10)

ES6之前,arguments是唯一可变参数的实现。
ES6开始,不推荐,建议使用可变参数。为了兼容而保留。
注意,使用箭头函数,取到的arguments不是我们想要的(实际上是一些全局参数),如下

((x, ...args) => {
    console.log(args); // 数组
    console.log(x);
    console.log(arguments); //不是传入的值;
})(...[1, 2, 3, 4]);
#----------------------------------------------------------------
Info: Start process (上午9:30:50)
[ 2, 3, 4 ]
1
{ '0': {},
  '1': 
   { [Function: require]
     resolve: { [Function: resolve] paths: [Function: paths] },
     main: 
      Module {
        id: '.',
        exports: {},
        parent: null,
        filename: 'c:\\Users\\Administrator\\Desktop\\mage_edu\\52 前端开发之ES6入门1\\testjs\\node_75f5f327a41b0.tmp',
        loaded: false,
        children: [],
        paths: [Array] },
     extensions: { '.js': [Function], '.json': [Function], '.node': [Function] },
     cache: 
      { 'c:\\Users\\Administrator\\Desktop\\mage_edu\\52 前端开发之ES6入门1\\testjs\\node_75f5f327a41b0.tmp': [Object] } },
  '2': 
   Module {
     id: '.',
     exports: {},
     parent: null,
     filename: 'c:\\Users\\Administrator\\Desktop\\mage_edu\\52 前端开发之ES6入门1\\testjs\\node_75f5f327a41b0.tmp',
     loaded: false,
     children: [],
     paths: 
      [ 'c:\\Users\\Administrator\\Desktop\\mage_edu\\52 前端开发之ES6入门1\\testjs\\node_modules',
        'c:\\Users\\Administrator\\Desktop\\mage_edu\\52 前端开发之ES6入门1\\node_modules',
        'c:\\Users\\Administrator\\Desktop\\mage_edu\\node_modules',
        'c:\\Users\\Administrator\\Desktop\\node_modules',
        'c:\\Users\\Administrator\\node_modules',
        'c:\\Users\\node_modules',
        'c:\\node_modules' ] },
  '3': 'c:\\Users\\Administrator\\Desktop\\mage_edu\\52 前端开发之ES6入门1\\testjs\\node_75f5f327a41b0.tmp',
  '4': 'c:\\Users\\Administrator\\Desktop\\mage_edu\\52 前端开发之ES6入门1\\testjs' }
Info: End process (上午9:30:50)
参数解构

和Python类似,Js提供参数结构,依然使用了...来结构

const add = (x, y) => {console.log(x,y);return x+y};
console.log(add(...[100, 200]))
console.log('---------------------------------------------')
console.log(add(...[100, 200, 300, 3, 5, 3]))
console.log('---------------------------------------------')
console.log(add(...[100]))
#--------------------------------------------------------
Info: Start process (上午9:44:20)
100 200
300
---------------------------------------------
100 200
300
---------------------------------------------
100 undefined
NaN
Info: End process (上午9:44:20)

JS支持参数解构,不需要解构后的值个数和参数个数对应。

函数返回值

python 中可以使用 return 1,2 返回多值,本质上也是一个值,就是一个元组。Js中呢?

const add = (x, y) => { return x, y };
console.log(add(4, 100)); // 返回什么?
#-----------------------------------------------------
100   // 最后一个值;
表达式的值

类C的语言,都有一个概念——表达式的值
赋值表达式的值:等号右边的值。
逗号表达式的值:类C语言,都支持逗号表达式,逗号表达式的值,就是最后一个表达式的值。

a = (x = 5, y = 6, true);
console.log(a); // true

b = (123, true, z = 'test')
console.log(b)  // test
function c() {
    return x = 5, y = 6, true, 'ok';
}
console.log(c()); // ok

作用域
// 函数中变量的作用域
function test() {
    a = 100;
    var b = 200;
    let c = 300;
}
// 先要运行test函数
test()

console.log(a);
console.log(b); // 不可见
console.log(c); // 不可见,出不了函数块;

// 块作用域中变量
if (1) {
    a = 100;
    var b = 200;
    let c = 300;
}
console.log(a);
console.log(b);
console.log(c); // 不可见

function是函数的定义,是一个独立的作用域,其中定义的变量在函数外不可见。
var a = 100 可以提升声明,也可以突破非函数的块作用域。
**a = 100 隐式声明不能提升声明,在“严格模式”下会出错,但是可以把变量隐式声明为全局变量。建议少用。
let a = 100 不能提升声明,而且不能突破任何的块作用域。推荐使用。

严格模式:使用"use strict";,这条语句放到函数的首行,或者js脚本首行

function show(i, arg) {
    console.log(i, arg)

}
// 作用域测试
x = 500;
function fn() {
    let z = 400;
    {
        var o = 100; // var 作用域当前上下文
        show(1, x);
        t = 'free'; // 此语句执行后,t作用域就是全局的,不推荐
        let p = 200;
    }
    var y = 300;
    show(2, z);
    show(3, x);
    show(4, o);
    show(5, t);
    //show(6,p); // 异常,let出不来上一个语句块
    {
        show(7, y);
        show(8, o);
        show(9, t);
        {
            show(10,o);
            show(11,t);
            show(12,t);
        }
    }
}
// 先执行函数
fn()
//show(13,y); // 异常,y只能存在于定义的上下文中,出不了函数
show(14, t); // 全局,但是严格模式会抛异常

//show(15,o) // 看不到o,异常原因同y
show(16, z); // 变量声明提升,var声明了z,但是此时还没有赋值

var z = 10;
const m = 1
//m = 2 // 常量不可以重新赋值

2. 异常

抛出异常

Js的异常语法和Java相同,使用throw关键字抛出。
使用throw关键字可以抛出任意对象的异常

throw new Error('new error');
throw new ReferenceError('Ref Error');
throw 1;
throw 'not ok';
throw [1, 2, 3];
throw { 'a': 1 };
throw () => { };   // 函数
捕获异常

try...catch 语句捕获异常。
try...catch...finally 语句捕获异常,finally保证最终一定执行。
注意这里的catch不支持类型,也就是说至多一个catch语句。可以在catch的语句块内,自行处理异常;

try {
    //throw new Error('new error') ;
    throw new ReferenceError('Ref Error') ;
    //throw 1;
    //throw new Number(100);
    // throw 'not ok';
    // throw [1,2,3]'
    // throw {'a':1};
    throw () => { }; //函数
} catch (e) {
    console.log(e)
    console.log(typeof (e))
    console.log(e.name)
    console.log(e.constructor.name)
    console.log(4,e instanceof ReferenceError)
} finally {
    console.log('===end===')
}
#--------------------------------------------------------
ReferenceError: Ref Error
    at Object. (c:\Users\Administrator\Desktop\mage_edu\52 前端开发之ES6入门1\testjs\node_e7bb5c7ffa282.tmp:6:11)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:191:16)
    at bootstrap_node.js:612:3
object
ReferenceError
ReferenceError
4 true
===end===

你可能感兴趣的:(53.3-箭头函数、传参、作用域和异常处理)