在javascript中关于变量与函数的提升

一、简介

在javascript中声明变量与函数的执行步骤:

1、先预解析变量或函数声明代码,会把用var声明的变量或者函数声明的代码块进行提升操作

2、然后再进行执行操作

关于变量声明提升:用var声明的变量提升,其只是变量提升了,而没有进行赋值的提升

二、关于变量与函数提升的注意点

1、变量提升的代码演示

var a = 10;
console.log(a);//10
console.log(b);// undefined
var b = 20;
console.log(b);//20

/*变量提升演示*/
var a; // 变量提升  只提升不赋值
var b;// 变量提升  只提升不赋值
a = 10; // 赋值操作
console.log(a);// 10
console.log(b);// 由于b还没有赋值,所以 undefined
b = 20; // 赋值操作
console.log(b);// 20

2、两函数名相同的情况下,后面的函数声明会覆盖前面的函数声明

var a = 10;
var b = 20;
 function funcName() {
     console.log(a);
 }

function funcName(){
     console.log(b);
 }
 funcName();// 20

/*变量与函数提升演示*/
    var a;
    var b;
    function funcName(){//后面的覆盖了前面的函数声明
        console.log(b);
    }
    a = 10;
    b = 20;
    funcName(); // 20

3、变量名与函数名相同的情况下,只会提升函数声明,而不提升变量声明

var a = 10;
 function funcName() {
     console.log(a);
 }
funcName();// 10
var funcName = '字符串';
 console.log(funcName);// 字符串
funcName();// Uncaught TypeError:funcName is not a function

/*变量与函数提升演示*/
var a;
function funcName() {
    console.log(a);
}
a = 10;
funcName();// 10
var funcName = '字符串';// 与函数同名变量声明忽略提升
console.log(funcName);//  字符串
//由于重新给funcName赋值,funcName是一个字符串了,而不是函数,无法调用
console.log(typeof funcName);// string
funcName();// Uncaught TypeError:funcName is not a function

4、用函数表达式声明函数时,函数声明提升,只会提升变量,而不是整个函数提升

say()//Uncaught TypeError: say is not a function
var say = function() {
    console.log('hello');
};

/*函数声明演示*/
var say;// 函数表达式声明函数,只提升变量
say();// Uncaught TypeError: say is not a function
say = function () {
    console.log('hello');
};

5、变量与函数的提升是分作用域的

function sayHello() {
    console.log('hello');// hello
    function sayHi() {
       console.log(a); // 10
       console.log(b); // undefined
    }
    sayHi();
    var b = 10;
}
var a = 10;
sayHello();
console.log(b);// Uncaught ReferenceError: b is not defined

/*函数与变量提升演示*/
function sayHello() {
    function sayHi() {
        console.log(a); // 10 a是全局变量,函数内部可以访问
        console.log(b); // undefined
    }
    var b;
    console.log('hello');// hello
    sayHi();//调用时b还没有赋值,所以undefined
    b = 10;
}
var a;
a = 10;
sayHello();// 函数调用
// b 是局部变量,函数之外无法访问
console.log(b);// Uncaught ReferenceError: b is not defined

三、关于函数提升与变量提升的测试题

第一题

function show() {
    var a = 123;
    console.log(a); //?
}
show();
console.log(a); //?

第二题

var str = "string";
show();
function show() {
    console.log(str); //?
    var str = "字符串";
    console.log(str); //?
}

第三题

if("a" in window){
    var a = 10;
}
console.log(a); // ?

第四题

function show(){
    if("a" in window){
        var a = 10;
    }
    console.log(a); // ?
}
show();

第五题

var a = 1;
function show() {
    if(!a)
    {
        var a = 10;
    }
    console.log(a); //?
}
show();

第六题

function Foo() {
    getName = function(){ alert(1); };
    return this;
}
Foo.getName = function() { alert(2); };
Foo.prototype.getName = function(){ alert(3); };
var getName = function() { alert(4); };
function getName(){ alert(5); }

Foo.getName(); // ?
getName(); // ?
Foo().getName(); // ?
getName(); // ?
new Foo.getName(); // ?
new Foo().getName(); // ?
new new Foo().getName(); // ?

