主頁 > 前端設計 > 【前端圭臬】七:JavaScript 簡史與面向物件之道

【前端圭臬】七:JavaScript 簡史與面向物件之道

2021-04-05 10:28:46 前端設計

前言

從這篇起我們來一起學習 JS,

在二十一世紀二十年代的今天,想必不會有人再對 JS 作為一門正兒八經的編程語言的合理地位提出質疑了,而想要獲得一門編程語言的比較完備的知識,我們就至少需要從文法(語法詞法)、語意、編譯時、運行時四個角度去考慮,

由于 JS 在大部分情況下是 解釋執行 的,一般不考慮編譯時的東西,因此它的基礎知識結構就如下圖所示:
JS

當然,我們不是語言學家,作為工程技術人員對語意這個東西并不需要過分解釋,它就是指一段代碼的意思,所以我們學 JS ,說白了就是在學它的文法和運行時

我們之后的內容也會圍繞著這兩部分展開,但為了真正弄明白 JS 這門語言的設計思路,我覺得還是有必要先從它的歷史沿革說起,

1 JS 簡史

1.1 倉促誕生

JavaScript 誕生于網景(Netscape)公司,最初 Netscape Navigator 瀏覽器只能展示靜態頁面,缺乏動態互動的能力,因此在 1995 年,網景公司決定向瀏覽器中加入一個 “腳本語言”,他們設想了兩條實作路徑:

  • 與 Sun 公司合作,嵌入 Java
  • 嵌入 Scheme 語言

然而網景的管理者最終覺得最好的辦法是設計一門語法 類似 Java,而不是像現存的 Scheme 等腳本語言的新語言出來,

因此,原本被招來負責嵌入 Scheme 的 Brendan Eich 就花了幾周時間搞出來了這么個東西,一開始被稱為 Mocha,然后改為 LiveScript,三個月又后改為 JavaScript,

JavaScript 這個名字使它看起來像 Java 派生出來的,誤導了不少小白,其實兩者的關系也僅僅在語法設計層面,起這么個名字往難聽了說就是蹭熱度,只能說當時格局小了,

另外據說 Brendan 對要求自己照著 Java 語法設計語言這件事有些不爽,還在網上吐槽過自己的某個“光頭老板”,

1.2 明爭暗斗

為了與網景分庭抗禮,1996 年,微軟在自己的 IE 瀏覽器中內置了一門新的腳本語言,稱為 JScript,去蹭 JavaScript 的熱度,這個 JScript 跟 JS 在實作方式上又很大不同,因此開發者很難解決兼容性問題,使得當年許多網頁上都會有類似 “best viewed in Netscape” 和 “best viewed in Internet Exploer” 這也的 logo,

同年,網景把 JavaScript 提交到了 ECMA 國際,意在形成一個讓所有瀏覽器廠商遵守的標準規范,1997 年,ECMA 基于 JavaScript 發布了 ECMAScript 的第一個正式版本,

雖然自此有了一個規范擺在那里,但代碼怎么執行還是瀏覽器說了算,在實作上多一些少一些原創一些都有可能,因此 JavaScript 這個稱呼還是保留了下來,代指這些差不多又不那么規范的東西,

此后幾年,ECMAScript 陸續發布了 2、3、4 版本,然而到 2000 年時,IE 瀏覽器已經占據了 95% 的市場,可以說 JScript 反倒成了事實上的客戶端腳本標準,

其實在 ECMAScript 制定的初期,微軟還依據 JScript 提出了一些建議,但后來逐漸停止了跟 ECMA 的合作,而 ES 4 由于爭議性比較大最終被棄用了,看起來似乎 JScript 要一統江山了,(有意思的是,ES 4 里最具爭議的幾個特性,比如生成器、迭代器、解構賦值等在最近的版本里又被加了回來)

1.3 融合統一

天道好輪回,Netscape 的后繼者 Mozilla 基金會又發行了 Firefox 瀏覽器,由于廣受好評,沒過幾年又搶占了 IE 的許多市場份額,

2005 年,Jesse James Garrett 發布了論文:《Ajax: A New Approach to Web Applications》,描述了一種以 JavaScript 為基礎的技術,使得頁面無需全部重新加載即可回應變化,這種技術的出現極大地豐富了網頁的表現能力,引發了 JavaScript 的復興,在開源社區的主導下誕生了 jQuery、Prototype、Dojo Toolkit、MooTools 等著名的庫或工具集,

