JavaScript嚴格模式說明及變量函數(shù)的提升day05

JavaScript嚴格模式說明及變量函數(shù)的提升

一.嚴格模式的簡單說明

1.函數(shù)調(diào)用的方式和this的丟失

(1)函數(shù)的調(diào)用方法:

  • 001 以對象的方法來調(diào)用 this--->對象
  • 002 以普通的函數(shù)的方法來調(diào)用 this--->window
  • 003 以構(gòu)造函數(shù)的方式來調(diào)用 new Function() this---->指內(nèi)部新創(chuàng)建的對象
  • 004 以函數(shù)上下文的方式來調(diào)用(call|apply) this--->綁定的第一個參數(shù) 如果不傳遞參數(shù)那么默認指向window

解決this的丟失問題:

eg:
<script>
//var getId = document.getElementById('demo');//以對象的方法來調(diào)用
   /* var getId = document.getElementById;//  getId代表是一個函數(shù)
    console.log(getId('demo')); */      //報錯    (以普通函數(shù)的方法來調(diào)用)this的丟失問題!

//document.getElementById('demo');
//getId('demo');

//原因:document.getElementById的內(nèi)部實現(xiàn)中使用到了this,內(nèi)部的this始終指向document
//以普通函數(shù)的方式來調(diào)用,內(nèi)部的this指向的是window

//解決問題:
//將this綁定給document
var getId = (function (func){
   return function (){
       //return func.apply(document,arguments);
       return func.call(document,arguments[0]);
    }
})(document.getElementById);
console.log(getId('demo'));

var getTagName = (function (func){
    return function (){
        //return func.apply(document,arguments);
        return func.call(document,arguments[0]);
    }
})(document.getElementsByTagName);
console.log(getTagName('div')[0]);
</script>

2.嚴格模式的簡單說明

嚴格模式:

  • js有兩種開發(fā)模式:嚴格模式和非嚴格模式(默認)

  • 在嚴格模式下:會對代碼進行更嚴格的檢查.以前在默認情況下可能不會出錯或者是靜默失敗或者是可以使用的特性,那么會在嚴格模式下會直接報錯.

開啟嚴格模式:

在當前作用域的最頂端加上一個命令字符串:'use strict';

兼容性問題:

  • 部分瀏覽器不支持嚴格模式.
  • 如果該引擎支持嚴格模式,那么當檢測到'use strict';這個字符串的時候會自動開啟嚴格模式,如果不支持那么就忽略.

嚴格模式的使用注意:

  • 01 所有的變量必須使用var聲明
  • 02 禁止使用with
  • 03 禁止使用八進制
  • 04 禁止使用callee | caller
  • 05 禁止使用eval和arguments作為標識符
  • 06 在if語句中不能聲明函數(shù)
  • 07 在函數(shù)的聲明中不能出現(xiàn)同名的參數(shù)
  • 08 在對象中不能出現(xiàn)同名的屬性
  • 09 在嚴格模式下arguments的表現(xiàn)略微的不同
  • 10 不能刪除全局變量
  • 11 this的指向被修正

建議:使用嚴格模式來開發(fā).

eg:

<script>
'use strict';
//01 所有的變量必須使用var聲明
   /* b = 'testB';
    console.log(b);*/

//02 禁止使用with
   /* var obj = {
        name:'張三'
    }
    with(obj){
        name:'李四'
    }
    console.log(obj);*/

//03 禁止使用八進制
//八進制說明:如果數(shù)值前面是0,那么默認以八進制的方式來處理
//如果數(shù)字中出現(xiàn)超過8的數(shù)字,那么以十進制的方式來處理

/*   var n = 027;
console.log(n);*/

//04 禁止使用callee | caller
//callee 指向自己    用于匿名函數(shù)的遞歸中
//caller 指向調(diào)用者
  /*  function func01(){
        console.log(func01.caller);
    }
    function func02(){
        func01();
    }
    func02();

console.log((function (n){
    if(n == 1){
        return 1;
    }
    return arguments.callee(n-1)+n;
})(11));*/

//05 禁止使用eval和arguments作為標識符(變量|對象|函數(shù)的名稱)
  /*  var arguments = 'demo';
    console.log(arguments);

//06 在if語句中不能聲明函數(shù)
if(true){
    function test(){
        console.log('test');
    }
    test();
}*/

