函数参数作用域?

date
Dec 29, 2023
slug
scope-in-function-parameters
status
Published
tags
JavaScript
summary
scope in function parameters
type
Post
第一次看到这个概念我也是一脸懵逼,啥叫函数参数作用域啊?
通常来说我们知道有全局作用域,函数作用域和块级作用域,函数参数作用域又是什么?我们来看一个案例:
var x = 1
function foo(x, y = function(){x = 3; console.log(x)}) {
	console.log(x)
	var x = 2
	y()
	console.log(x)
}

foo();
console.log(x)
思考一下上述最终的输出是什么?
这里主要比较疑惑的点应该就是 y 这个函数里面改动的x 到底是哪个?全局的还是函数内部的呢?
其实两个都不是,最后输出的结果是:
	undefined
	3
	2
	1
这就有点意思了,第一个undefined是因为foo在被调用的时候没有传参数,所以打印undefined的,第二个是y 的函数打印,第三个打印的是foo 函数内部的x, 最后一个打印的是全局的变量x。那么y函数改变的到底是哪个x 呢?其实这里改变的是y前面的参数x, 在函数参数中有默认值的情况时,会形成一个函数参数作用域, 此时定义的默认函数参数的作用域就是这个函数参数作用域,更改的事前一个参数x, 我们可以将代码更改如下测试:
var x = 1
function foo(x, y = function(){x = 3; console.log(x)}) {
	console.log(x)
	// var x = 2
	y()
	console.log(x)
}

foo(4);
console.log(x)

//4
//3
//3
//1

我们发现foo 中最后打印的x 是3, 表明y 的默认参数函数更改的就是参数x 。
当然,上面的写法正常人应该都不会这么写,更多的是面试中专门考察这个知识点吧。如果我们将y的默认函数定义放在全局,那么就是正常的更改全局的x 了。
var x = 1
function bar() {x = 3; console.log(x)}
function foo(x, y = bar) {
	console.log(x)
	var x = 2
	y()
	console.log(x)
}

foo();
console.log(x)

//undefined
//3
//2
//3

所以出现所谓的函数参数作用域时,要注意它的条件,一个是默认参数,另外就是当前这个默认参数函数定义也是在参数内的,这样才会出现所谓的函数参数作用域。

© xk_wan 2021 - 2024