函数作用域
全局作用域:在函数外面定义的变量,在页面的任何地方都可以访问
函数作用域:函数会新开辟一个作用域空间,等函数执行完以后,函数会把这个作用域关闭,并且把变量也进行销毁
function getName() {
let uname = "奥特曼"
var age = "20"
console.log(age);
console.log(uname); //奥特曼
}
getName()
console.log(age); // age is not defined
console.log(uname); //uname is not defined
块级作用域
if(true){
let uname = '奥特曼'
var age="20"
console.log(age); //20
console.log(uname); // //奥特曼
}
console.log(age); //20
console.log(uname); //uname is not defined
块级作用域:被 { } 包裹住的代码就是块级作用域( 包括函数中的{ }、if、for ),在{ }中定义的变量,用let声明的变量 在{ } 外部同样访问不到 ,但是用var 声明的可以访问
var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。
if(true){
let uname = '奥特曼'
var age="20"
console.log(age); //20
console.log(uname); // //奥特曼
}
console.log(age); //20
console.log(uname); //uname is not defined
练习题
- 函数的值传递只与最后定义的值有关,与全局变量,全文变量无关。
var a=1;
a=2;
var a=3;
function add(a){
var a=4;
a=5;
var a=6;
console.log(a);
}
add(a);//6
console.log(a);//3
全局变量无法突破函数内的范围,除非通过函数调用和return。
function add(){
a=5;
}
console.log(a);//ReferenceError: a is not defined
function add(){
a=5;
}
add();
console.log(a);//5
全局变量无法突破函数内的范围,除非通过函数调用和return。
var a=[2];
function add(){
console.log(a);
}
add();//[2]
a=[1];
add();//[1]
console.log(a);//[1]
var bb = 1;
function aa(bb) {
bb = 2;
console.log(bb);
};
aa(bb);//2(属于传值,不会改变原来的数值)
console.log(bb);//1
var bb = 1;
function aa() {
bb = 2;(此时属于传值,改变bb的值)
console.log(bb);
};
aa(bb);//2
console.log(bb);//2
预编译,function声明的a提前声明,值为函数体,var关键字声明的b提前声明,值为undefined,所以在函数执行前调用时,a输出a,b输出undefined。
a();
functon a(){
console.log('a');
}
b();
var b =function b(){
console.log('b');
}
//a undefined
函数的预编译,在函数执行前,内部的用var关键字声明的变量a提前声明了,值为undefined,当遇到重名变量时,会优先使用自身拥有的变量,如果fn内没有a变量,才会使用外部的变量。
console.log(a);//2
console.log(b);//undefined
var a= b=2;
console.log(a);//2
console.log(b);//2
fn();
function fn(){
console.log(a);//undefined,函数体内有a,var a声明提前undefined
console.log(b);//函数体内无b,寻找上层,有b,输出2
var a = 90;
}
这题考的变量的声明,在函数内用var关键字声明的变量是局部变量,不影响全局变量,没有用var关键字声明的变量是全局变量,因为函数内声明的a变量重名,所以函数内的声明的a变量覆盖了原先的a变量,所以a输出的都是6,因为b也没有用var声明,所以b也是全局变量,在函数外可以访问,而c是用var声明的,局部变量在函数外不能访问,所以报错c未定义。
var a = 3;
console.log("未定义的e",e);//undefined
var e = 9;
function fun1 () {
var c = b = a = 6;
d = 8;
console.log("函数里面的a",a);//6
console.log("函数里面的b",b);//6
console.log("函数里面的c",c);//6
console.log("函数里面的d",d);//8
}
fun1();
console.log("外界的a",a);//6
console.log("外界的b",b)//6;
console.log("外界的c",c);//报错
console.log("外界的d",d);//8
请列举JavaScript中函数声明的几种方式。
答案:1.函数声明
function funName(){}
2.函数表达式(函数字面量)
var f = new function (){}
3.函数构造法
var fun = Function()
this指向,getCount被user调用,所以this指向的是user,返回1, 变量func接收的是一个函数体,所以当func执行的时候,this指向的是window,而window里没有count这个属性,所以返回的是undefined。
var user ={
count:1,
gerCount:function(){
return this.count;
}
}
console.log(user.getCount);
var func = user.getCount;
console.log(func());
考this指向,obj.fun1()返回的是一个函数体,这个函数体在对象外被调用,this指向的是window,而window里有name这个属性,所以输出the window。
var name = 'the window';
var obj = {
name:'My Object',
fun1:function () {
return function () {
return this.name;
}
}
}
alert(obj.fun1()());
考点this指向,如果在一个函数前面那加上new关键字来调用,那么其实就是会自动创建一个链接到该函数的原型prototype的新对象,所以此时this绑定的是这个新对象,不再是全局,所以不会修改全局中的a。
var a = 'one';
function func() {
this.a = 'two';
}
var b = new func();
console.log(a);//one
var a = 'one';
function func() {
this.a = 'two';
}
func();
console.log(a);//two,调用后改变值
使用连等赋值时,先看y = typeof x,x此时未赋值,因此是undefined,此时y被赋值为undefined,之后x=y,x被赋值为undefined。
var y = 1,x = y = typeof x;
console.log(x);//undefined
执行函数中var a=b=3可分解为b=3,var a=b,由于b前没有var重新声明,因此是全局变量b被赋值3,之后函数内局部变量a被赋值,第一对console.log输出的a是局部变量a,b是全局变量b,两者都未定义,第三对console.log输出的是全局变量a,b。因此结果为:undefined,undefined,3,3,undefined,3。
var a,b;
(function(){
console.log(a);
console.log(b);
var a=b=3;
console.log(a);
console.log(b);
})();
console.log(a);
console.log(b);
js解释器会在所有代码执行前先查找所有函数,因此可以在函数声明前调用函数。并且后面定义的函数将覆盖前面同名的函数。
var m= 1, j = k = 0;
function add(n) {
console.log("进入add1");
return n = n+1;
}
y = add(m);
console.log("y的值为",y);
function add(n) {
console.log("进入add2");
return n = n + 3;
}
z = add(m);
console.log("z的值为",z);