2008 年,Google 推出 Chrome 瀏覽器,由于其 JavaScript 引擎在性能上的優勢,又一次引發了瀏覽器市場的洗牌,

也許是終于意識到在內置語言這個問題上爭論不休不利于 Web 技術的發展,2008 年 7 月,相關廠商在奧斯陸(Oslo)舉辦了會議,認為應當攜手推動語言的發展,并基于 ES 4 開展了標準的重修作業,

會議后不久,ES 5 正式發布,同時,在這次會議上提出的代號為 Harmony 的專案最終于 2015 年開花結果,也就是我們熟知的 ES 6(ES 2015),

可以說,直到 ES 6 發布,用于瀏覽器端的編程語言 才真正有了統一的廣受認可的標準,實際上從此時開始,ECMAScript 每年都會發布新的版本,其雖然脫胎于 JavaScript,但顯然背后的推動力量已經上了一個新臺階,

ES 6 在技術層面也是具有里程碑意義的重要版本,它補充了一些十分關鍵但不被舊版瀏覽器支持的特性,促進了瀏覽器的新一輪迭代,豐富了語言的能力,甚至形成了新的編程風格,在過去的幾年里,使用 ES 6 改寫代碼、處理使用 ES 6 導致的兼容性問題也是前端的重要作業之一,

雖然嚴格意義上一統江湖的是 ECMAScript,但由于 JavaScript 這個名字已經太過深入人心,我們在大部分情況下還是習慣性地用它來代指這門語言,

前面提到,最初對 JS 的定位就是一門 “腳本語言(Script,解釋執行的語言)”,但越來越多的人不再把 JS 當作一門腳本語言,實際上 “解釋執行”“編譯執行” 并非是語言本身的特性,而是 編譯器/解釋器/引擎 需要做的事情,因此 腳本語言/非腳本語言 這種分類方式其實并不嚴謹,

現代瀏覽器的顛覆性革新之一就是使用 JIT(Just In Time)技術,對一段 JS 代碼動態地選擇究竟使用解釋還是編譯執行,所以忘掉 JavaScript 叫 Script 這件事吧,(另外其實 Java 也采用了類似的技術,使得它可以被解釋執行)

2 JS 面向物件

2.1 面向物件與基于物件

在 JavaScript 誕生至今的二十五六年里,對于它到底是不是面向物件的編程語言這件事經常有爭議,也有不少人強調,JS 不是 “面向物件(Object-Oriented)”,而是 “基于物件(Object-Based)”

這個問題,怎么說呢,一部分是文字游戲,一部分又涉及語言的本質,需要認真理解,

首先,ECMAScript 規范中明確指出 ES 是面向物件的編程語言,

ECMAScript is an object-oriented programming language for performing computations and manipulating computational objects within a host environment.

當然,我們可以暫且認為這只代表了撰寫規范的人的想法,究竟是不是面向物件,還要看面向物件的定義又是什么,

oh,不好意思,面向物件至今仍然沒有統一的定義,

實際上計算機領域里少有公理一般的概念,同一個術語在一個時期里并存多種解釋的情況是廣泛存在的,這些解釋里有的認可度高,有的認可度低,有的更抽象,有的更貼切,有的全面一些,有些片面一些,

如何回答什么是面向物件,與問題的語境密切相關,在 Java 領域,你就得咬死面向物件三大特性——封裝、繼承、多型,最近一朋友去面位元組,反饋還是有這種問題,他稱之為 “Java 八股”,😂

說白了就是,一部分工程師(以 Java 為代表)認為 “面向物件” 是一個內涵確定的概念,判斷一個語言是否是面向物件,存在一組必要條件,不符合其中之一,就不是面向物件,即使有物件這個東西在,也只能稱為 “基于物件”

然而面向物件,其實屬于不斷被豐富又不斷被抽象的一個概念,

豐富,意思是不斷地有新的特性被加入,這些特性使得面向物件這種設計能夠展現更大的能力,

而抽象,意思是面向物件的核心概念在收斂,從而擴大了滿足面向物件基本要求的語言范圍,

但作為前端工程師,對面向物件這個問題就可以認識地更靈活一些,面向物件語言的基本條件就是,它是 “面向” -> “物件” 的,面向,就是針對或以···為主體的意思,而物件這個東西,我們認為它具有以下特征:

  • 唯一標識性:每個物件是唯一且可以標識的,即使看起來完全相同,也并非同一個
  • 物件有狀態:物件具有狀態,同一物件可能處于不同狀態之下
  • 物件具有行為:即物件的狀態,可能因為它的行為產生變遷

