10分鐘瞭解Javascript-天碼營

Javascript是動態的,弱類型的,解釋執行的程序設計語言。javascript

Javascript極其靈活,支持多種程序設計範式:面向對象、指令式、函數式。JavaSCript最初被用於瀏覽器腳本,如今已是全部主流瀏覽器的默認腳本語言。瀏覽器腳本的做用包括用戶交互、DOM操做、以及與服務器通訊。Node.js的流行已經將JavaScript從瀏覽器端引入到服務器端,並顯示出卓越的併發性能。java

Javascript 由 Netscape 瀏覽器首次引入到Web文檔中。Javascript的出現使web文檔變得更像動態的App,而不是靜態的文檔。如今主流的瀏覽器都有javascript支持。Javascript核心被標準化爲ECMAScript。web

JavaScript做爲一門通用編程語言(general purpose),其語法、內置對象、以及工具庫須要大量的精力才能掌握,但JavaScript有着直觀的語法,是一門很是容易上手的編程語言。本章中介紹JavaScript最基本的語法,而後編寫一個簡單的Javascript程序。編程

1.Hello World

使用你喜歡的文本編輯器,創建一個javascript文件(後綴命名爲.js便可),輸入如下的內容:設計模式

console.log('Hello, world!')

console多數JavaScript的宿主環境都會提供的全局對象,它的log方法用來輸出(到標準輸出)一個字符串。爲了運行這段程序,能夠打開Chrome瀏覽器的開發者工具(右上角的設置按鈕->更多工具->開發者工具),進入Console頁面。數組

拷貝這段代碼進去,按下回車,你會看到在控制檯的輸出:Hello, world!瀏覽器

2.數據類型

Javascript 是一門弱類型動態類型的語言。弱類型意味着容許隱式類型轉換,不一樣類型的變量間能夠直接賦值和運算;動態類型則意味着只在運行時纔會進行類型檢查,因而包含錯誤的文件仍然可以獲得執行,直到運行至包含類型錯誤的語句,JavaScript程序才異常退出。服務器

Javascript中包含5種基本類型(primitive types):閉包

  • 字符串(String):其取值爲字符序列。字符串能夠用單引號或雙引號分隔,兩者徹底等價。併發

var str1 = "str1",
str2 = '"str1" is a string';
  • 數字(Number):它是實數?整數?無符號數?這些都不須要考慮!Javascript中,數字就是數字!

var n = 1;
n = n/3;    // 0.33333...
  • 布爾類型(Boolean):只有兩種取值:true, false

  • 空(Null):該類型只有一個值可取,它就是null。在多數Javascript運行時中,null是一種特殊的object

  • 未定義(Undefined):該類型也只有一個值可取,它就是undefined。有趣的是,你能夠把一個變量聲明爲未定義:

var foo = undefined;

除了基本數據類型,還有一種對象(object)類型,Object是JavaScript中全部其餘對象的原型(若是你熟知Java等基於類繼承的語言,能夠理解爲Object是其餘全部對象的公共父類)。日期、數組、函數都是JavaScript內置的特殊對象。ECMAScript將對象定義爲屬性的集合(Collection),建立一個對象的語法就像建立一個集合:

var student = {name: '小明', age: 23};

咱們看到:

  1. 全部的變量都是以var聲明的,若是你忘記了寫var,那麼這個變量將成爲整個運行時的全局變量。

  2. 另外,Javascript與C++使用一樣的註釋風格,即/**/用於多行註釋,//用於單行註釋。

3.對象

Javascript是面向對象的編程語言,對象是javascript中最重要的概念。上一節咱們經過一對大括號建立了一個對象:

var student = {name: '小明', age: 23};

若是你熟悉構造函數,JavaScript也支持這種方式:

function Student(name){
   this.name = name;
   this.age = 23;
}
var student = new Student('小明');
student.school = 'PKU';

