JavaScript面向對象中的嚴格模式我的分享

嚴格模式

嚴格模式的概念

  • 所謂嚴格模式就是對JavaScript中的一種限制性更強的方式.
  • 屬於代碼的一種強制規則,來規範代碼的格式簡單的說就是必須按照嚴格模式的規則書寫代碼不然就會報錯
  • 嚴格模式修正了一些引擎難以優化的錯誤: 一樣的代碼有些時候嚴格模式會比非嚴格模式下更加快

開啓嚴格模式

全局開啓嚴格模式

  • 就是在全部代碼以前,定義一個不會賦給任何變量的字符串

示例代碼:數組

// 開啓嚴格模式 - 做用於全局做用域
  'use strict';
// 定義一個變量 - 不使用var關鍵字

b = '皮卡丘';
console.log(b);

控制檯示例圖:
圖片描述app


變量

禁止意外建立變量

  • 沒有開啓嚴格模式時編輯器

    • 在調用該變量時,不會報錯
    • 解釋器會自動補全 var關鍵字
  • 開啓嚴格模式時函數

    • 在調用該變量時,會報錯

示例代碼:優化

// 開啓嚴格模式
'use strict';

var v = '舒克,貝特';
console.log(v);


function fn() {
    /* 在非嚴格模式:
        * 在函數做用域中定義變量 - 不適用var關鍵字時JavaScript就會自動將其提高爲全局變量
     */
    w = '貓和老鼠';
    console.log(w);
}
fn();
console.log(w);

控制檯效果對比圖:
圖片描述this

靜默失敗轉爲異常

  • 靜默表示既不報錯也不顯示任何效果
  • 在嚴格模式下,靜默失敗會轉爲報錯

示例代碼:spa

// 開啓嚴格模式
'use strict';

const v = 12.19;// 定義常量
v = 1993;// 從新賦值

console.log(v);

控制檯效果圖:
圖片描述prototype

禁用delete關鍵字

  • 注意: 注意: 嚴格模式下禁用delete關鍵字 - 是針對刪除變量,而不是數組元素的對象屬性的
  • 在非嚴格模式下,對變量使用delete 會靜默失敗
  • 在嚴格模式下,對變量使用delete 會報錯

示例代碼:code

// 開啓嚴格模式
'use strict';

// 注意: 嚴格模式下禁用delete關鍵字 - 是針對刪除變量,而不是數組元素的對象屬性的

// 定義一個全局變量
var v = '皮卡丘';
console.log(v);

delete  v;//刪除全局變量v
console.log(v);

//定義一個數組
var arr = [1,2,3,4,5];
delete arr[0];
console.log(arr);


// 定義一個對象
var obj = {
    name : '花花世界'
};
delete obj.name;
console.log(obj.name);

控制檯效果對比:
圖片描述對象

對變量名的限制

  • 注意: 嚴格模式下不容許把保留字當變量名稱 - 由於在ES6中保留字會變成關鍵字

示例代碼:

// 開啓嚴格模式
'use strict';

/*
    注意: 嚴格模式下不容許把保留字當變量名稱
      * 由於在ES6中保留字會變成關鍵字
 */
var static = '一花一世界';
console.log(static);

控制檯效果對比圖:
圖片描述


對象

不可刪除的屬性

  • 在非嚴格模式下,使用delete去刪除不可刪除的屬性時,會靜默失敗

示例代碼:

// 開啓嚴格模式
'use strict';

/* 使用delete 刪除Object對象的原型屬性 */
delete Object.prototype;
/* 在調用Object對象的原型屬性 */
console.log(Object.prototype);

控制檯效果對比圖:
圖片描述

屬性名必須惟一

  • 當開啓嚴格模式時 - 對象具備相同名稱的屬性時,編輯器報錯(不是運行時報錯)
  • 當非嚴格模式時 - 對象具備相同名稱的屬性時,後面的會覆蓋前面的屬性名

示例代碼:

// 開啓嚴格模式
 'use strict';

var obj = {
    /*
        當開啓嚴格模式時 - 對象具備相同名稱的屬性時,編輯器報錯(不是運行時報錯)
        當非嚴格模式時 - 對象具備相同名稱的屬性時,後面的會覆蓋前面的屬性名
     */
    name : '皮卡丘',
    name : '亞奇洛貝'
};
console.log(obj.name);

控制檯效果對比圖:
圖片描述

只讀屬性的賦值

  • 在非嚴格模式下,對只讀屬性進行重新賦值,會靜默失敗
  • 在嚴格模式下,對只讀屬性進行從新賦值,會報錯

示例代碼:

// 開啓嚴格模式
'use strict';

/* 定義一個對象 */
var obj = {
    name : '皮卡丘'
};
/* 獲取指定屬性的屬性描述符 - 將屬性改成只讀屬性 */
var result = Object.getOwnPropertyDescriptor(obj,'name');
console.log(result);
// 定義對象obj的只讀屬性
Object.defineProperty(obj,'age',{
    value : 18
});
// 針對只讀屬性進行修改操做
// obj.age = 80;
// console.log(obj.age);

delete obj.age;
console.log(obj.age);

控制檯效果對比圖:
圖片描述