“物件” 又是一個可能變化的概念,但上述特征是比較貼近我們對現實世界中的事物的認知的本質的,因此我們姑且可以遵循這個定義去判斷一個語言是否實作了完備的物件系統,

對于 JS 來說,每個物件在記憶體中都有獨立的地址,且可以通過物件名訪問,符合唯一標識性,JS 的物件有狀態屬性、有行為屬性,符合后兩個特征,它的物件系統是完備的,

只不過,JS 走了一條與 C++、Java 等老大哥不同的道路,那就是基于 “原型” 來描述物件,

2.1 基于原型的面向物件系統

在面向物件的世界里,使用 “類(Class)” 這個概念描述物件是如此成功,以至于人們認為面向物件一定要有類這個東西,

然而,JS 的設計者,Brendan 老哥使用了另一套理念去實作物件系統,那就是基于 “原型” 描述物件,

我們前面提到,JS 在設計之初被要求貼近 Java 的語法,因此 Brendan “被迫” 引入了一些語言特性,使得它能夠用類似 Java 語言的方式去操縱物件,這些特性只是一種模擬,或者說是語法糖,并沒有運行時的支撐,

什么意思呢?Java 的每個類都是一種真正存在的型別,而 JS 中的物件均屬于 Object 這一種型別,所謂的 Class 只不過是物件的一個私有屬性,

而且,JS 初期對 “類系統” 的模擬主要依靠 new、this 等關鍵字,不但無法模仿繼承等關鍵特性,還存在一些反直覺的現象,而崇尚類系統的開發者們又折騰出了不同的解決方案,使得 JS 中對物件的使用五花八門,造成了許多的麻煩,直到 ES 6 問世,提供了 class 關鍵字來定義類,才使得 JS 對類的模擬方式終于統一起來,

但是我們大可不必非要去模仿類系統,對于 ES 6 之后版本的 JS 來說,使用原型系統本身的特性是十分自然的,

原型這個概念乍一看不太好理解,感覺背后有很深的含義在,但其實原型就是原型的字面意思,

在 Java 中,假如我們想要獲得一個英短金漸層物件,需要先定義一個英短金漸層類,這個類可能繼承自貓類,然后根據類 new 一個物件出來,

而 JS 中,我們可以直接根據已經存在的英短銀漸層這個原型(也是一個物件)去創建金漸層物件,不需要再定義一個類,物件與原型之間也不必有抽象層次的限制,只需要描述與原型的區別即可,

而且,從運行時的角度來說,根據原型創建的物件不需要保存原型的屬性,但卻可以順著 “原型鏈” 訪問自己沒有而原型有的屬性,

什么是原型鏈?一個屬性如果物件沒有,就會根據 [[prototype]] 欄位訪問原型,查找原型中的欄位,在 JS 中,所有物件的原型都可以追溯到 Null,到 Null,或者說其實是 Object,但 Object 本身的原型是 Null,

因此,我們也可以通過原型物件控制所有基于它實作的物件的行為,這是基于類的系統所不具備的能力,JS 也算是在一定程度上證明了基于原型這條路一樣走得通,孰優孰劣目前還下不了定論,

在語法層面,今天的 JS 有四套操縱物件的方式:

  • {} / . / [] / Obejct.defineProperty,不依賴類或原型創建物件、訪問屬性、定義新屬性的基礎方法
  • Obejct.create / Object.setPrototypeOf / Object.getPrototypeOf,基于原型的描述方法
  • new / class / extends,模擬類的方式
  • new / function /prototype,原始的模擬類的方式,ES 3 版本之后不推薦使用

這就造成了同樣的一門語言,不同的公司、不同的人寫起來可能完全是不同的風格,新手可能會因為這種現象大為頭疼,但是我們應該認識到,幾種寫法背后其實是同一套機制在支撐,

好了,這篇文章我們先從 JS 原型系統這么一個關鍵點切入,踏出理解 JS 本質的第一步,在之后的文章中,我們會繼續深入剖析 JS 的運行時,

下一步

下一篇文章,我們就來詳細探討一下 JavaScript 的型別系統,理解各種型別在記憶體中的組織方式以及使用時的注意事項,


記憶拾遺:

JS 這門語言,有太多的眾說紛紜、似是而非,我們雖然可以通過 ECMA 標準來論證真偽,但有時候一些錯誤的說法在實踐上卻可以取得正確的結果,因此我們自己可能都感覺不出來有問題,