//07 在函數(shù)中不能出現(xiàn)同名的參數(shù)
//默認情況下,如果函數(shù)中出現(xiàn)同名的形參,那么后面一個會把前面一個覆蓋
/*function foo(a,b,a){
    /!*var a = 1;
    var b = 2;
    var a = 3;*!/
    console.log(a+b+c);//8
}
foo(1,2,3);*/

//08 對象中也不能出現(xiàn)同名的參數(shù) (默認情況下衣形,后面的會覆蓋前面的)

  /*  var o = {
        name:'張三',
        name:'李四'
    }
    console.log(o.name);*/

//09 不能刪除全局變量
//默認情況下刪除失敗岁经,但是不會報錯 (靜默失敗)

   /* var obj = '我是測試的魔鏡';
    console.log(delete obj);
    console.log(obj);*/

    //10 argumnets在嚴格模式下和非嚴格模式下表現(xiàn)不一致的
    //默認情況下再悼,在函數(shù)內(nèi)部重新設置形參的值鳍置,arguments也會跟著改變迂求,他們是共享的
    //嚴格模式下梆惯,他們是相互獨立的

function demoTest(stringTest){
    console.log(stringTest);//String
    console.log(arguments);//

    stringTest = '我是一個字符串';
    console.log(stringTest);
    console.log(arguments);
}
demoTest('String');

function demoTestObj(obj){
    console.log(obj);
    console.log(arguments);

    obj = {age:23};
    console.log(obj);
    console.log(arguments);
}
demoTestObj({});
console.log('+++++++++++++++');

//11 修正了this的指向
//默認情況下,指向的是window
//嚴格模式下,指向的是undefined;

var name = 'window的name';
function func01(){
    console.log(this);
}

func01();//undefined
var o = {
    name:'張三',
    showName:function (){
        console.log(this);
    }
}

o.showName();//張三
var o2 = {
    name:'李四'
}
o.showName.call(null);//null
//默認情況下不傳參數(shù)密似,那么this指向window辞居,嚴格模式下指向的是undefined
// 如果傳遞的參數(shù)是null,那么this的值就是null

</script>

3.嚴格模式的書寫格式

  1. 位置: 當前作用域的最頂端
  2. 書寫格式:

① 雙引號和單引號無所謂

② 必須全部都是小寫字符

③ 分號可以被省略

④ 必須是10個字符

eg:

<script>
//    "use strict";
//    "use strict"      //省略分號  正確
//    use strict;       //不加引號 錯誤
//    'use strict';     //單引號   正確
//    "use  strict";     //錯誤的
//    "use strict ";    //錯誤的
//    "use Strict";

var a = 'testA';
b = 'testB';
</script>

4.嚴格模式的作用域說明

作用域:
js中的作用域分為兩種:全局作用域(例如script作用域內(nèi) )和函數(shù)作用域

作用域: 變量起作用的范圍

塊級作用域:

  • js沒有塊級作用域
  • 注意:try...catch例外(有塊級作用域)

函數(shù)作用域:
在js中只有函數(shù)可以創(chuàng)建作用域;

詞法作用域:

  • 詞法作用域:當代碼寫好之后,它的作用域就已經(jīng)確定了
  • 動態(tài)作用域:作用域范圍在程序運行的時候確定;
  • js本身是詞法作用域(with + eval + try...catch 除外);

詞法作用域的訪問規(guī)則:

首先先在自己的作用域中查找,如果找到那么就直接使用,如果沒有找到那么就在上一級的作用域中查找,重復這個過程

eg:

<script>
var a = 'testA';
function test01(){
    var a  = 123;
    var b = '456';
    console.log(a);

    function test02(){
        console.log(b);
        console.log(a);
    }
    test02();
}

test01();
console.log(a);
</script>
<script>
function hi(){
    console.log('hi');
}
var hello = function hi(){
    console.log('hello');
}
hello();//hello
hi();//hi   //當賦值之后,就不能再直接使用名稱來調(diào)用

</script>
<script>
var a = 'testA';
function add(n){
    //函數(shù)作用域
}
</script>
<script>
for(var i = 0;i<10;i++) {
    console.log(i);
}
console.log(i,'------------');