不可擴展的對象

  • 在非嚴格模式下,對不可擴展的對象添加新屬性,會靜默失敗
  • 在嚴格模式下,對不可擴展的對象添加新屬性,會報錯

示例代碼:

// 開啓嚴格模式
'use strict';

/* 定義一個空對象 */
var obj = {};
// 設置對象obj是一個不可擴展的對象
Object.preventExtensions(obj);
// 爲對象obj新增屬性
obj.name = '皮卡丘';
/* 調用對象 */
console.log(obj);

控制檯效果對比圖:
圖片描述


函數

參數名必須惟一

  • 在非嚴格模式下,參數名容許重複,後面匹配的參數會覆蓋以前匹配的參數
  • 在嚴格模式下,參數名重複時,編輯器會提示報錯,運行時也會報錯

示例代碼:

// 開啓嚴格模式
'use strict';

/* 定義一個函數 */
function fn(a,a,b) {
    console.log(a + a + b);
}
/* 調用函數並傳遞參數 */
fn(1,2,3);

控制檯效果對比圖:
圖片描述

arguments的不一樣

  • 嚴格模式下 - arguments對象獲取參數的值與形參有關的

    • 若是局部變量與形參名相同 - 就根據就近原則進行獲取
  • 嚴格模式下 - arguments對象獲取參數的值與形參無關的

示例代碼:

// 開啓嚴格模式
'use strict';

function fn(value) {
    var value = '皮卡丘';
    console.log(value);// 調用結果爲 皮卡丘 - 就近原則
    /*
        * 嚴格模式下 - arguments對象獲取參數的值與形參有關的
          * 若是局部變量與形參名相同 - 就根據就近原則進行獲取
        * 嚴格模式下 - arguments對象獲取參數的值與形參無關的
     */
    console.log(arguments[0]);// 調用結果爲 皮卡丘 , 嚴格模式下調用結果爲 皮皮蝦
}
fn('皮皮蝦');

控制檯效果對比圖:
圖片描述

arguments對象的callee( )方法

  • 在非嚴格模式下,callee()方法表示當前調用的函數
  • 在嚴格模式下,arguments對象將沒法調用callee()方法,會報錯

示例代碼:

// 開啓嚴格模式
'use strict';

/* 定義一個函數 */
function fn() {
    console.log(arguments.length);
    /* 將callee()方法返回 */
    return arguments.callee;
}
fn();

控制檯效果對比圖:
圖片描述

函數聲明的限制

  • 在嚴格模式下, 函數的定義只能在全局做用域與函數做用域(不能再塊級做用域定義函數)
  • 在非嚴格模式下,函數能夠在任何做用域下進行定義

示例代碼:

// 開啓嚴格模式
'use strict';

// 在全局做用域
function fn() {
    // 在函數做用域
    function n() {}
}
// 在嚴格模式下, 函數的定義只能在全局做用域與函數做用域(不能再塊級做用域定義函數)
for (var i=0; i<10; i++){
    //ECMAScript 6新增 - 存在着塊級做用域
    var v = 100;
    function f() {
        console.log('這是一個皮卡丘');
    }
}
console.log(v);
f();

控制檯對比效果圖:
圖片描述


eval()函數

增長eval()做用域

  • 在非嚴格模式下,eval()函數建立的變量能夠在其餘位置進行調用
  • 在嚴格模式下,eval()函數建立的變量只能在當前eval()函數中使用,其餘位置調用會報錯

示例代碼:

// 開啓嚴格模式
'use strict';

// 在嚴格模式下,增長eval做用域 - eval()函數定義的變量只能在當前eval()函數中使用
eval('var v = "一花一世界";');
// 在全局做用域中調用變量 - 則會報錯
console.log(v);// 非嚴格模式下調用結果爲 一花一世界

控制檯效果對比圖:
圖片描述


arguments對象

禁止讀寫

  • 在非嚴格模式下,使用 eval 或 arguments 作爲標識符(變量名、函數名、對象名)時,會靜默失敗
  • 在嚴格模式下,使用 eval 或 arguments 作爲標識符(變量名、函數名、對象名)時,會報錯

示例代碼:

// 開啓嚴格模式
"use strict";

/* 使用 eval 或 arguments 作爲標識符 */
eval = 17;
arguments++;
++eval;
var obj = { set p(arguments) { } };
var eval;
try { } catch (arguments) { }
function x(eval) { }
function arguments() { }
var y = function eval() { };
var f = new Function("arguments", "'use strict'; return 17;");

代碼效果圖:
圖片描述


this關鍵字

抑制this

  • 在非嚴格模式下,在函數使用apply()方法或call()方法來調用函數時,使用null或undefined來代替this的指向對象時,this會指向全局對象
  • 在嚴格模式下,在函數使用apply()方法或call()方法來調用函數時,使用null或undefined來代替this的指向對象時,會報錯

示例代碼:

// 開啓嚴格模式
'use strict';


/* 定義全局變量 */
var v = 100;

/* 定義函數 */
function fn() {
    console.log(this.v);
}


/* 使用appl()方法或call()方法來調用函數 */
fn.call(obj);// this 指向全局對象

控制檯效果對比圖:
圖片描述

相關文章
相關標籤/搜索