也是受到 winter 大神的啟發,我才意識到理解 JS 的本質應該從運行時入手,縱使語法特性不斷迭代,JS 的運行時依舊遵循著最初的設計路線,

然而,各類面經又熱衷于傳遞拗口的語法層面的概念,大家如果自己參與過出題這種活動就會明白,有些題的出處可能就是哪個人在博客或者什么地方隨便說了一句話,被出題的人搜到了拿來湊數,沒想到一傳十十傳百,最后比定義還像定義,你不知道還顯得像個菜雞,

網上嚴謹一些的教程,比如 MDN,大部分時候解釋的是對的,但就是遇到稍微復雜一點的問題,看著感覺十分費勁,這也是因為 MDN 的中文并非原創,而是從英文原版翻譯而來,首先外國人的思維模式跟我們有出入,再加上可能并不那么專業的翻譯(MDN 是一個開源專案),相當于被加了兩層 debuff,

所以有時候我們學習知識確實比英語國家要費勁一些,希望有一天我們能在更多領域讓別人試圖理解我們的意思吧,嗯,從這個層面來說,對尤雨溪大神,我真的 respect,同叫 Evan,我很慚愧,😝

年后的第一個三天小長假,大半天算是陪各位度過了,明天好好休息一天,下周見,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/272505.html

標籤:其他

上一篇:簡單理解vue中data資料的改變影響視圖

