在javascript中關於變量與函數的提高

javascript中關於變量與函數的提高

1、簡介

javascript中聲明變量與函數的執行步驟:javascript

一、 先預解析變量或函數聲明代碼,會把用var聲明的變量或者函數聲明的代碼塊進行提高操做java

二、 而後再進行執行操做git

 

關於變量聲明提高:var聲明的變量提高,其只是變量提高了,而沒有進行賦值的提高github

 

2、關於變量與函數提高的注意點

一、 變量提高的代碼演示函數

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測試

 

 

二、 兩函數名相同的狀況下,後面的函數聲明會覆蓋前面的函數聲明this

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(); // 20spa

 

 

三、 變量名與函數名相同的狀況下,只會提高函數聲明,而不提高變量聲明prototype

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 functionorm

 

 

四、 用函數表達式聲明函數時,函數聲明提高,只會提高變量,而不是整個函數提高

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');
};

 

 

五、 變量與函數的提高是分做用域的

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

 

 

3、關於函數提高與變量提高的測試題

第一題

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(); // ?

 

 

4、 答案

第一題

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

 

 

 5、源碼連接

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

相關文章
相關標籤/搜索