這篇文章運(yùn)用簡單易懂的例子給大家介紹Python與Javascript的區(qū)別是什么,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
專注于為中小企業(yè)提供成都網(wǎng)站制作、做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)下陸免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了上千余家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
基本概念
Python和Javascript都是腳本語言,所以它們有很多共同的特性,都需要解釋器來運(yùn)行,都是動態(tài)類型,都支持自動內(nèi)存管理,都可以調(diào)用eval()來執(zhí)行腳本等等腳本語言所共有的特性。
然而它們也有很大的區(qū)別,Javascript這設(shè)計之初是一種客戶端的腳本語言,主要應(yīng)用于瀏覽器,它的語法主要借鑒了C,而Python由于其“優(yōu)雅”,“明確”,“簡單”的設(shè)計而廣受歡迎,被應(yīng)用于教育,科學(xué)計算,web開發(fā)等不同的場景中。
編程范式
Python和Javascript都支持多種不同的編程范式,在面向?qū)ο蟮木幊躺厦?,它們有很大的區(qū)別。Javascript的面向?qū)ο笫腔谠停╬rototype)的, 對象的繼承是由原型(也是對象)創(chuàng)建出來的,由原型對象創(chuàng)建出來的對象繼承了原型鏈上的方法。而Python則是中規(guī)中矩的基于類(class)的繼承,并天然的支持多態(tài)(polymophine)。
OO in Pyhton
class Employee: 'Common base class for all employees' empCount = 0 ##類成員 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary ## 創(chuàng)建實例 ea = Employee("a",1000) eb = Employee("b",2000) OO in Javascript var empCount = 0; //構(gòu)造函數(shù) function Employee(name, salary){ this.name = name; this.salary = salary; this.empCount += 1; } Employee.prototype.displayCount = function(){ console.log("Total Employee " + empCount ); } Employee.prototype.displayEmployee = function(){ console.log("Name " + this.name + ", Salary " + this.salary ); } //創(chuàng)建實例 var ea = new Employee("a",1000); var eb = new Employee("b",2000);
因為是基于對象的繼承,在Javascript中,我們沒有辦法使用類成員empCount,只好聲明了一個全局變量,當(dāng)然實際開發(fā)中我們會用更合適的scope。注意Javascript創(chuàng)建對象需要使用new關(guān)鍵字,而Python不需要。
除了原生的基于原型的繼承,還有很多利用閉包或者原型來模擬類繼承的Javascript OO工具,因為不是語言本身的屬性,我們就不討論了。
線程模型
在Javascript的世界中是沒有多線程的概念的,并發(fā)使用過使用事件驅(qū)動的方式來進(jìn)行的, 所有的JavaScript程序都運(yùn)行在一個線程中。在HTML5中引入web worker可以并發(fā)的處理任務(wù),但沒有改變Javascript單線程的限制。
Python通過thread包支持多線程。
不可改變類型 (immutable type)
在Python中,有的數(shù)據(jù)類型是不可改變的,也就意味著這種類型的數(shù)據(jù)不能被修改,所有的修改都會返回新的對象。而在Javascript中所有的數(shù)據(jù)類型都是可以改變的。Python引入不可改變類型我認(rèn)為是為了支持線程安全,而因為Javascript是單線程模型,所以沒有必要引入不可改變類型。
當(dāng)然在Javascript可以定義一個對象的屬性為只讀。
var obj = {};Object.defineProperty(obj, "prop", { value: "test", writable: false});
在ECMAScript5的支持中,也可以調(diào)用Object的freeze方法來是對象變得不可修改。
Object.freeze(obj)
數(shù)據(jù)類型
Javascript的數(shù)據(jù)類型比較簡單,有object、string、boolean、number、null和undefined,總共六種
Python中一切均為對象,像module、function、class等等都是。
Python有五個內(nèi)置的簡單數(shù)據(jù)類型bool、int、long、float和complex,另外還有容器類型,代碼類型,內(nèi)部類型等等。
布爾
Javascript有true和false。Python有True和False。它們除了大小寫沒有什么區(qū)別。
字符串
Javascript采用UTF16編碼。
Python使用ASCII碼。需要調(diào)用encode、decode來進(jìn)行編碼轉(zhuǎn)換。使用u作為前綴可以指定字符串使用Unicode編碼。
數(shù)值
Javascript中所有的數(shù)值類型都是實現(xiàn)為64位浮點數(shù)。支持NaN(Not a number),正負(fù)無窮大(+/-Infiity)。
Python擁有諸多的數(shù)值類型,其中的復(fù)數(shù)類型非常方便,所以在Python在科研和教育領(lǐng)域很受歡迎。這應(yīng)該也是其中一個原因吧。Python中沒有定義NaN,除零操作會引發(fā)異常。
列表
Javascript內(nèi)置了array類型(array也是object)
Python的列表(List)和Javascript的Array比較接近,而元組(Tuple)可以理解為不可改變的列表。
除了求長度在Python中是使用內(nèi)置方法len外,基本上Javascript和Python都提供了類似的方法來操作列表。Python中對列表下標(biāo)的操作非常靈活也非常方便,這是Javascript所沒有的。例如l[5:-1],l[:6]等等。
字典、哈希表、對象
Javascript中大量的使用{}來創(chuàng)建對象,這些對象和字典沒有什么區(qū)別,可以使用[]或者.來訪問對象的成員??梢詣討B(tài)的添加,修改和刪除成員??梢哉J(rèn)為對象就是Javascript的字典或者哈希表。對象的key必須是字符串。
Python內(nèi)置了哈希表(dictS),和Javascript不同的是,dictS可以有各種類型的key值。
空值
Javascript定義了兩種空值。 undefined表示變量沒有被初始化,null表示變量已經(jīng)初始化但是值為空。
Python中不存在未初始化的值,如果一個變量值為空,Python使用None來表示。
Javascript中變量的聲明和初始化
v1; v2 = null; var v3; var v4 = null; var v5 = 'something';
在如上的代碼中v1是全局變量,未初始化,值為undefined;v2是全局變量,初始化為空值;v3為局部未初始化變量,v4是局部初始化為空值的變量;v5是局部已初始化為一個字符處的變量。
Python中變量的聲明和初始化
v1 = None
v2 = 'someting'
Python中的變量聲明和初始化就簡單了許多。當(dāng)在Python中訪問一個不存在的變量時,會拋出NameError的異常。當(dāng)訪問對象或者字典的值不存在的時候,會拋出AttributeError或者KeyError。因此判斷一個值是否存在在Javascript和Python中需要不一樣的方式。
Javascript中檢查某變量的存在性:
if (!v ) { // do something if v does not exist or is null or is false } if (v === undefined) { // do something if v does not initialized }
注意使用!v來檢查v是否初始化是有歧義的因為有許多種情況!v都會返回true
Python中檢查某變量的存在性:
try: v except NameError ## do something if v does not exist
在Python中也可以通過檢查變量是不是存在于局部locals()或者全局globals()來判斷是否存在該變量。
類型檢查
Javascript可以通過typeof來獲得某個變量的類型:
typeof in Javascript 的例子:
typeof 3 // "number" typeof "abc" // "string" typeof {} // "object" typeof true // "boolean" typeof undefined // "undefined" typeof function(){} // "function" typeof [] // "object" typeof null // "object"
要非常小心的使用typeof,從上面的例子你可以看到,typeof null居然是object。因為javscript的弱類型特性,想要獲得更實際的類型,還需要結(jié)合使用instanceof,constructor等概念。具體請參考這篇文章
Python提供內(nèi)置方法type來獲得數(shù)據(jù)的類型。
>>> type([]) is list True >>> type({}) is dict True >>> type('') is str True >>> type(0) is int True
同時也可以通過isinstance()來判斷類的類型
class A: pass class B(A): pass isinstance(A(), A) # returns True type(A()) == A # returns True isinstance(B(), A) # returns True type(B()) == A # returns False
但是注意Python的class style發(fā)生過一次變化,不是每個版本的Python運(yùn)行上述代碼的行為都一樣,在old style中,所有的實例的type都是‘instance’,所以用type方法來檢查也不是一個好的方法。這一點和Javascript很類似。 自動類型轉(zhuǎn)換 當(dāng)操作不同類型一起進(jìn)行運(yùn)算的時候,Javascript總是盡可能的進(jìn)行自動的類型轉(zhuǎn)換,這很方便,當(dāng)然也很容易出錯。尤其是在進(jìn)行數(shù)值和字符串操作的時候,一不小心就會出錯。我以前經(jīng)常會計算SVG中的各種數(shù)值屬性,諸如x,y坐標(biāo)之類的,當(dāng)你一不小心把一個字符串加到數(shù)值上的時候,Javascript會自動轉(zhuǎn)換出一個數(shù)值,往往是NaN,這樣SVG就完全畫不出來啦,因為自動轉(zhuǎn)化是合法的,找到出錯的地方也非常困難。 Python在這一點上就非常的謹(jǐn)慎,一般不會在不同的類型之間做自動的轉(zhuǎn)換。 語法 風(fēng)格 Python使用縮進(jìn)來決定邏輯行的結(jié)束非常具有創(chuàng)造性,這也許是Python最獨(dú)特的屬性了,當(dāng)然也有人對此頗具微詞,尤其是需要修改重構(gòu)代碼的時候,修改縮進(jìn)往往會引起不小的麻煩。 Javascript雖然名字里有Java,它的風(fēng)格也有那么一點像Java,可是它和Java就好比雷峰塔和雷鋒一樣,真的沒有半毛錢的關(guān)系。到時語法上和C比較類似。這里必須要提到的是coffeescript作為構(gòu)建與Javascript之上的一種語言,采用了類似Python的語法風(fēng)格,也是用縮進(jìn)來決定邏輯行。
Python風(fēng)格
def func(list): for i in range(0,len(list)): print list[i] Javascript風(fēng)格 function funcs(list) { for(var i=0, len = list.length(); i < len; i++) { console.log(list[i]); } }
從以上的兩個代碼的例子可以看出,Python確實非常簡潔。
作用范圍和包管理
Javascript的作用域是由方法function來定義的,也就是說同一個方法內(nèi)部擁有相同的作用域。這個嚴(yán)重區(qū)別與C語言使用{}來定義的作用域。Closure是Javascript最有用的一個特性。
Python的作用域是由module,function,class來定義的。
Python的import可以很好的管理依賴和作用域,而Javascript沒有原生的包管理機(jī)制,需要借助AMD來異步的加載依賴的js文件,requirejs是一個常用的工具。
賦值邏輯操作符
Javascript使用=賦值,擁有判斷相等(==)和全等(===)兩種相等的判斷。其它的邏輯運(yùn)算符有&& 和||,和C語言類似。
Python中沒有全等,或和與使用的時and 和 or,更接近自然語言。Python中沒有三元運(yùn)算符 A :B ?C,通常的寫法是
(A and B) or C
因為這樣寫有一定的缺陷,也可以寫作
B if A else C
Python對賦值操作的一個重要的改進(jìn)是不允許賦值操作返回賦值的結(jié)果,這樣做的好處是避免出現(xiàn)在應(yīng)該使用相等判斷的時候錯誤的使用了賦值操作。因為這兩個操作符實在太像了,而且從自然語言上來說它們也沒有區(qū)別。
++運(yùn)算符
Python不支持++運(yùn)算符,沒錯你再也不需要根據(jù)++符號在變量的左右位置來思考到底是先加一再賦值呢還是先賦值再加一。
連續(xù)賦值
利用元組(tuple),Python可以一次性的給多個變量賦值
(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7)
函數(shù)參數(shù)
Python的函數(shù)參數(shù)支持命名參數(shù)和可選參數(shù)(提供默認(rèn)值),使用起來很方便,Javascript不支持可選參數(shù)和默認(rèn)值(可以通過對arguments的解析來支持)
def info(object, spacing=10, collapse=1):
... ...
其它
立即調(diào)用函數(shù)表達(dá)式 (IIFE)
Javascript的一個方便的特性是可以立即調(diào)用一個剛剛聲明的匿名函數(shù)。也有人稱之為自調(diào)用匿名函數(shù)。
下面的代碼是一個module模式的例子,使用閉包來保存狀態(tài)實現(xiàn)良好的封裝。這樣的代碼可以用在無需重用的場合。
var counter = (function(){ var i = 0; return { get: function(){ return i; }, set: function( val ){ i = val; }, increment: function() { return ++i; } }; }());
Python沒有相應(yīng)的支持。
生成器和迭代器(Generators & Iterator)
在我接觸到的Python代碼中,大量的使用這樣的生成器的模式。
Python生成器的例子
# a generator that yields items instead of returning a list def firstn(n): num = 0 while num < n: yield num num += 1 sum_of_first_n = sum(firstn(1000000))
Javascript1.7中引入了一些列的新特性,其中就包括生成器和迭代器。然而大部分的瀏覽器除了Mozilla(Mozilla基本上是在自己玩,下一代的Javascript標(biāo)準(zhǔn)應(yīng)該是ECMAScript5)都不支持這些特性
Javascript1.7 迭代器和生成器的例子。
function fib() { var i = 0, j = 1; while (true) { yield i; var t = i; i = j; j += t; } }; var g = fib(); for (var i = 0; i < 10; i++) { console.log(g.next()); }
列表(字典、集合)映射表達(dá)式 (List、Dict、Set Comprehension)
Python的映射表達(dá)式可以非常方便的幫助用戶構(gòu)造列表、字典、集合等內(nèi)置數(shù)據(jù)類型。
下面是列表映射表達(dá)式使用的例子
>>> [x + 3 for x in range(4)] [3, 4, 5, 6] >>> {x + 3 for x in range(4)} {3, 4, 5, 6} >>> {x: x + 3 for x in range(4)} {0: 3, 1: 4, 2: 5, 3: 6}
Javascript1.7開始也引入了Array Comprehension
var numbers = [1, 2, 3, 4]; var doubled = [i * 2 for (i of numbers)];
Lamda表達(dá)式 (Lamda Expression )
Lamda表達(dá)式是一種匿名函數(shù),基于著名的λ演算。許多語言諸如C#,Java都提供了對lamda的支持。Pyhton就是其中之一。Javascript沒有提供原生的Lamda支持。但是有第三方的Lamda包。
g = lambda x : x*3
裝飾器(Decorators)
Decorator是一種設(shè)計模式,大部分語言都可以支持這樣的模式,Python提供了原生的對該模式的支持,算是一種對程序員的便利把。
Decorator的用法如下。
@classmethod def foo (arg1, arg2): ....
關(guān)于Python與Javascript的區(qū)別是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。