下一篇:JavaScript 常用方法封裝使用

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • vue移動端上拉加載

    可能做得過于簡單或者比較low,請各位大佬留情,一起探討技術 ......

    uj5u.com 2020-09-10 04:38:07 more
  • 優美網站首頁,頂部多層導航

    一個個人用的瀏覽器首頁,可以把一下常用的網站放在這里,平常打開會比較方便。 第一步,HTML代碼 <script src=https://www.cnblogs.com/szharf/p/"js/jquery-3.4.1.min.js"></script> <div id="navigate"> <ul> <li class="labels labels_1"> ......

    uj5u.com 2020-09-10 04:38:47 more
  • 頁面為要加<!DOCTYPE html>

    最近因為寫一個js函式,需要用到$(window).height(); 由于手寫demo的時候,過于自信,其實對前端方面的認識也不夠體系,用文本檔案直接敲出來的html代碼,第一行沒有加上<!DOCTYPE html> 導致了$(window).height();的結果直接是整個document的高 ......

    uj5u.com 2020-09-10 04:38:52 more
  • WordPress網站程式手動升級要做好資料備份

    WordPress博客網站程式在進行升級前,必須要做好網站資料的備份,這個問題良家佐言是遇見過的;在剛開始接觸WordPress博客程式的時候,因為升級問題和博客網站的修改的一些嘗試,良家佐言是吃盡了苦頭。因為購買的是西部數碼的空間和域名,每當佐言把自己的WordPress博客網站搞到一塌糊涂的時候 ......

    uj5u.com 2020-09-10 04:39:30 more
  • WordPress程式不能升級為5.4.2版本的原因

    WordPress是一款個人博客系統,受到英文博客愛好者和中文博客愛好者的追捧,并逐步演化成一款內容管理系統軟體;它是使用PHP語言和MySQL資料庫開發的,用戶可以在支持PHP和MySQL資料庫的服務器上使用自己的博客。每一次WordPress程式的更新,就會牽動無數WordPress愛好者的心, ......

    uj5u.com 2020-09-10 04:39:49 more
  • 使用CSS3的偽元素進行首字母下沉和首行改變樣式

    網頁中常見的一種效果,首字改變樣式或者首行改變樣式,效果如下圖。 代碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ......

    uj5u.com 2020-09-10 04:40:09 more
  • 關于a標簽的講解

    什么是a標簽? <a> 標簽定義超鏈接,用于從一個頁面鏈接到另一個頁面。 <a> 元素最重要的屬性是 href 屬性,它指定鏈接的目標。 a標簽的語法格式:<a href=https://www.cnblogs.com/summerxbc/p/"指定要跳轉的目標界面的鏈接">需要展示給用戶看見的內容</a> a標簽 在所有瀏覽器中,鏈接的默認外觀如下: 未被訪問的鏈接帶 ......

    uj5u.com 2020-09-10 04:40:11 more
  • 前端輪播圖

    在需要輪播的頁面是引入swiper.min.js和swiper.min.css swiper.min.js地址: 鏈接:https://pan.baidu.com/s/15Uh516YHa4CV3X-RyjEIWw 提取碼:4aks swiper.min.css地址 鏈接:https://pan.b ......

    uj5u.com 2020-09-10 04:40:13 more
  • 如何設定html中的背景圖片(全屏顯示,且不拉伸)

    1 <style>2 body{background-image:url(https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture); 3 background-size:cover;background ......

    uj5u.com 2020-09-10 04:40:16 more
  • Java學習——HTML詳解(上)

    HTML詳解 初識HTML Hyper Text Markup Language(超文本標記語言) 1 <!--DOCTYPE:告訴瀏覽器我們要使用什么規范--> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <!--meta 描述性的標簽,描述一些 ......

    uj5u.com 2020-09-10 04:40:33 more
最新发布
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 07:59:23 more
  • 生產事故-走近科學之消失的JWT

    入職多年,面對生產環境,盡管都是小心翼翼,慎之又慎,還是難免捅出簍子。輕則滿頭大汗,面紅耳赤。重則系統停擺,損失資金。每一個生產事故的背后,都是寶貴的經驗和教訓,都是專案成員的血淚史。為了更好地防范和遏制今后的各類事故,特開此專題,長期更新和記錄大大小小的各類事故。有些是親身經歷,有些是經人耳傳口授 ......

    uj5u.com 2023-04-18 07:55:04 more
  • 記錄--Canvas實作打飛字游戲

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 打開游戲界面,看到一個畫面簡潔、卻又富有挑戰性的游戲。螢屏上,有一個白色的矩形框,里面不斷下落著各種單詞,而我需要迅速地輸入這些單詞。如果我輸入的單詞與螢屏上的單詞匹配,那么我就可以獲得得分;如果我輸入的單詞錯誤或者時間過長,那么我就會輸 ......

    uj5u.com 2023-04-04 08:35:30 more
  • 了解 HTTP 看這一篇就夠

    在學習網路之前,了解它的歷史能夠幫助我們明白為何它會發展為如今這個樣子,引發探究網路的興趣。下面的這張圖片就展示了“互聯網”誕生至今的發展歷程。 ......

    uj5u.com 2023-03-16 11:00:15 more
  • 藍牙-低功耗中心設備

    //11.開啟藍牙配接器 openBluetoothAdapter //21.開始搜索藍牙設備 startBluetoothDevicesDiscovery //31.開啟監聽搜索藍牙設備 onBluetoothDeviceFound //30.停止監聽搜索藍牙設備 offBluetoothDevi ......

    uj5u.com 2023-03-15 09:06:45 more
  • canvas畫板(滑鼠和觸摸)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>canves</title> <style> #canvas { cursor:url(../images/pen.png),crosshair; } #canvasdiv{ bo ......

    uj5u.com 2023-02-15 08:56:31 more
  • 手機端H5 實作自定義拍照界面

    手機端 H5 實作自定義拍照界面也可以使用 MediaDevices API 和 <video> 標簽來實作,和在桌面端做法基本一致。 首先,使用 MediaDevices.getUserMedia() 方法獲取攝像頭媒體流,并將其傳遞給 <video> 標簽進行渲染。 接著,使用 HTML 的 < ......

    uj5u.com 2023-01-12 07:58:22 more
  • 記錄--短視頻滑動播放在 H5 下的實作

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 短視頻已經無數不在了,但是主體還是使用 app 來承載的。本文講述 H5 如何實作 app 的視頻滑動體驗。 無聲勝有聲,一圖頂百辯,且看下圖: 網址鏈接(需在微信或者手Q中瀏覽) 從上圖可以看到,我們主要實作的功能也是本文要講解的有: ......

    uj5u.com 2023-01-04 07:29:05 more
  • 一文讀懂 HTTP/1 HTTP/2 HTTP/3

    從 1989 年萬維網(www)誕生,HTTP(HyperText Transfer Protocol)經歷了眾多版本迭代,WebSocket 也在期間萌芽。1991 年 HTTP0.9 被發明。1996 年出現了 HTTP1.0。2015 年 HTTP2 正式發布。2020 年 HTTP3 或能正... ......

    uj5u.com 2022-12-24 06:56:02 more
  • 【HTML基礎篇002】HTML之form表單超詳解

    ??一、form表單是什么

    ??二、form表單的屬性

    ??三、input中的各種Type屬性值

    ??四、標簽 ......

    uj5u.com 2022-12-18 07:17:06 more