[譯文]透過Python反補ES6

原文:How Python can help you learn ES6javascript

「你學ES6了嗎?「前端

每當被人這麼問的時候,我總會感到有一種壓力。事實上,我在Python的幫助下學習了ES6。很奇怪對嗎?事實證實,這兩種語言在語法上有不少是相通的,在某種程度上它們實際上是大手拉小手地在發展。java

在這篇文章中,你將會看到Python是怎樣幫助我學習ES6的。python

Python與ES6的基本差別

在咱們探索JavaScriptPython之間的類似以前,咱們先看一下二者之間的差別。例如,在JavaScript中,空格在編譯過程不會產生影響,但在Python中卻會形成報錯。Python是依賴縮進去區分語句分組的。es6

JavaScriptPython中基本數據類型的初始值也有很大不一樣。查看下面表格詳細瞭解兩種語言的基本類型。你會發現除了BooleanNothing的值有一些類似以外,其餘是徹底不一樣的。 編程

最後一個須要注意的是JavaScript容許類型強制。下面的代碼塊演示了JavaScript將數字強制轉換爲字符串,這在Python中是不可能的: 數組

函數或者...方法?

JavaScriptPython中,函數和條件語句的結構很是類似,例如:閉包

// JS
function drSeuss(catInTheHat, thing1, thing2) {
  if (catInTheHat == true &&
    thing1 == true &&
    thing2 == true) {
    console.log('is cray');
  } else if (catInTheHat != true) {
    console.log('boring');
  } else {
    console.log('so boring');
  }
}
複製代碼
# PY
def dr_seuss(cat_in_the_hat, thing1, thing2):
  if cat_in_the_hat == True and
    thing2 == True and
    thing2 == True:
    print 'is cray'
  elif cat_in_the_hat != True:
    print 'boring'
  else:
    print 'so boring'
複製代碼

我沒有過多考慮這個問題(函數仍是方法),但對於JavaScript,「方法」的概念一般是構建在語言規範上的方法。Eg:Function.prototype.apply()app

摘自MDN:編程語言

在不少方面函數和方法是相同的,除了下面兩點關鍵區別:

  • 方法會隱式地傳遞調用它的對象(譯者注:好比能夠經過this訪問對象)
  • 方法能夠對包含在類裏面的數據進行操做

由於JavaScript中不存在真正的類,下面函數和方法的例子僅用Python演示(ES6的類稍後再介紹)

# PY
def fish_and_chips():
  ingredients = ['fish', 'potatoes', 'batter']
  print 'cooking %s together' % (', '.join(ingredients))

# cooking fish, potatoes, batter

class Baking(object):
  def __init__(self, supplies):
    self.supplies = supplies

  def bakewell_tart(self):
    ingredients = ['almonds', 'raspberry', 'icing sugar']
    print self
    print 'baking %s' % (', '.join(ingredients))

# <__main__.Baking object at 0x10d6e0510>
複製代碼

OK,讓咱們看看 Python是如何促使我學習更多ES6的知識的!

塊級做用域

當我第一次學習JavaScript時(在「古老的」ES5時代),我認爲語言中的不少結構都建立了做用域,我還認爲條件語句中的塊建立了做用域,但最後發如今JavaScript中只有函數在建立做用域。

經過ES6中引入的constlet,咱們擁有了塊級做用域:

// JS
function simpleExample(value) {
  if (value) {
    var varValue = value;
    let letValue = value;
    console.log(varValue, letValue); // value value
  }
 
  // if塊裏面定義的varValue會提高到整個function
  console.log(varValue); // value
 
  // letValue不會提高到if塊以外
  console.log(letValue); // Uncaught ReferenceError: letValue is not defined
}
複製代碼

還有什麼能在JavaScriptES6Python中建立做用域?它們使用什麼類型的做用域?查看下面這個表格:

模板字符串

我常常認爲模板字符串是完形填空,句子中缺乏單詞,你能夠往這些空格填入任何你想寫的內容,只須要保證它符合指定的單詞類型便可:名詞、動詞、形容詞等。

完形填空讀起來像:

mothers sit around burping. Last summer, my little brother fell in a/an hairdo and got poison palmtree all over his butt. My family is going to Winsconsin, and I will..

與完形填空類似,模板字符串裏面容許嵌入表達式。

是的,這些在ES6發佈以前就已經存在於Python中了。實際上我已經先學習了Python的字符串插值,這使得我更容易理解ES6的模板字符串。

// JS
let exclamation = 'Whoa!';
let sentence = `They are really similar to Python.`;
 
