看圖學習javascript
如果想成為一個高效的javascript的程序員,深刻理解javascript的語法是必須的。記得上小學的時候,再難的數學題通過畫圖的方式很快就能解決,我們在學習javascript有時感覺一些語法也比較難理解,為何不能用畫圖的方式幫助我們理解呢?下麵我們就把javascript一些基本的語法轉換成圖行元素,估計您會有一個醍醐灌頂的感覺。這個係列文章我準備使用兩篇文章寫完,今天我們來看一些最基本的內容。
在javascript中變量名(variable)就是一個簡單的標記,來引用內存中的一個值,這些值可以是一些基本類型(strings, numbers, and booleans.),也有可能是一些引用類型(objects or functions)
-
局部變量
在下麵的例子中,我們在頂層作用域中來聲明一些局部變量,他們指向的是一些基本類型的數值。
/* 在頂層作用域來聲明一些局部變量*/ var name = "Tim Caswell"; var age = 25; var isProgrammer = true; var likesJavaScript = true; // 如果兩個變量指向相同的值,看看這兩個變量是否相等。 isProgrammer === likesJavaScript; /* 結果:true */
下麵我們來用圖形來表示上麵的代碼關係:
注意:兩個boolean類型的變量在內存中指向相同的值,這是因為基本類型的數值是不可變的,這樣javascript的解釋器就可以讓指向相同值的所有引用共享一個實例。
因此isProgrammer和likesJavaScript用===(絕對等於)進行比較的結果是true。左邊最外城的矩形表示最外層的閉包作用域,裏麵的變量表示頂層的局部標量,不要和global/window的屬性混淆。
對象和原型鏈
先來看個簡單的例子:這裏需要用到一個工具方法:
if (typeof Object.create !== 'function') { Object.create = function (o) { function F() {} F.prototype = o; return new F(); }; } // Create a parent object var tim = { name: "Tim Caswell", age: 28, isProgrammer: true, likesJavaScript: true } // Create a child object var jack = Object.create(tim); // Override some properties locally jack.name = "Jack Caswell"; jack.age = 4; // Look up stuff through the prototype chain jack.likesJavaScript; /* => true */
下麵我們來用圖形來表示上麵代碼的關係:
通過上圖我們可以一目了然的看到jack.likesJavaScript值是什麼了。
- 全局對象
曾經懷疑想jslint這樣的工具怎麼會提示不要在聲明變量的時候忘記var,如果忘記了會發生什麼呢?
var name = "Tim Caswell"; var age = 28; var isProgrammer = true; // Oops we forgot a var likesJavaScript = true;
注意:likesJavaScript是全局對象的一個屬性,而不是一個最外層閉包的一個自由變量。這樣做一般情況下沒有問題,當你混淆多個javascript的時候就會有問題了。
因此當你聲明變量的時候使用var關鍵字,可以讓你的變量在當前的作用域或者子作用域中;如果你真的想聲明全局對象的屬性,在瀏覽器中用window.myVariable, 在node.js用global.myVariable
- 函數和閉包
Javascript不僅僅是一係列鏈表的數據結構。他還包含可以執行和調用的函數,這些函數生成了作用域鏈和閉包。
顯式的閉包
方法可以被認為是含有可執行代碼和一些屬性的特殊對象,每一個函數有一個scope屬性表示它定義時所在的環境,如果一個函數是從兩外一個函數放回的,那麼他對原來環境的引用會被新的函數封閉在閉包中。
下麵的代碼,我們聲明一個函數然後讓他產生一個閉包並且返回一個函數。
function makeClosure(name) { return function () { return name; }; } var description1 = makeClosure("Cloe the Closure"); var description2 = makeClosure("Albert the Awesome"); console.log(description1()); console.log(description2()); /* Cloe the Closure Albert the Awesome */
當我們調用description1()的時候,解釋器首先查詢到description1引用的函數,
然後執行它,該函數需要一個名字為name的局部變量,然後他在閉包中找到了這個變量。makeClosure所生成的方法的局部變量都有自己單獨的一份空間。
- 共享方法和this
Javascript提供了this關鍵字允許我們根據不同的調用對象在不同的作用域中重用同一個函數。如:
var Lane = {
name: "Lane the Lambda",
description: function () {
return this.name;
}
};
var description = Lane.description;
var Fred = {
description: Lane.description,
name: "Fred the Functor"
};
// Call the function from four different scopes
console.log(Lane.description());
console.log(Fred.description());
console.log(description());
console.log(description.call({
name: "Zed the Zetabyte"
}));
/*
Lane the Lambda
Fred the Functor
undefined
Zed the Zetabyte
*/
從圖中我們可以看到description確實指向同一個函數,但是name的指向是不相同的。
最後我希望用圖形的方式能夠讓大家更好的理解javascript,祝大家學習愉快,有什麼問題,請留言反饋。
最後更新:2017-04-02 06:51:32