四、 答案

第一题

function show() {
    var a = 123;
    console.log(a); //123
}
show();
console.log(a); //Uncaught ReferenceError: a is not defined(未定义)
/*变量提升演示*/
function show() {
    var a;
    a = 123;
    console.log(a); //123
}
show();
console.log(a); //Uncaught ReferenceError: a is not defined(未定义)

第二题

var str = "string";
show();
function show() {
    console.log(str); //undefined
    var str = "字符串";
    console.log(str); //字符串
}
/*变量提升演示*/
var str;
function show() {
    var str;
    console.log(str); //undefined
    str = "字符串";
    console.log(str); //字符串
}
str = "string";
show();

第三题

if("a" in window){
    var a = 10;
}
console.log(a); // 10
/*变量提升演示*/
var a;// 全局变量
if("a" in window){ // true
    a = 10;
}
console.log(a); // 10

第四题

function show(){
    if("a" in window){
        var a = 10;
    }
    console.log(a); // undefined
}
show();
/*变量提升演示*/
function show(){
    var a;// 局部变量 不是全局变量
    if("a" in window){// false
        a = 10;
    }
    console.log(a); // undefined
}
show();

第五题

var a = 1;
    function show() {
        if(!a)
        {
            var a = 10;
        }
        console.log(a); // 10
    }
    show();
    
    /*变量提升演示*/
var a;
function show() {
    var a;
    if(!a)// Blooean(undefined) == false  !a == true
    {
        a = 10;
    }
    console.log(a); // 10
}
a = 1;
show();

第六题

function Foo() {
    getName = function(){ alert(1); };
    return this;
}
Foo.getName = function() { alert(2); };
Foo.prototype.getName = function(){ alert(3); };
var getName = function() { alert(4); };
function getName(){ alert(5); }

Foo.getName(); // 2
getName(); // 4
Foo().getName(); // 1
getName(); // 1
new Foo.getName(); // 2
new Foo().getName(); // 3
new new Foo().getName(); // 3

/*函数与变量提升演示*/
function Foo() {
    getName = function(){ alert(1); };//
    return this;
}
var getName;
//function getName(){ alert(5); }//被 getName = function() { alert(4); };覆盖
Foo.getName = function() { alert(2); };//构造函数的静态方法
Foo.prototype.getName = function(){ alert(3); };// 原型方法
getName = function() { alert(4); };

Foo.getName(); // ? 2  构造函数调用自己的静态方法
//getName = function(){ alert(1); }; 覆盖 getName = function() { alert(4); };
getName(); // ? 4 window.getName();  5已经被4覆盖
Foo().getName(); // ? 1 Foo()中this指向window,方法调用把getName = function() { alert(4); };用getName = function(){ alert(1); };覆盖
getName(); // ? 1 window.getName() 就是调用getName = function(){ alert(1); };
new Foo.getName(); // ? 2 Foo.getName() 构造函数调用自己的静态方法   new 2 == 2
new Foo().getName(); // ? 3 (new Foo()).getName() 对象调用原型方法
new new Foo().getName(); // ? 3  new 3 == 3

五、源码链接

https://github.com/350469960/OS/blob/master/javascript/promotion.md