在Javascript中,經過this來訪問本身的屬性。有趣的是,訪問屬性前不需聲明:

  1. 若是直接讀取未聲明屬性,會獲得undefined

  2. 若是直接寫入未聲明屬性,則會聲明並用指定的值初始化該屬性

若是你熟悉設計模式,你可能會須要這樣的對象建立方式:

function StudentFactory(_school){
    var school = _school;

    this.create = function(name, age){
        return {
            name: name,
            age : age,
            school: school
        }
    }
}
var factory = new StudentFactory('PKU');
var student = factory.create('小明', 23);

上述代碼中,首先聲明瞭一個工廠對象(function是一種特殊的對象),並用school來配置該工廠。此後用該工廠生產一個學生對象:小明

如今,你已經熟悉了Javascript中對象的建立。若是你曾開發過C++或者Java,你可能會關心Javascript中如何進行繼承,以及實現多態。

不錯,Javascript是面嚮對象語言。但沒有類的聲明和實例化機制,Javascript使用原型繼承的方式(prototype)。看到下面的例子也許就清楚了:

// file: prototype.js

var Person = {
    sayhi : function(){
        console.log("hi! I'm", this.name)
    }
};

function Student(name){
    this.name = name;
    this.school = 'pku';
}
Student.prototype = Person;

var student = new Student('alice');

// hi! I'm alice
student.sayhi();

上述代碼中,首先聲明瞭Person對象,他有一個sayhi屬性,該屬性的值爲function類型(還記得嗎?函數是一種特殊的對象)。而後將構造函數Student的原型設爲Person,便實現了對象繼承。

prototype對象是個模板,要實例化的對象都以這個模板爲基礎(屬性和方法都被傳遞給那個類的全部實例)。prototype是能夠傳遞的,最終造成原型鏈。

4.函數

JavaScript 最使人感興趣的可能莫過於函數其實是功能完整的對象,經過function來聲明函數。在JavaScript中的函數是一級公民,這意味着函數和其餘變量同樣,能夠被傳參、賦值、以及返回。函數有以下幾個默認屬性:

1.length:參數個數

function func(arg1, arg2){}

 // 2
 console.log(func.length)

2.toString:這是全部對象共有的方法,將會輸出函數的源代碼

// function func(arg1, arg2){}
 console.log(func.toString())

5.arguments

在函數體中,JavaScript提供了一個特殊對象 arguments,它是當前函數被調用時傳入的參數數組,經過訪問arguments不只能夠訪問全部實參,還能夠得到實參的數目,從而實現其餘編程語言中可變參數的機制:

/ file: arguments.js

function sayHi(){
    if(arguments.length == 1)
        console.log("I'm", arguments[0]);
    if(arguments.length == 2)
        console.log("I'm", arguments[0], 'aged', arguments[1]);
}
// I'm alice
sayHi('alice');
// I'm alice aged 23
sayHi('alice', 23);

Javascript並未提供函數重載、默認參數機制。但咱們能夠直接訪問arguments參數列表,sayHi其實模仿了函數重載。

6.call & apply

callapply是函數對象的兩個函數屬性,通常用於對象冒充、包裝或者代理。可能在教學中不會用到太多,但在JS庫的開發中會常常用到。這兩個函數的功能均爲用一個對象去調用一個函數,而該函數並不是該對象的屬性,例如:

// file: call.js
function sayHi(age){
    console.log("I'm", this.name, 'aged', age)
}
var student = {
    name: 'alice'
};
// I'm alice aged 23
sayHi.call(student, 23)

call的第一個參數是用做this的對象。其餘參數都直接傳遞給函數自身。既然如此,若是咱們但願實現一個本身的log函數,來包裝console.log

// file: log.js
function log(){
    var str = '';
    for(var i = 0; i < arguments.length; i++){
        str += ' ' + arguments[i]
    }
    console.log(str);
}
// a b c
log('a', 'b', 'c');

