一、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 = 10;
function a() {
}
/**
* 只有a(arg)会被预解析
*/
function a(arg) {
}