探索javascirpt-原型與原型鏈

javascript使用原型鏈來解析屬性值(很類似於使用做用域鏈來解析變量)javascript

 

原型鏈是往"內部"找java

做用域鏈是往「外部」找閉包

 

使用Object.create()和工廠函數 取代 new(雖然如今new用的最多,大多數庫源代碼都是用new的方式來建立對象的,但畢竟javascirpt是原型繼承,因此隱藏oop的new)函數

Object.create僅支持ie9+,oop

因此要作兼容性判斷this

var objectCreate = function(arg) {

  if(!arg) { return {};}

  function obj(){};

  obj.prototype = arg;

  return new obj;

}

Object.create = Object.create || objectCreate ;//這是一種很經常使用的修復兼容性和檢測庫是否重複加載的方式

 

談談執行環境

  執行環境是函數被調用執行時才創建的,而做用域是根據代碼結構來定去區分的,無論函數賦值到哪去,(能夠大概認爲定義函數時函數就在內存中的一段地址,變量都是引用,沒法改變其地址,因此做用域都是同樣的)prototype

  但執行環境一個特有的變量就是this,this是根據執行環境要肯定它是指向那個對象。對象

  執行環境執行過程大體分爲兩輪,blog

  1:聲明參數並賦值繼承

  2:聲明局部變量但不賦值

  3:聲明函數而且賦值,但不執行(其優先級大於2)

 

模塊模式-將私有變量引入

  //其中也有一點,函數也是對象,因此函數的某些定義對象也因此,例如做用域,準確來講我認爲做用域是按對象來劃分的

 

var me = (function() {

    var name = "jack",

      jjLength = 18;

    return {

      yetName: function() {

        console.log(name);

      },

      yetJJ : function() {

        console.log(jjLength);

      }

    }

  })();

  me.yetName();//jack

  做爲匿名自執行函數,執行完一次以後便結束,

  裏面的變量就永遠都不會更新,除非你定義了set方法

  還有一點很關鍵,函數和對象的賦值都是引用賦值,二基礎變量是值傳遞。(也能夠這樣說,複雜數據類型是引用傳遞,基礎數據類型是值傳遞)

  這裏代碼能夠解釋:

  

var a = {
	bb : '3',
	cc : function() {
		console.log(this.bb);
	}
}

a.cc();//3
var b = a;
var bbb = a.bb;
b.bb = '2333';
a.cc();//2333
console.log(bbb);//3

  

談談閉包

  就我而言看了不少書,當講起閉包的概念的時候,沒幾本書能完全的解釋,例如」閉包是讓內部函數能訪問外部函數的變量的特性仍是xxxxbalabala「,反正都不懂

  但我曾看到一個最好的解釋是:

  閉包是阻止javascirpt垃圾回收器將變量從內存中移除的方法,使得在建立變量的執行環境的外面能訪問到該變量。(雖然我一直吐槽爲什麼叫作「閉包」,暫時還不懂命名的意義)

  

  話說閉包是如何工做的呢?答案就在執行環境對象中。//因此是執行時生成的,關於javascirpt垃圾回收規則,當變量被引用時邊不會被回收

  閉包實現柯里化,如下是seajs源碼中的一段

function isType(type) {
  return function(obj) {
    return {}.toString.call(obj) == "[object " + type + "]"
  }
}

var isObject = isType("Object")
var isString = isType("String")
var isArray = Array.isArray || isType("Array")
var isFunction = isType("Function")

  閉包可能會致使內存使用失控(思考一下內存泄露)

  由於若是一個函數一直循環執行,便每次建立一個執行環境,內存沒法獲得釋放,因此便會形成內存使用失控

相關文章
相關標籤/搜索