JS参数传递和作用域的易混淆点

一、JS传参的形式

JS中不管参数是基本数据类型还是引用数据类型,都是按值传递!!!
引用数据类型作为参数时,会将对象的内存地址值赋给形参

/**
 * 欲更改对象的名字
 */
function setName(obj) {
	obj.name = "小明";
}

var student = {
	name: "无名"
};

setName(student); // 最后结果为student.name == "小明"

上述代码中,调用setName()方法时将student对象作为参数传递,形参obj会被赋值为student(即将obj指向了student所指向的内存),此时对obj对象修改name属性就等同于修改student对象的name属性。
在这里插入图片描述


/**
 * 欲更改对象的名字,但增加了一条赋值语句
 */
function setName(obj) {
	obj = teacher; // 将teacher的内存地址赋值给obj
	obj.name = "小明";
}

var student = {
	name: "无名"
};

var teacher = {
	name: "无名";
}

setName(student); // 最后结果为student.name == "无名",teacher.name == "小明"

上述代码中,因为添加了一句obj = teacher,导致形参obj在指向student后又重新指向了teacher,所以修改并不会对student生效,而是对teacher生效。
在这里插入图片描述

二、JS的局部作用域

在函数体内以var形式声明的变量为局部变量,以非var形式声明的变量为全局变量。

/**
 * 分别以var形式和非var形式在函数内声明变量a、b、c
 */ 
function fn() {
	var a = 1;
	b = 2;
	this.c = 3;
}

fn();
console.log(b); // 2
console.log(c); // 3
console.log(a); // 报错,提示a未定义

JS有函数作用域,但没有块级作用域!!!
for和if都属于块级作用域,在其中定义的任何变量都属于全局变量。

for (var i = 0; i < 5; i++) {
	
}

console.log(i); // 能够正常输出5

三、JS的预解析机制

JS文件在运行的时候,会先进行预解析操作。
预解析时会从上至下将所有以var声明的变量初始化为undefined,将所有以function命名形式声明的函数初始化为自身(函数内部的变量遵循同样的预解析原则)

var name = "张三";

var age = 18;

function fn() {
	var time = "上午";
}

在这里插入图片描述


当变量与函数重名时,只有函数会被解析;当函数与函数重名时,只有最后一个函数会被解析。

var a = 10function a() {

}

/**
 * 只有a(arg)会被预解析
 */
function a(arg) {

}
发布了48 篇原创文章 · 获赞 4 · 访问量 6172

猜你喜欢

转载自blog.csdn.net/Knightletter/article/details/102687744