函数中的return:
(1)return语句后面的代码 都不执行。
(2)return【只能】返回【一个】值
例子1:
如果同时return多个值,return【只】返回【最后一个值】
例子2:
如果想要得到看起来像是多个值,则 return【一个数组】
1.return,return true,return false相同点:都可以阻止后续代码执行
<script>
//1.加了return,之后的部分不执行
function fn1() {
return;
console.log('A不执行')
}
fn1();
//2.加了return false,之后的部分不执行
function fn2() {
return false
console.log('B不执行')
}
fn2();
//3.加了return true,之后的部分不执行
function fn3() {
return true
console.log('C不执行')
}
fn3();
//4.不加return,之后的部分执行
function fn4() {
console.log('D会执行')
}
fn4();
</script>
2.return,return true,return false不同点:
(1)return +内容;(写在函数里面,加上return+内容为了使得调用函数的时候有返回结果)
a. 把控制权返回页面
b. 打印调用该函数时,返回内容
c. 阻止后面内容的执行
e.g.1 return后面的部分不执行
<script>
function myFun() {
return 10;//打印调用函数的时候,返回10
console.log("byebye")//不执行
}
console.log(myFun());//10
</script>
e.g.2 return前面的部分执行
<script>
function myFun() {
console.log("Hello");//执行
return 10;//打印调用函数的时候,返回10
console.log("byebye");//不执行
}
console.log(myFun());//10
</script>
e.g.3 return返回内容
例子1:函数中return 内容
<script>
function fn() {
var a = 5;
var b = 8;
return a * b
}
console.log(fn());//40 5*8
</script>
例子2:Vue3后台管理项目的JS部分中(注释加了!!!的地方是关于return 内容的。此处只放了部分JS代码,仅供学习总结使用)
原数组.map(提供的函数)——创建一个由[原数组中的每个元素都调用一次**提供的函数**后的**返回值**组成] 的[新数组]。[!!!!不改变]原数组
比如:
const array1 = [1, 4, 9, 16];
const map1 = array1.map(x => x * 2);
console.log(map1);//[2, 8, 18, 32]
// map方法【不改变】原数组
console.log(array1);//[1, 4, 9, 16]
此处因为之前的res3.list中的每一项item中是没有item.sexLabel的,所以map处理完之后一定要return item(这个被return的item里是有item.sexLabel的)。
又因为将处理过的res3中的list给 新建的响应式变量list赋值
所以list.value中的内容里面,包括了处理完的res3.list中的每一项item中新增的item.sexLabel
<script>
import {
defineComponent,
getCurrentInstance,
onMounted,
ref,
reactive,
} from "vue";
export default defineComponent({
setup() {
// 新建响应式变量list,默认值是[]——存放【表的内容部分】的数据
let list = ref([]);
// 用[!!!getCurrentInstance()]方法拿到[!!!proxy]—— proxy类似Vue2中的this
const { proxy } = getCurrentInstance();
// 新建函数getUser
const getUser = async () => {
// 用proxy获取,main.js中的$api.去调用scr-api-api.js中的getUserData函数
// 用变量res3接收axios请求返回的数据
let res3 = await proxy.$api.getUserData();
console.log(res3);
// 将处理过的res3中的list给 新建的响应式变量list赋值
// 用map()对res3.list做处理
// item指res3.list中每一项
list.value = res3.list.map((item) => {
// 此处用item.sexLabel接收返回值
// - 如果item.sex是0,则item.sexLabel的值是"女"
// - 如果item.sex不是0,则item.sexLabel的值是"男"
item.sexLabel = item.sex === 0 ? "女" : "男";
// !!!!!!返回添加了item.sexLabel的item去res3.list中
// !!!!因为之前的item中是没有item.sexLabel的
return item;
});
};
(2)return ;
把控制权返回页面
相当于return undefined
e.g.
<script>
function myFun() {
console.log("Hello");//执行
return;//打印调用函数的时候,返回undefined
console.log("byebye");//不执行
}
console.log(myFun());//undefined
</script>
(3)return false:【只对return false所在的当前函数有效,不影响其他函数的执行】
事件处理函数添加return false:
a. 阻止默认的事件行为(e.g.1点了a链接就会自动跳转 e.g.2 点了提交表单按钮,表单就会提交)
b. 阻止后面内容的执行
e.g.1 return false阻止了点击a链接就会自动跳转到对应地址
只是弹出'点击了a',不会跳转到百度首页
<body>
<a href="https://www.baidu.com">百度</a>
<script>
var a = document.querySelector('a');
a.onclick = function () {
alert('点击了a');
// return false;//点击a之后,不会跳转到百度首页,只会弹出'点击了a'
//也就是阻止了默认事件:本来点击a链接就会自动跳转到对应地址
}
</script>
</body>
VS
如果以上代码不加return false:会先弹出'点击了a',再跳转到百度首页
阻止表单提交(return false特有),阻止之后内容的执行
(4)return true: (写在函数里面)
a. 返回正常处理的结果/操作成功 =之后调用该函数的时候,返回结果是true,就可用根据这个true来判断
b. 阻止后面内容的执行
例子1:
Vue3中用new Proxy实现双向绑定/响应式的代码中
此处new Proxy中的set里面本来是不需要返回值的,因为set函数的主要作用是修改目标对象的属性值,而非返回任何值
但是,如果需要在实现修改属性值之后执行一些特定的操作,就在set中添加一个return true表示设置成功
<script>
const data = { text: '你好' }
const obj = new Proxy(data, {
get(target, key) {
bucket.add(effect)
return target[key]
},
set(target, key, newValue) {
target[key] = newValue
bucket.forEach(fn => fn())
//此处的return true是表示操作成功
return true
}
})
function effect() {
console.log('调用')
document.body.innerText = obj.text
}
const bucket = new Set()
effect()
setTimeout(() => {
obj.text = 'hello world'
}, 1000)
</script>
例子2:
Vue3后台管理项目中的main.js中:创建了命名函数checkRouter 用来判断【当前url上访问的path】是否和【router.getRoutes()这个【所有路由记录的数组】每一项】相等(未完。。待补)
目标效果:
- 1. 如果url输入的路由【有】匹配的页面,则跳转到对应匹配页面
- 2. 如果url输入的路由【没有】匹配的页面,则应该自动跳转到/home页面
以下代码中:
else if (!checkRouter(to.path)) {中的 !checkRouter(to.path)的值如果要是true,则checkRouter(to.path)的值是false,即对应的是checkRouter函数中【checkRouter函数中[即将要进入的路由的path]【没有】匹配[当前有的页面路由]时,return false】
main.js中的部分代码
// 新增命名函数,函数名称是checkRouter——用于判断访问的路由是否为permission.js中的【当前有的页面路由】
// 形参path——接收下面router.beforeEach里面else if (!checkRouter(to.path))传入的【实参to.path】=【即将要进入的路由的path】
function checkRouter(path) {
// **router实例.getRoutes()——[获得包含【所有路由记录的数组】**
// 此处的router是【import router from './router/index.js'引入的router实例】
console.log(router.getRoutes());
// 新增变量hasCheck——其值是【[所有路由记录的数组的每一项]和[当前url上访问的path]相等的长度】
// **数组.filter(数组中每一项item=>关于对数组中每一项item的筛选条件)——返回存放 满足数组中每一项item的筛选条件的所有元素 的新数组**
// 此处item指——router.getRoutes()这个【所有路由记录的数组】每一项
// item.path(这个是【所有路由记录的数组】每一项的path) == path(这个是接收【当前url上访问的path】的形参path)
const hasCheck = router.getRoutes().filter(item => item.path == path).length
// (1)如果hasCheck变量存在,即[当前url上访问的path]和[所有路由记录的数组每一项]【有】匹配
if (hasCheck) {
// return指返回值——如果想要调用函数有返回的结果的话,必须要在函数内添加return
// 之后调用命名函数checkRouter的时候,可根据【【有】匹配的返回结果是true】来判断
return true;
// (2)如果hasCheck变量存在,即[当前url上访问的path]和[所有路由记录的数组每一项]【没有】匹配
} else {
// return指返回值——如果想要调用函数有返回的结果的话,必须要在函数内添加return
// 之后调用命名函数checkRouter的时候,可根据【【没有】匹配的返回结果是false】来判断
return false;
}
};
// 全局前置路由守卫router.beforeEach
// 参数1【必填】 to: 即将要进入的路由
// 参数2【必填】 from: 当前导航正要离开的路由
// 参数3【选填】 next: 放行
router.beforeEach((to, from, next) => {
// 调用vuex中的mutations
// commit参数1:mutations中调用的方法名称——调用src-store-index.js中的getToken,使得getToken函数中获取token
store.commit("getToken");
// 新建变量token1,其值是src-store-index.js中的state中的token变量的值
// 【变量token1要存在】——必须是在Login.vue页面【点击了登录按钮】——因为这样才可以获得res7中的token,然后Login.vue中的store.commit("setToken", res7.token);传递res7.token给src-store-index.js中的setToken(state, val4)。然后这个val4=res7.token。setToken函数中给state中的token赋值为个val4=res7.token
const token1 = store.state.token;
// (1)如果变量token1【不存在】=【没有】在Login页面点击登录按钮 并且 即将要进入的路由to的name【不是】"login"=【没】token也想进入登录页后面的页面
if (!token1 && to.name !== "login") {
// 就让其跳转到name是"login"的路由
// **其他的next("/login") 或 next(to) 等 ——中断当前导航,执行新的导航**
next({ name: "login" });
// (2)如果 即将要进入的路由to的name【是】"login"
// 此处调用命名函数checkRouter,并且传入【实参to.path】=【即将要进入的路由的path】
// 这边要想!checkRouter(to.path的值是true,则[checkRouter(to.path)的值是false】=【checkRouter函数中[即将要进入的路由的path]【没有】匹配[当前有的页面路由]】
} else if (!checkRouter(to.path)) {
// 就让其跳转到name是"home"的路由
// **其他的next("/login") 或 next(to) 等 ——中断当前导航,执行新的导航**
next({ name: "home" });
// (3)如果变量token1【存在】=在Login页面【点击了】登录按钮 并且 即将要进入的路由to的name【是】"login"
} else {
// 往下跳转=放行
// **next()——放行**
next();
}
})
例子3:
抽象以下以上例子2方便理解
如果一个函数需要返回值,则需要在函数中添加return
如果函数中添加的是
比如 :
function fn(){if(条件1){
//满足条件1,return true
return true
}else{
//不满足条件1,return true
return false
}
}
则之后调用fn()的时候,会根据以上的 满足条件1的情况是true,不满足条件1是false,进行判断
比如
if(fn()){
此处代码要想走进来——fn()就得是true,即此时function fn中条件1得成立
}
比如:
(1)当前变量a的值是10
下面if(fn2(10))给fn2传入值是10
function(a)中的参数a的值就是10
然后进入function fn2(a){}这个命名函数中的if(a==1)这边的判断
因为此时a的值是10,不满足a==1
所以function fn2(a){}这个命名函数中走到return false
所以if(fn2(a))中的fn2(a)的值是false
所以if(fn2(a))这个里面走入else
<script>
//形参a接收下面调用fn2()时候的实参
function fn2(a) {
if (a == 1) {
return true
} else {
return false
}
}
// 调用命名函数fn2,传实参10
if (fn2(10)) {
console.log("return true对应的结果")
} else {
console.log("return false对应的结果")
}
</script>
对应控制台效果:
走入的是if(fn2(a))这个里面的else
(2)当前变量a的值是1
下面if(fn2(1))给fn2传入值是1
function(a)中的参数a的值就是1
然后进入function fn2(a){}这个命名函数中的if(a==1)这边的判断
因为此时a的值是1,满足a==1
所以function fn2(a){}这个命名函数中走到return true
所以if(fn2(a))中的fn2(a)的值是true
所以if(fn2(a))这个里面走入if(fn2(a)){}里面
<script>
//形参a接收下面调用fn2()时候的实参
function fn2(a) {
if (a == 1) {
return true
} else {
return false
}
}
// 调用命名函数fn2,传实参1
if (fn2(1)) {
console.log("return true对应的结果")
} else {
console.log("return false对应的结果")
}
</script>
对应控制台效果:
走入的是if(fn2(a)){}里面