关于箭头函数

如题.
1.情况:

const getters = {
  sidemenu: state => state.app.sidemenu,
}

与如下这样写的区别?

const getters = {
  sidemenu: state.app.sidemenu,
}

2.情况:
(state = {}) => state
这种写法如何解释?

=========================================

感谢各位!
解释的都非常详细!

阅读 2.5k
4 个回答

第一种是在需要时再去获取值
第二种是创建对象时就设定了值

还可以借助 ts 来查看他们的差异
图片.png图片.png
可以看到他们的 sidemenu 字段的类型是完全不一样的,一个是函数类型,一个则是 setate.app.sidemenu 的值的类型

至于 (state = {}) => state 则是一个有默认参数的箭头函数罢了

情况1

const getters = {
  sidemenu: state => state.app.sidemenu,
}

getters.sidemenu 是一个函数,通过 getters.sidemenu(state) 调用,它的作用是接收一个参数并返回该参数的 app.sidemenu 属性

const getters = {
  sidemenu: state.app.sidemenu,
}

getters.sidemenu 是一个值,在运行到 sidemenu: state.app.sidemenu 这一语句时确定值,这时会延着作用域链寻找 state 变量,然后取app.sidemenu赋值给自己

举个实例

const state = {
  app: {
    sidemenu: 1
  }
}
const state1 = {
  app: {
    sidemenu: 2
  }
}
const getters1 = {
  sidemenu: state => state.app.sidemenu,
}
const getters2 = {
  sidemenu: state.app.sidemenu,
}

getters1.sidemenu(state1) // 返回 2
getters1.sidemenu(state) // 返回 1
getters2.sidemenu` // 返回 1

情况 2

(state = {}) => state 是在箭头函数 (state) => state 的基础上为参数加了默认值,举个例子:

const getSelf = (state = {}) => state;
getSelf(); // 返回 {}

第 1 个问题

// 预先定义一个 case
const state = {
    app: {
        sidemenu: "global state app side menu"
    }
}

const getters1 = {
    // 这里的 state 是参数传入的,传入的啥就是啥
    sidemenu: state => state.app.sidemenu,
}

const getters2 = {
    // 这里的 state 作用域范围内的,提前定义好的
    sidemenu: state.app.sidemenu,
}

// 调用方式不一样,上面那个需要参数
const r1 = getters1.sidemenu(state);
const r11 = getters1.sidemenu({ app: { sidemenu: "another one" } });

// 下面这个不需要参数,也不是函数,是以属性的方式访问的
const r2 = getters2.sidemenu;

console.log(r1);    // global state app side menu
console.log(r11);   // another one
console.log(r2);    // global state app side menu

不过我觉得你可能是想问的是另一种情况,与箭头函数无关(没使用 this 的情况下,普通函数也是一样的)。我觉得需要关注的是是属性的 getter 访问器,比如

const getters1 = {
    // getter 访问器
    get sidemenu() { return state.app.sidemenu }
}

const getters2 = {
    sidemenu: state.app.sidemenu,
}

console.log(getters1.sidemenu); // global state app side menu
console.log(getters2.sidemenu); // global state app side menu

这样一来,二者的访问形式相同,才有比较的必要。

区别在于,一个可以动态获取 state.app.sidemenu,另一个不能,比如代码

console.log(getters1.sidemenu); // global state app side menu
console.log(getters2.sidemenu); // global state app side menu

// 这里改变了数据源 state.app.sidemenu 的值
state.app.sidemenu = "new side menu";

console.log(getters1.sidemenu); // new side menu
console.log(getters2.sidemenu); // global state app side menu

不存在优劣,根据业务需要来选择。

第 2 个问题

(state = {}) => state,这里的 state 是个参数,= {} 是参数的默认值,合起来叫默认参数

const test = (state = {}) => state;
console.log(test("abc"));   // abc
// 可以不给参数 state,它是默认值 {}
console.log(test());        // {}

虽然题目里有箭头函数,但是实则和箭头函数一点关系都没有,换成普通函数也没啥影响:

const getters = {
  sidemenu: function(state){
    return state.app.sidemenu
  }
}

(如果对普通函数有所了解的话,凭此就能正确地理解第一种情况中两段代码(而不是两种写法)的差异所在);

function fn(state = {}){
  return state
}

就是普通函数的写法要长一点。

第二种情形,是 ES6 语法中声明函数默认值的方式,在此之前我们写默认值要这样:

function fn(state){
  // 如果调用方没有给参数,使用默认参数 {}
  if(state == undefined) {
    state = {}
  }
}

很显然,有了默认参数语法之后,写起来要简单得多。而且聪明的 IDE 可以据此推断函数参数的大致类型,不知道执行引擎会不会也这样搞,如果会的话,那些写法规范的代码执行速度可能会更上一层楼。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题