js作用域详解
js对象
众所周知,js的所有数据类型都是一个对象,例如:
var a = 1;
console.log
复制
声明a=1;a属于number类型,但是number类型又是number对象,有着以下方法:
interface Number {
/**
* Returns a string representation of an object.
* @param radix Specifies a radix for converting numeric values to strings. This value is only used for numbers.
*/
toString(radix?: number): string;
/**
* Returns a string representing a number in fixed-point notation.
* @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive.
*/
toFixed(fractionDigits?: number): string;
/**
* Returns a string containing a number represented in exponential notation.
* @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive.
*/
toExponential(fractionDigits?: number): string;
/**
* Returns a string containing a number represented either in exponential or fixed-point notation with a specified number of digits.
* @param precision Number of significant digits. Must be in the range 1 - 21, inclusive.
*/
toPrecision(precision?: number): string;
/** Returns the primitive value of the specified object. */
valueOf(): number;
}
复制
更多关于js对象,可查看:https://codeplayer.vip/p/j7sh5
同样,声明一个函数,其实该函数属于window对象的一个方法:
例如,声明一个atest方法:
function atest() {
console.log(1);
}
复制
通过console控制台,我们可以看到:
atest其实是一个window对象下的方法对象
var 局部变量作用域
var 声明一个对象,只作用域当前作用域以下。例如:
var a = 'test';
function b() {
console.log(a);
}
b();
复制
b函数可以成功调用上层作用域变量:
但是不能被上层作用域调用:
在顶级作用域下,var 声明变量,等于全局变量,被window对象接管:
<script>
var aaaa='666';
</script>
复制
定义全局作用域变量
直接定义不借助var,将定义全局变量,成为window对象的属性:
<script>
var a1='666';
a2='777';
function test() {
a3='888';
}
test();
console.log(a1,a2,a3);
</script>
复制
window对象直接赋值
window对象直接赋值方法,等同于不使用var 关键字定义:
<script>
window.a1='666';
window.a2='777';
function test() {
a3='888';
}
test();
console.log(a1,a2,a3);
</script>
复制
同理,可以使用window对象,直接赋值一个函数:
<script>
window.test = function () {
console.log(666);
};
test();
</script>
复制
变量作用域覆盖问题
通过var 关键字我们知道,当声明一个变量时,该变量可以被当前作用域,以及下层作用域访问 当下层作用域存在同名变量时,下层变量将覆盖上层变量:
<script>
var a=1;
function atest() {
btest();
function btest() {
var a=2;
console.log('btest:'+a);
}
console.log("atest:"+a);
}
atest();
</script>
复制
同时,在子作用域声明的方法,只能在当前作用域或者下层作用域调用
闭包函数,闭包作用域
闭包函数,又称匿名函数,例如:
<script>
(function () {
var a = 1;
console.log(a);
});
console.log(a);
</script>
复制
该段函数并没有运行,因为它没有被调用:
在声明函数之后,在后面增加括号即可实现声明后直接运行:
<script>
(function () {
var a = 1;
console.log(a);
})();
console.log(a);
</script>
复制
赋值闭包函数
可通过赋值一个闭包函数,使其可以二次调用:
<script>
var atest = function () {
console.log('hello')
};
atest();
atest();
</script>
复制
闭包函数增加括号并且赋值,变量将等于闭包函数返回的内容:(他将不再是一个函数,成为了一个函数返回值的对象)
<script>
var atest = function () {
var a='666';
console.log('hello');
return a;
}();
console.log(atest);
</script>
复制
闭包返回对象
可return一个json型对象,用于调用:
<script>
var atest = function () {
var a=1;
return{
a:2,
b:3,
c:function () {
//返回上层闭包声明的a变量
return a;
}
};
}();
console.log(atest.c());
console.log(atest.a);//输出闭包return的json对象属性
console.log(atest.b);
</script>
复制
在闭包函数中声明的变量,只能在闭包函数内的作用域,以及下层作用域使用,可通过return 对象中,通过return对象中声明的方法进行返回,使得上级作用域能成功访问到闭包作用域的变量
return作用域变量访问情况
在return作用域中的变量,外部可使用 匿名函数赋值的变量.变量名 方式访问,并且改值是引用型的,内部可使用 this.变量名方式
<script>
var atest = function () {
return{
a:2,
b:1,
getA:function () {
//返回上层闭包声明的a变量
return this.a;
},
getB:function () {
//返回上层闭包声明的a变量
return this.b;
}
};
}();
console.log(atest.getA());
console.log(atest.getB());
atest.a=7;
atest.b=6;
console.log(atest.getA());
console.log(atest.getB());
</script>
复制
总结
1:js万物皆对象,所有变量都是对象类型。
2:js的作用域是往下通用的,下层作用域可访问上层作用域的变量,并可修改值
3:js下层作用域变量和上层同名冲突时,下层作用域将覆盖上层变量,但上层作用域的访问不受影响
4:不适用var方法定义的变量,都属于全局变量,也就是window对象的属性
5:可通过window.方法定义全局变量
6:在顶层作用域声明的函数,其实就是window对象的方法
7:闭包在首次声明时,需要加括号自动调用,否则不能调用
8:闭包函数可通过赋值方法调用
9:闭包函数加括号 赋值到变量中,该变量将等于闭包的返回值
10:闭包返回值可返回一个对象,后期可使用 闭包赋值变量名.对象属性方法进行访问
11:闭包函数类var 的变量,只能在闭包函数下层或当前层使用,外部无法访问,但可以通过return 对象中,声明一个方法进行访问
12:闭包函数return的对象,都可以被 外部通过闭包赋值变量名.对象属性 应用,而对象本身也可以通过this.变量名,方式应用
- 点赞
- 收藏
- 关注作者
评论(0)