JavaScript基础 ----- 一些概念杂谈(2)

1.变量声明提升:

console.log(a);           //undefined
var a = 123;

此处的变量声明部分会被提升,赋值部分不会被提升(相当于没有给a赋值),所以输出undefined;

a = "hello";
console.log(a)     //hello
var a = 123;

改动之后,将a赋予一个值,这样才会有输出;

2.函数表达式提升:

console.log(a())     //直接报错
var a = function(){
    return "hello"
}
console.log(a())     //hello
var a = function b(){
    return 123
}
console.log(b())              //直接报错

注意: 函数表达式其实就是变量声明,只不过被赋值的部分是一个函数,所以提升的依然是声明部分,赋值部分不会被提升,否则会报错(也就是函数表达式不能提升);

3.函数声明提升:

console.log(add())      //hello
function add(){
    return "hello"
}
console.log(add())      //hello
function str(){
    return "hello"
}
console.log(str());        //world
function str(){
    return "world"
}
console.log(str())         //world
var a = 2;
function a(a){
    console.log(a)           //直接报错
}
a(3)
//函数声明和变量声明如果遇到同名,函数声明会被忽略(前者覆盖后者),所以会报错

函数声明会被全部提升,包括函数名,函数体;

如果碰到同名的函数声明,则后者会覆盖前者;如果遇到同名的变量声明,则前者会覆盖后者;

4.变量的重复声明:

var a = 1;
var a = 2;
console.log(a)      //2

当变量重复声明时,遵循就近原则,选择最近的进行输出;

5.立即执行函数(并不代表就是闭包):

(function(){
    var a = 2;
})()
console.log(a)         //直接报错

在这个立即执行函数中,不管传不传参数,函数体内的都是局部变量,所有最后会报错;

var a;              //这段代码就相当于在顶部声明了一个没有值的全局变量
(function(){
    a = 2;          //这里会改变全局变量的值
})()
console.log(a)       //2

在这个立即执行函数中,顶部的没有值的全局变量可写可不写;

var a;                //全局变量没有赋值
(function(a){
    a = 2;
})(a)
console.log(a)         //ubdefined

在这个立即执行函数中,传入了参数,此时的函数体内是一个新的作用域,里面是局部变量;

var a = 1;
//console.log(a)        //由于没有加分号,直接报错
(function(a){
    console.log(a)      //1
})(a)
console.log(a)          //1

根据作用域查找,立即执行函数体体内没有值,它就会向上查找,找到外面的值,进行输出;

(注意:在写立即执行函数之前,一定要加上分号,否则会报错;)

var a = 1;
(function(a){
    console.log(a)       //1
    a = 3;
    console.log(a)       //3
    var a = 2            
    console.log(a)       //2
})(a)
console.log(a)           //1

在这个立即执行函数体内,会形成一个单独的作用域,如果里面的变量赋予了值(相当于重新定义了一个变量),根据作用域查找,会找到自己本身的值进行输出;

(注意:函数体内的变量都是局部变量,函数体外的变量是全局变量)

var foo = {n:1};
(function(foo){
    console.log(foo.n)     //1
    foo.n = 2;             //没有重新定义一个变量,仅仅是将foo中的参数的值进行了改变,将参数的值变成了2
    console.log(foo.n)     //2     
})(foo)
console.log(foo.n)         //2

在这个立即执行函数中,仅仅是将foo这个对象中的参数的值进行了改变,并没有重新定义一个变量,所以最后输出的就是参数值已经改变了的对象;

var foo = {n:1};
(function(foo){
    console.log(foo.n)      //1
    foo.n = 2;
    console.log(foo.n)      //2
    var foo = {n:3}         //重新定义了一个变量,也就是形成一个新的作用域
    console.log(foo.n)      //3
})(foo)
console.log(foo.n)          //2

在这个立即函数中,就是重新定义了一个变量(相当于组成了一个新的作用域);

var foo = {n:1};
(function(foo){
    console.log(foo.n)      //1
    foo.n = 2;
    console.log(foo.n)      //2

    var foo = {n:3}         //重新定义了一个变量,也就是形成一个新的作用域
    console.log(foo.n)      //3
    foo.n = 4               //不论怎么改变参数的值,始终改变的是新的作用域的参数
    console.log(foo.n)      //4
})(foo)
console.log(foo.n)          //2

在这个立即执行函数中,已经形成了一个新的作用域,所以在下面无论怎么改动参数的值,只是改动的新的作用域中的参数,与原作用域无关;

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值