try{
    a();
}
catch (e){
    console.log(e);
}
console.log(e,'______________');//報錯
</script>

eg2:

<script>
'use strict';               //位置1 作用范圍是全局
function demo1(){
    'use strict';               //位置2 demo1
    a = 'testA';
}
function demo2(){
    'use strict';               //位置3 demo2
    b = 'testB';
}

'use strict';                   //位置4 無效
demo1();
demo2();

</script>

二.變量和函數(shù)的提升

1. 變量和函數(shù)的提升

01 js預先解析處理    變量和函數(shù)的提升  把變量和函數(shù)提升在作用域頂端

02 具體執(zhí)行

eg:

<script>

console.log(b);//報錯
console.log(a);//undefined

var a = 'testA';//var a; a= 'testA';
console.log(a);//testA;

</script>
<script>
function demo(){
    console.log('demo');
}

console.log(typeof demo);//function
demo();//demo
</script>

注意點:

  • 01 變量和變量同名的情況, 后面的變量會把前面的同名變量覆蓋
  • 02 函數(shù)和函數(shù)名, 后面的函數(shù)會把前面的同名函數(shù)覆蓋
  • 03 變量和函數(shù)同名情況 , 前后關(guān)系無所謂

eg:

//01 變量和變量同名的情況 
<script>
var num = 10;
function demo1(){
    num = 20;
    console.log(num);//20
    demo2();//30
    console.log(num);//30
}

function demo2(){
    num = 30;
    console.log(num);//
}
demo1();

//02函數(shù)和函數(shù)名 
var a = 'testA';
console.log(a);//testA

var a = 'testB';
console.log(a);//testB

//03變量和函數(shù)同名情況
demo1();

function demo1(){
    console.log('demo1')
}
demo1();

function demo1(){
    console.log('demo2');
}

demo1();

//04變量和函數(shù)同名情況
var str = '我是一個字符串';
str = function (){
    console.log('我的同桌是美女')
}
console.log(str);//function()...
</script>

2.變量的提升作用于不同的作用域

eg:

<script>
var num = 10;
function func(){
    console.log(num);//10
    num = 20;
}
console.log(num);//10
func();//10
console.log(num);//20


   /* var num;
    function func(){
        console.log(num);//undefined
        num = 20;
    }
    num = 10;
    console.log(num);//10
    func();//10
    console.log(num);//20*/
</script>

3.函數(shù)表達式的提升

函數(shù)表達式: 那么在提升的時候僅僅只會把var 變量名提升

eg:

<script>
var demo;
console.log(demo);//undefined
demo();//報錯

   demo = function (){
        console.log('11111111');
    }

</script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末楷怒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瓦灶,更是在濱河造成了極大的恐慌鸠删,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贼陶,死亡現(xiàn)場離奇詭異刃泡,居然都是意外死亡,警方通過查閱死者的電腦和手機碉怔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門烘贴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人撮胧,你說我怎么就攤上這事桨踪。” “怎么了芹啥?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵锻离,是天一觀的道長铺峭。 經(jīng)常有香客問我,道長汽纠,這世上最難降的妖魔是什么逛薇? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮疏虫,結(jié)果婚禮上永罚,老公的妹妹穿的比我還像新娘。我一直安慰自己卧秘,他們只是感情好呢袱,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著翅敌,像睡著了一般羞福。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蚯涮,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天治专,我揣著相機與錄音,去河邊找鬼遭顶。 笑死张峰,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的棒旗。 我是一名探鬼主播喘批,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼铣揉!你這毒婦竟也來了饶深?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤逛拱,失蹤者是張志新(化名)和其女友劉穎敌厘,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體朽合,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡俱两,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了旁舰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锋华。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖箭窜,靈堂內(nèi)的尸體忽然破棺而出毯焕,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布纳猫,位于F島的核電站婆咸,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏芜辕。R本人自食惡果不足惜尚骄,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望侵续。 院中可真熱鬧倔丈,春花似錦、人聲如沸状蜗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽轧坎。三九已至宏邮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缸血,已是汗流浹背蜜氨。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留捎泻,地道東北人飒炎。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像族扰,于是被迫代替她去往敵國和親厌丑。 傳聞我的和親對象是個殘疾皇子定欧,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容