要想理解 …mapState,…mapStations这种对象扩展运算符写法,先来了解es6 对象展开符。
对象展开符号 …
本文我们介绍ES6的展开运算符。
展开运算符(spread operator)允许一个表达式在某处展开。
展开运算符在多个参数(用于函数调用)或多个元素(用于数组字面量)或者多个变量(用于解构赋值)的地方可以使用。
使用展开运算符
在函数调用中。
es5通过apply展开 自然而然想把applay和call做比较
js apply方法
apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性.这点和call类似
Function.apply(obj,args)方法能接收两个参数
obj:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function(args–>arguments)
数组的元素个数和函数的参数个数刚好一致
function hello(a, b, c) {
console.info(a);
console.info(b);
console.info(c);
console.info("this:"+this);
}
var args = ['光脚丫思考1', '光脚丫思考2', '光脚丫思考3'];
hello.apply(null, args);
// es6展开符传参 hello(...args);
如果数组的元素比函数的参数多了?或者少于函数的参数个数呢?是否仍然可以使用展开运算符呢?下面我们尝试下。
动态参数 : 多个参数合成数组
像是把剩余的参数聚拢到args这个参数中形成一个数组 而前面我们演示的几个示例则是把数组中的元素“展开”为各个对应的参数,两者刚好是反着来的。
function createBox(width, height, color, ...args) {
var message = `盒子的宽度=${width},高度=${height},颜色=${color}`;
console.log(message);//输出1 盒子的宽度=500,高度=200,颜色=red
console.log(args); //输出2 Array(2)["这里是盒子的描述信息1","这里是盒子的描述信息2"]
}
createBox(500, 200, "red", "这里是盒子的描述信息1", "这里是盒子的描述信息2");
// 像是把剩余的参数聚拢到args这个参数中形成一个数组
结论:在定义函数的时候使用运算符(…),会将传过来的多余参数聚拢到一起。
在调用函数的时候使用运算符(…),会把原本聚拢在一起的数据展开传递给各个参数。
js类
对象展开 对象展开符可以展开多个对象,组合成新的对象 。结论:新对象包含了合并的对象的所有属性。
展开对象
let user1={
name1:'思考1',
name2:'思考2'
}
let user2={
name3:'思考3',
name4:'思考4'
}
let user3={...user1,...user2};
console.log(user3);
// 结果:{
// name1: "思考1"
// name2: "思考2"
// name3: "思考3"
// name4: "思考4"
// }
如果2个对象包含了相同名称的属性,合并的时候会发生什么事情呢?
合并的对象中包含有同名的属性,则后面对象中的属性值覆盖前面的同名的属性值
let user11={
name1:'思考1',
name2:'思考2',
name3:'思考3',
}
let user22={
name3:'思考31',
name4:'思考4'
}
let user4={...user11,...user22};
console.log(user4);
//{name1: '思考1', name2: '思考2', name3: '思考31', name4: '思考4'},如遇相同属性,后面展开的会覆盖前面的
使用展开运算符可以复制对象!
通过展开运算符(…)拷贝对象,值类型的属性被深度拷贝了,而引用类型的属性只是做了浅拷贝
let user={
name:'zhq',
blog:'www.http.com'
}
let cloneUser={...user};
user.name='zhq1';
console.log(cloneUser); //{name: 'zhq', blog: 'www.http.com'}
//新复制的对象clonedUser.name属性值并没有随着user.name的改变而改变
//这可以证明2个对象并非引用的关系,而是互相独立的对象
//这说明对于引用类型的对象属性,只是做了一个浅拷贝,也就是把引用地址给复制了,而引用的对象并未复制,用的是同一个对象。
let user={
name:'zhq',
blog:'www.http.com',
address: {
city: "中国杭州"
}
}
let cloneUser={...user};
user.address.city='南京';//我们只是修改了简单类型的属性值,如果修改的属性值是一个对象
console.log(cloneUser); //{name: 'zhq', blog: 'www.http.com',address: {city: '南京'}}
//新复制的对象clonedUser.name属性值并没有随着user.name的改变而改变
//这可以证明2个对象并非引用的关系,而是互相独立的对象
vuex …mapState,…mapStations与对象扩展运算符使用的理解
引入 import {mapStations} from ‘vuex’
代码中的使用
import {mapState} from 'vuex'; //mapState返回一个object {home_city: ƒ mappedState()}
console.log(mapState);
export default{
name:'CityAddress',
computed:{
...mapState(['home_city','cur_alpha']) //mapState返回 {cur_alpha: ƒ mappedState(), home_city: ƒ mappedState() }
//以上即 ...{cur_alpha: ƒ mappedState(), home_city: ƒ mappedState() }
}
}
mapState([‘home_city’,‘cur_alpha’]) 进入vuex源码,一些理解见注释
function normalizeNamespace (fn) {
return function (namespace, map) {
if (typeof namespace !== 'string') { //namespace:['home_city','cur_alpha']
map = namespace;// map:['home_city','cur_alpha']
namespace = '';
} else if (namespace.charAt(namespace.length - 1) !== '/') {
namespace += '/';
}
return fn(namespace, map)
}
}
var mapState = normalizeNamespace(function (namespace, states) {//namespace:'',states:['home_city','cur_alpha']
var res = {};
if ((process.env.NODE_ENV !== 'production') && !isValidMap(states)) {
console.error('[vuex] mapState: mapper parameter must be either an Array or an Object');
}
normalizeMap(states).forEach(function (ref) {//states是数组
var key = ref.key;
var val = ref.val;
res[key] = function mappedState () {
var state = this.$store.state;
var getters = this.$store.getters;
if (namespace) {
var module = getModuleByNamespace(this.$store, 'mapState', namespace);
if (!module) {
return
}
state = module.context.state;
getters = module.context.getters;
}
return typeof val === 'function'
? val.call(this, state, getters)
: state[val]
};
// mark vuex getter for devtools
res[key].vuex = true;
});
return res //res结果 {cur_alpha:function mappedState () {...},home_city: ƒ mappedState()}
});
可以得出mapState([“home_city”,“cur_alpha”])结果 为一个对象 {cur_alpha:function mappedState () {…},home_city: ƒ mappedState()}
根据对象扩展运算符原理,可以把该对象展开,合并到computed对象中,computed对象包含了{cur_alpha: ƒ mappedState(), home_city: ƒ mappedState() }对象的所有属性 即实际computed对象
import {mapState} from 'vuex'; //mapState返回一个object {home_city: ƒ mappedState()}
console.log(mapState);
export default{
name:'CityAddress',
computed:{
cur_alpha:function mappedState () {...},
home_city: ƒ mappedState() //mapState返回 {cur_alpha: ƒ mappedState(), home_city: ƒ mappedState() }
//以上即 ...{cur_alpha: ƒ mappedState(), home_city: ƒ mappedState() }
}
}
mapMutations,mapGetters,mapActions应该也是同理
相关参考:https://blog.youkuaiyun.com/gjysk/article/details/124977525