前端初學-變量提升

本人所有文章均為學習過程中的總結,不同程度地參考了互聯網上其他的文章,如果不正懇請指出,共同進步

變量提升

JS代碼的執行分為兩個階段
預解析階段

  • 變量名和函數聲明提升至當前作用域的最上方(只提升聲明,不提升賦值)

執行階段

  • 按照從上至下的順序執行語句

注意:

  • 變量與函數同名時,只提升函數,不提升變量
  • 函數同名時,都提升,后面的函數覆蓋前面的函數
  • 函數表達式只會提升變量名,賦值語句在執行階段按照順序執行
  • 變量提升是分塊的<script></script>
  • 條件是函數聲明能否被提升取決于瀏覽器,不推薦使用if(true){function(){}};

實例:

//js中沒有塊級作用域的說法,大括號并不會創建一個作用域

for(var i=0;i<5;i++){
    console.log(i);//0 1 2 3 4
}
console.log(i);//5 for循環外部依舊可以訪問到i

只有函數能夠創建作用域

變量提升是分作用域的

函數與變量同名只提升函數 但是變量賦值還是要執行的

代碼:

var num=10;
function num(){
    console.log(123);
}
num();

預編譯

function num(){
    console.log(123);
}
num=10;
num();//is not a function

函數與函數同名全部都會提升,但會以函數聲明順序進行覆蓋,后面覆蓋前面的

代碼:

function f1(){
    console.log('first');
}
function f1(){
    console.log('last');
}

預編譯:

function f1(){
    console.log('last')
}

函數表達式與變量提升方式相同,變量賦值不會被提升,但變量聲明會提升

代碼:

f1()//undefined
var f1=function(){
    console.log('f1');
}

預編譯:

var f1;//提升
f1();//調用 undefined
f1=function(){//賦值
    console.log('f1');
}

代碼:

function foo() {
    var num = 123;
    console.log(num); //123
}
foo();
console.log(num); //is not defined

預編譯:

function foo() {
    var num;
    num = 123;
    console.log(num); //?123
}
foo();
console.log(num); //is not defined

//is not defined 沒有定義
//undefined  定義了沒有賦值

代碼:

var scope = "global";
foo();
function foo() {
    console.log(scope); //undefined
    var scope = "local";
    console.log(scope); //local
}

預編譯:

var scope;
function foo(){
    var scope;
    console.log(scope); 
    scope = "local";
    console.log(scope); 
}
scope = "global";
foo();

//in 關鍵字 判斷某個對象中是否有某個屬性

代碼:

function f1(){
   if("a" in window){
       var a = 10;
   }
   alert(a);//undefined
}
f1();

預編譯:

function f1(){
   var a;
   if("a" in window){
       a = 10;
   }
   alert(a);//undefined
}
f1();

代碼:

if("a" in window){
    var a = 10;
}
alert(a); //10

預解析:

var a;
if("a" in window){
    a = 10;
}
alert(a);

代碼:

if(!"a" in window){
    var a = 10;
}
alert(a); // undefined

預解析:

var a;
if(!"a" in window){
  a=10;
}
alert(a);

代碼:

var foo = 1;
function bar() {
    if(!foo) {//此處提升了foo但是是undefined 判斷語句會轉為!undefined -->true
        var foo = 10;
    }
    alert(foo); //10
}
bar();

預解析:

var foo;
function bar(){
    var foo;//undefined
    if(!foo) {//!undefined --> ture
        foo = 10;//10
    }
    alert(foo); //10
}
foo = 1;
bar();

代碼:

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

Foo.getName = function() { alert(2); };

Foo.prototype.getName = function(){ alert(3); };

getName = function() { alert(4); };



getName(); //4

Foo().getName(); //1
  
getName(); //1

Foo.getName(); //2

new Foo.getName();//2 先執行Foo.getName()  new關鍵字無效

(new Foo).getName();//3 先執行new Foo創建對象

new Foo().getName(); //3 先執行new Foo()創建對象

new new Foo().getName(); //3 相當于 new Foo().getName() new關鍵字無效
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容