JavaScript語言精粹

JavaScript嚴格模式

"use strict" 指令在 JavaScript 1.8.5 (ECMAScript5) 中新增。目的是指定代碼在嚴格條件下執行。
嚴格模式經過在腳本或函數的頭部添加 use strict; 表達式來聲明。
ESM中的模塊默認都是嚴格模式。html

爲何使用嚴格模式:
消除Javascript語法的一些不合理、不嚴謹之處,減小一些怪異行爲;* 消除代碼運行的一些不安全之處,保證代碼運行的安全;算法

  • 提升編譯器效率,增長運行速度;
  • 爲將來新版本的Javascript作好鋪墊。

"嚴格模式"體現了Javascript更合理、更安全、更嚴謹的發展方向,包括IE 10在內的主流瀏覽器,都已經支持它,許多大項目已經開始全面擁抱它。瀏覽器

嚴格模式的限制:
一、不容許使用未聲明的變量: a = 3;
二、不容許刪除變量:delete a安全

**`delete` 操做符**用於刪除對象的某個屬性。若是對象包含該屬性,那麼該屬性就會被移除。它不會觸及原型鏈中的任何對象。刪除對象的屬性可能會讓來自原型鏈中的屬性透現出來。
 
 在嚴格模式下,若是對一個變量的直接引用、函數的參數或者函數名使用delete操做,將會拋出語法錯誤([`SyntaxError`]。所以,爲避免嚴格模式下的語法錯誤,必須以`delete object.property`或`delete object['property']`的形式使用delete運算符。
 
 與一般的見解不一樣,`delete`操做符與直接釋放內存**無關**。內存管理 經過斷開引用來間接完成。

三、不容許變量重名:
四、因爲一些安全緣由,在做用域 eval() 建立的變量不能被調用:eval ("var x = 2"); alert (x);
五、.....完整內容點擊標題連接......ide

JavaScript垃圾回收

引用
垃圾回收算法主要依賴於引用的概念。在內存管理的環境中,一個對象若是有訪問另外一個對象的權限(隱式或者顯式),叫作一個對象引用另外一個對象。例如,一個Javascript對象具備對它原型的引用(隱式引用)和對它屬性的引用(顯式引用)。函數

在這裏,「對象」的概念不只特指 JavaScript 對象,還包括函數做用域(或者全局詞法做用域)。ui

引用計數垃圾收集算法
這是最初級的垃圾收集算法。此算法把「對象是否再也不須要」簡化定義爲「對象有沒有其餘對象引用到它」。若是沒有引用指向該對象(零引用),對象將被垃圾回收機制回收。this

限制:循環引用prototype

function f(){
  var o = {};
  var o2 = {};
  o.a = o2; // o 引用 o2
  o2.a = o; // o2 引用 o

  return "azerty";
}

f();

該算法有個限制:沒法處理循環引用的事例。在下面的例子中,兩個對象被建立,並互相引用,造成了一個循環。它們被調用以後會離開函數做用域,因此它們已經沒有用了,能夠被回收了。然而,引用計數算法考慮到它們互相都有至少一次引用,因此它們不會被回收。插件

標記-清除算法
這個算法把「對象是否再也不須要」簡化定義爲「對象是否能夠得到」。

這個算法假定設置一個叫作根(root)的對象(在Javascript裏,根是全局對象)。垃圾回收器將按期從根開始,找全部從根開始引用的對象,而後找這些對象引用的對象……從根開始,垃圾回收器將找到全部能夠得到的對象和收集全部不能得到的對象。

這個算法比前一個要好,由於「有零引用的對象」老是不可得到的,可是相反卻不必定,參考「循環引用」。

從2012年起,全部現代瀏覽器都使用了標記-清除垃圾回收算法。全部對JavaScript垃圾回收算法的改進都是基於標記-清除算法的改進,並無改進標記-清除算法自己和它對「對象是否再也不須要」的簡化定義。

Javascript中的基本數據類型:數字,字符串,邏輯類型,undefined,object, function
若是不考慮js的面向對象部分,JS是夠簡單的。

JavaScript面向對象
典型案例代碼一:
一、編寫圖片有序、無需排序預加載插件:

(function($) {
  function Preload(imgs, options) { // ES5形式定義類
    // 至關於JAVA中類的成員屬性和方法
    this.imgs = (typeof imgs === 'string') ? [imgs] : imgs;
    this.opts = $.extend({}, Preload.DEFAULTS, options)
    // 約定:下劃線_開頭的方法爲內部使用,不提供外部調用
    if('ordered' === this.opts.order ) {
      this._ordered(); // 有序預加載
    } else {
      this._unordered(); // 無序預加載
    }    
  }
  
  // 至關於JAVA中類的靜態成員屬性和方法,類的實例對象共享,能夠經過類名調用
  Preload.DEFAULTS = {
    order: 'unordered', // 插件默認設置
    each: null, // 每一張圖片加載完畢後執行
    all: null // 全部圖片加載完畢後執行
  }
  
  // 無序預加載方法
  Preload.prototype._unordered = function () {
    var imgs = this.imgs,
        opts = this.opts, 
        count = 0
    // 無序加載
    $.each(imgs, function(i, src) {
        var img = new Image()
        $(img).on('load error', function() {
          count++
          opts.each && opts.each() // 先判斷傳參是否空
          if(count >= imgs.length-1) {
            opts.all && opts.all() // 先判斷傳參是否空
          }
          ...
        })
        img.src = src
    })
  }
  
  // 有序預加載方法
  Preload.prototype._oderded = function () {
     var imgs = this.imgs,
         opts = this.opts,
         count = 0
     load()
     // 有序加載
     funciton load() {
        var img = new Image()
        $(img).on('load error', function() {
          count++
          opts.each && opts.each() // 先判斷傳參是否空
          if(count >= imgs.length-1) {
            opts.all && opts.all() // 先判斷傳參是否空
          } else {
            load()
          }
        })
        img.src = imgs[count]
     }   
        
  }
  
  // 寫成jQuery插件
  $.extend({
    preload: function(imgs, opts) {
      new Preload(imgs, opts)
    }
  })
})(jQuery);

調用:$.preload(['https://xx.gif', ''], { 'ordered', function() {}, function() {} })

jQuery插件兩種形式:$.fn.extend -> $('#img').preload() // 掛載到jQuery.fn上,調用時能夠選擇元素後調用$.extend -> $.preload() // 直接掛載到jQuery上,不須要選擇元素

相關文章
相關標籤/搜索