在javascript中关于变量与函数的提升的更多相关文章

  1. JavaScript 中对变量和函数声明提前的演示样例

    如题所看到的,看以下的演示样例(能够使用Chrome浏览器,然后F12/或者右键,审查元素.调出开发人员工具,进入控制台console输入)(使用技巧: 控制台输入时Shift+Enter能够中途代码 ...

  2. 关于Javascript中声明变量、函数的笔记

    一.概念 1.变量声明 在JavaScript中,变量一般通过var关键字(隐式声明,let关键字声明除外)进行声明,如下通过var关键字声明a,b,c三个变量(并给其中的a赋值): var a=1, ...

  3. JavaScript 中对变量和函数声明的“提前”

    变量声明“被提前” JavaScript 的语法和 C .Java.C# 类似,统称为 C 类语法.有过 C 或 Java 编程经验的同学应该对“先声明.后使用”的规则很熟悉,如果使用未经声明的变量或 ...

  4. (转)JavaScript 中对变量和函数声明的“提前(hoist)”

    变量声明“被提前” JavaScript 的语法和 C .Java.C# 类似,统称为 C 类语法.有过 C 或 Java 编程经验的同学应该对“先声明.后使用”的规则很熟悉,如果使用未经声明的变量或 ...

  5. JavaScript 中对变量和函数声明的“提前(hoist)”

    hoist vt.升起,提起; vi.被举起或抬高; n.起重机,升降机; 升起; <俚>推,托,举; 这篇文章不讲英语,但是对于某些英语单词找不到很好的翻译,一上来就列出“hoist”这 ...

  6. 关于javascript中变量及函数的提升

    javascript中变量以及函数的提升,在我们平时的项目中其实还是挺常用的,尤其是大型项目中,不知不觉就会顺手添加一些变量,而有时候自己的不小心就会酿成一些不必要错误,趁有时间整理一下自己对于js中 ...

  7. JavaScript 中的变量命名方法

    三种命名方法 在程序语言中,通常使用的变量命名方法有三种:骆驼命名法(CamelCase),帕斯卡命名法(PascalCase)和匈牙利命名法. 依靠单词的大小写拼写复合词的做法,叫做"骆驼 ...

  8. [转]Javascript中的自执行函数表达式

    [转]Javascript中的自执行函数表达式 本文转载自:http://www.ghugo.com/javascript-auto-run-function/ 以下是正文: Posted on 20 ...

  9. 深入理解javascript中的立即执行函数(function(){…})()

    投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-06-12 我要评论 这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是 ...

随机推荐

  1. Incompatible pointer types assigning to 'id<>' from 'Class'错误

    实例变量在类方法中被使用 原因:静态方法访问了非静态变量属性(.h中声明的那些属性),就是类方法访问了成员变量

  2. Thinking in scala (3)----求平方根

    采用“牛顿法”求一个数的平方根 object sqrt { def main(args:Array[String])={ println( sqrt(args(0).toDouble)) }  def ...

  3. 外部SRAM实验,让STM32的外部SRAM操作跟内部SRAM一样(转)

    源:外部SRAM实验,让STM32的外部SRAM操作跟内部SRAM一样 前几天看到开源电子论坛(openedv.com)有人在问这个问题,我特意去做了这个实验,这样用外部SRAM就跟用内部SRAM一样 ...

  4. java实现——007用两个栈实现队列

    import java.util.Stack; public class T007 { public static void main(String[] args) { Queue q = new Q ...

  5. iOS 之 系统机制

    iOS 沙盒 iOS 8 之 新特性 iOS 操作系统整体架构层次讲解

  6. Grid (read-only) objects and methods (client-side reference)获取子表单对象的一些方法 Crm 2016

    https://msdn.microsoft.com/en-us/library/dn932126.aspx#BKMK_GridControl Updated: November 29, 2016 A ...

  7. UVa 507 - Jill Rides Again

    题目大意:最大和子序列问题.由于具有最大和的子序列具有一下性质:第一项不为负数,并且从第一项开始累加,中间不会有和出现负数,因为一旦有负数我们可以抛弃前边的部分以得到更大的子序列和,这将会产生矛盾. ...

  8. PHP 中 static 和 self 的区别

    使用 self:: 或者 __CLASS__ 对当前类的静态引用,取决于定义当前方法所在的类: 使用 static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的.也可以称之为" ...

  9. Visual Studio 2015的安装与基本使用

    为什么要使用Visual Studio 2015? 它是中文的.界面友好.自动补全.实时语法错误提示(上图中波浪线部分).单步调试……最重要的社区版是免费的!所以你不必再使用破解的.老旧的的不兼容现代 ...

  10. 数据库基础-INDEX

    http://m.oschina.net/blog/10314 一.引言 对数据库索引的关注从未淡出我的们的讨论,那么数据库索引是什么样的?聚集索引与非聚集索引有什么不同?希望本文对各位同仁有一定的帮 ...