作用域
全局作用域
局部作用域 :函数作用域
var name = 'xm';
function fn(argument) {
var sex = 'male';
}
console.log(sex);
fn();
console.log(sex) 这里会发生报错 sex变量是未定义的
全局变量可以在局部作用域中访问到,局部变量 在全局作用域中访问不到。
在js中没有块级作用域
{ } 如果有的话就叫做块级作用域 比如
if (true) {
var name = 'xm';
}
for (var i = 0;) {
}
如果有块级作用域 里面的变量 生也萧何 败也萧何
变量对象
var name = 'xm';
function fn(argument) {
var sex = 'male';
function fn2(argument) {
var age = 18;
fn2.age
}
fn.sex
fn.fn2
}
window.name
window.fn
name
fn
console.log(window.name === name);
console.log(window.fn === fn);
fn
console.log(window.person);
console.log(window.person);结果是undefined 未定义的属性
作用域链
var name = 'xm';
function fn() {
var name = 'xh';
var sex = 'male';
function fn2() {
var name = 'xhei';
var age = 18;
}
}
从最里层作用域,通过作用域链可以访问到最外层的变量,
内层变量的优先级高于外层变量的优先级。
js解析机制-预解析
预热
var name = 'xm';
var age = 18;
function fn() {
var name = 'xh';
var age = 10;
console.log(name);
}
fn();
很正常打印的结果是 xh,接着看下面
js解析过程 (预解析, 是对 var 声明的变量 和 function 函数进行预解析需要注意的是 argument 和局部变量同等对待)
预解析逐行解读代码
var name = 'xm';
var age = 18;
function fn(argument) {
console.log(name);
var name = 'xh';
var age = 10;
}
fn();
这里打印的的结果是undefined 原因
window
name = undefined
age = undefined
function fn(argument) {
console.log(name);
var name = 'xh';
var age = 10;
}
fn
name = undefined
age = undefined
argument = undefined
先预解析,window作用域下 name=undfined,age=undefined, fn,
在fn 作用域下预解析 name=undefined,age = undefined,argument= undefined
然后逐行执行代码 so 返回的结果是 undefined
解析详解 js 作用域问题1
console.log(a);
var a = 1 ;
返回结果 undefined
console.log(a);
a = 1 ;
这里会发生报错 没有var js不能正常预解析
js作用域问题2
console.log(a);
var a = 1;
console.log(a);
function a() {
console.log(2);
}
console.log(a);
var a = 3;
console.log(a);
function a() {
console.log(4);
}
console.log(a);
a();
这里返回的结果是
function a() {
console.log(4);
}
1
1
3
3
报错
分析:在预解析中 现对var 和function 进行预解析,当var声明的变量和 function声明的变量相同发生命名冲突时 ,预解析结果保留function 当function 与后面的function 命名发生冲突(名称相同) ,预解析结果保留最后一个function ,
在逐行执行过程中a()返回的结果会报错的原因是,在a()前面 执行的var a = 3 所以此时的变量a 是常用类型 3 然后会报错。
3.JS作用域问题三 (预解析是分标签进行的)
<script>
var a = 1;
</script>
<script>
console.log(a);
</script>
当第一个标签预解析完成和执行完成 ,然后才对第二个script进行预解析然后执行
作用域问题4 还是很有意思的
var a =1;
function fn() {
console.log(a);
var a =2;
}
fn();
console.log(a);
返回的是undefined 和 1
var a = 1;
function fn() {
console.log(a);
a = 2;
}
fn();
console.log(a);
结果是1 2 分析当执行到里面的 console.log(a) 此时的fu函数作用域里面 是没有局部变量a的 a=2 是全局变量,所有此时 console.log(a) 的a通过作用域链向上查找返回结果1;
全局变量中的console.log(a)返回结果是2 ;原因当执行fn()之后 此时的a全局变量的值是a 如果不执行fu() 直接打印全局变量中的 console.log(a);结果还是1 。
例子3
var a = 1;
function fn(a) {
console.log(a);
a = 2;
}
fn();
console.log(a);
执行的结果是undefined和1 分析:fu(a) 中的a 是参数 在预解析中解析的结果是undefined 所以第一结果是undefined,fu 里面的a=2修改的是局部变量参数a的数值 对全局变量中的a=1 没有影响,所以全局变量中的console.log(a)结果是1
例子4
var a = 1;
function fn(a) {
console.log(a);
a = 2;
}
fn(a);
console.log(a);
执行结果是1 1 分析 fn(a) 是按值传递的 fn里面的 console.log(a);
a的值是全局变量的值。a=2 是把参数的值变成2 与全局变量a=1 没有影响 全局变量中console.log(a); 结果是 1