console.log(`Template Literals: ${exclamation} ${sentence}`);
// output: Whoa! They are really similar to Python.
複製代碼
# PY
print '.format(): {} {}'.format('Yup.', 'Quite!')
# output: .format(): Yup. Quite!
複製代碼

默認參數

是的,Python一直有這個特性。設置函數參數的默認值,這對於避免參數缺失引發報錯很是有效,隨着ES6的出現,JavaScript也引入了設置參數默認值。

// JS
function nom(food="ice cream") {
  console.log(`Time to eat ${food}`);
}
 
nom(); // Time to eat ice cream
複製代碼
# python
def nom(food="ice cream"):
  print 'Time to eat {}'.format(food)
 
nom() # Time to eat ice cream
複製代碼

rest參數 & *args

Rest參數語法容許咱們將不肯定數量的參數表示爲數組。在Python裏面叫作*args,也是我在ES6以前就已經學習的知識。

請查看這兩種語言是如何將參數封裝在一個有序包裏面的:

// JS
function joke(question, ...phrases) {
  console.log(question);
  for (let i = 0; i > phrases.length; i++) {
    console.log(phrases[i]);
  }
}

let es6Joke = "Why does JS single out one parameter?"
joke(es6Joke, "Because it doesn't", 'really like', 'all the REST of them!');
// output: 
// Why does JS single out one parameter?
// Because it doesn't
// really like
// all the REST of them!
複製代碼
# PY
def pirate_joke(question, *args):
  print question
  for arg in args:
    print arg
 
python_joke = "What's a Pyrate's favorite parameter?"
 
pirate_joke(python_joke, "*args!", "*arrgs!", "*arrrgs!")
 
# What's a Pyrate's favorite parameter?
# *args!
# *arrgs!
# *arrrgs!
複製代碼

如今咱們來看看原型繼承。ES6的類實際是基於ES5的原型鏈實現的語法糖,所以,咱們能夠用ES6類作的事情與用ES5原型作的事情沒有太大的不一樣。

Python有內置的類,容許咱們能夠快速而簡單地進行面向對象編程。但JavaScript中的原型總令我很是困惑,不過將PythonES6的類型放在一塊對比確實對我頗有意義。

MDN對JavaScript的原型作了解釋:

當談到繼承時,JavaScript 只有一種結構:對象。每一個實例對象( object )都有一個私有屬性(稱之爲 __proto__ )指向它的構造函數的原型對象(prototype)。該原型對象也有一個本身的原型對象( __proto__ ) ,層層向上直到一個對象的原型對象爲 null。根據定義,null 沒有原型,並做爲這個原型鏈中的最後一個環節。

讓咱們看一下基於原型鏈的ES6的類:

// JS
class Mammal {
  constructor() {
    this.neocortex = true;
  }
}
 
class Cat extends Mammal {
  constructor(name, years) {
    super();
    this.name = name;
    this.years = years;
  }
 
  eat(food) {
    console.log('nom ' + food);
  }
}
 
let fryCat = new Cat('Fry', 7);
fryCat.eat('steak');
複製代碼
# PY
class Mammal(object):
  neo_cortex = True
 
class Cat(Mammal):
  def __init__(self, name, years):
    self.name = name
    self.years = years
 
  def eat(food):
    print 'nom %s' % (food)
 
fry_cat = Cat('Fry', 7)
fry_cat.eat('steak')
複製代碼

ES6的類和ES5原型鏈之間的一個重大區別是:使用類比使用原型鏈更容易實現繼承。這跟python的結構很是類似,真棒!

吶!你看到了,一堆關於Python如何幫助我學習ES6的例子。一般在編程語言中,存在許多差別,但也有不少類似,正是這些類似的東西,幫助了咱們更容易地學習新語言!

譯者說

JavaScriptPython同爲腳本語言界的翹楚,在各自的領域稱霸一方。若是你同時學習了PythonJS,回過頭細細對比下,你會驚奇地發現二者居然如此高度類似,JavaScript彷佛一直在向Python「看齊」。

你會發現,基礎數據類型方面極類似:都有SetList對應ArrayDictionary對應Map;都有閉包和匿名函數的概念以及不少的JavaScript開源庫都推崇去分號的寫法...

語法層面的類似,有助於咱們快速掌握ES6,將對Python的理解應用到JavaScript上,也有助於咱們理解ES6的設計思想!

想到這,有一種抑制不住的興奮,對於咱們這些前端er,學習Python其實也是個優點。咱們也能夠像做者那這樣,透過ES6,反過來輔助Python的學習。

不說那麼多,我要去寫python了......😅😅😅

相關文章
相關標籤/搜索