要深入JavaScript, 下面的一些名詞出現的頻率非常高, 有些名字又很相近, 所以容易變得迷惑不清, 所以在理解就會限入不良的循環, 可能會感覺在用不理解的東西去解釋一個新東西, 后果可想而知. 如下是ECMAScript規范, 也是JavaScript實現的標准, 如果我們把最基礎的東西, 也就是用來解釋其它機制的東西都弄清楚了, 理解高級特性的時候就會變得容易了.
- 類型(Type): 數據的集合
- 原始值(Primitive Value): 只能是 Undefined, Null, Boolean, Number or String其中之一的值. 如: undefined, null, true / false, 3.1415926, "Hello world!"
- 對象(object): 是Object類型的一員(注意大小寫), 它是一些無序的,屬性的集合; 屬性可以是原始值, 另一個對象 或一個函數. 保存在對象屬性里的函數通常叫做方法(method).
- 構造函數(Constructor): constructor 是一個函數對象(Function object). 好吧, 這里出現一個讓人迷惑的詞: 函數對象. 這里先不詳細解釋, 記住既然它叫做構造函數, 那它自然是一個函數, 以后會講. 每個構造函數必定有一個原型對象(prototype object), JavsScript里用它來實現繼承和屬性共享. 繼承是高級應用, 以后再說. constuctor在繼承的實現時是一個需要留神的地方.
*任何函數都可以是構造函數, 但是並不是所有的函數都適合做構造函數, 要看我們定義這個函數的目的是什么.
var add = function(m, n) { return m + n; } var sum = add(3, 6); // 有實際意義, 完成特定功能的模塊 var foo = new add(); // 像它的名字foo一樣, 毫無意義, 但是無意義並不代表把add作為構造函數來用會產
//生語法 / 句法的錯誤! 僅僅是沒有意義. var Book = function(bookName) { this.bookName = bookName; } var book = Book("JaveScript權威指南"); // 就上面的代碼來看, 毫無意義 var myFavourateBook = new Book("JaveScript權威指南"); // 作為構造函數, 用來產生Book的實例. - 原型(prototype): 原型屬性指向的是一個對象! 一般叫它原型對象. JavaScript用它來實現好的繼承機制.
當構造函數(constructor) C(假設為構造函數的名字)創建一個新對象newObj的時候, newObj會有一個隱式的引用, 到構造函數C的prototype上. 讓人迷惑, 請看代碼和注釋
var C = function() { // 構造函數. 為什么這樣定義? 為什么是一個函數 而不是 C = {}? // 可以這樣記, 拋棄一切高級概念, // 既然叫構造函數, 那它就是一個函數, 所以要用函數定義或函數表達式這種形式. // 按高級OOP語言(如Java, C++, ...)的慣例, 首字母要大寫 } var newObj = new C(); C.prototype; // newObj會隱式的引用這個對象 // newObj會隱式的引用, 為什么用"隱式"這個詞? // 因為我們不能像 C.prototype 這種表達式直接引用到, 他是語言內部實現的東西. // 但是在Chrome中我們可以用 __proto__ 這個屬性來訪問到這個隱式的連接, 程序中是不應該這么用的, // Chrome應該是為了方便開發者才提供這樣的訪問. newObj.__proto__ === C.prototype; // true // 把上面這句翻譯成中文就是: 用構造函數C創建的新對象newObj, // 隱式的引用(newObj.__proto__)到了構造函數的原型對象(C.prototype).
待續... 歡迎指正, 共同進步. 后面就是涉及宿住環境的對象, 和內建對象一些說明. 這些是開始, 可能看到上面關於prototype介紹, 還是一大堆問號, 在以后會繼續一點點的寫 :) 盡量每一篇的topic少, 內容多 :)