這裏咱們不能使用call函數,由於咱們不知道參數個數。這即是apply的用武之地:

// file: log.js
function log(){
    console.log.apply(this, arguments)
}
// a b c
log('a', 'b', 'c');

apply接受的第二個參數爲參數數組,而非call的參數列表。這便爲上述的狀況提供了便利。

7.回調與異步

因Javascript最初運行於瀏覽器端,與服務器的通訊必然要異步執行(不然,將會阻塞主控制流,此時瀏覽器會不響應用戶操做)。因而,Javascript天生就是異步的,Node.js也是採用異步事件而大幅提升I/O密集型任務的效率。

異步是計算機在執行任務的過程當中,某些任務能夠獨立於主控制流執行,使得主控制流得以繼續執行,是一種非阻塞的控制方案。

在Javascript中有多種異步的實現方案,它們無一例外地須要回調函數。回調函數就是將函數做爲參數傳遞到其餘代碼(例如:某一個異步任務),這一設計容許了該異步任務完成時執行傳入的函數。例如:

// file: async.js
function taskFinished(){
    console.log('Task finished!')
}
setTimeout(taskFinished, 3000);

上述代碼中,首先定義了一個任務完成時須要執行的函數taskFinishedsetTimeout是Javascript提供的一個全局對象(還記得嗎?函數是一種特殊的對象),它是一個計時器,在到達指定的時間後調用某個函數。上述例子中,在5000毫秒後運行taskFinished函數。

8.變量做用域與閉包

Javascript的變量做用域不一樣於其餘的主流編程語言。包括變量的定義方式、做用域的劃分、做用持續時間等。

在javascript中使用賦值語句便可定義一個對象,而不須要對象聲明(也不須要指定變量的類型)。使用var能夠定義局部變量,而省略var則能夠定義全局變量。例如:

// 定義局部變量 foo
var foo = 'bar'

// 定義全局變量 bar
bar = 'foo

上述的全局變量做用域不是當前對象,也不是當前文件,而是整個運行時進程!實際項目中,應儘可能避免引入全局變量。衆所周知,全局變量會使得代碼高度耦合、難以複用和維護、複雜化團隊協做。

那麼,局部變量的做用域是怎樣的呢?局部做用域即當前函數,不一樣於C++或Java的當前代碼塊(以大括號分隔)。正由於javascript的這一點特殊性質,引出了javascript中的一個重要概念:閉包(closure)。閉包是指是引用了自由變量的函數。這個被引用的自由變量將和這個函數一同存在,即便已經離開了它最初被建立的環境。

閉包之因此如此重要,是由於它完成了javascript的諸多面向對象特性:數據封裝、運行時多態。咱們看一個閉包:

// file: closure.js
function Count(){
    var num=0;
    this.add = function(){
        console.log(num++);
    }
}
var c = new Count();
c.add();
c.add();

Count是函數,而函數是對象,對象能夠有屬性和方法。add是方法屬性(類型爲方法的屬性),而num則只是函數的局部變量。

首先,咱們定義一個構造函數Count,並在其中定義一個局部變量num。接着,咱們調用該構造函數建立一個對象c,並調用兩次它的add方法。不出所料,程序的輸出將是:

0
1

你可能已經注意到:第二次調用add方法時,add中引用的num仍然保持着上次調用後的值。事實上,num是被add方法引用的一個自由變量,其做用域會一直跟隨add而存在。

不要混淆局部變量和對象屬性。這裏的num是局部變量,其做用域仍然存在是閉包現象,而非對象屬性。對象屬性須要用this關鍵字來定義。

若是你但願進一步學習Javascript,Mozilla Developer和W3C School: Javascript教程都提供了很好文檔。若是你願意深究Javascript語法規則,請參考ECMAScript標準:ECMAScript-262。

版權聲明

本文由Harttle創做,轉載需署名做者且註明文章出處

相關文章
相關標籤/搜索