你不知道的JS系列【1】- 什麼是作用域

  幾乎所有的編程語言都能夠儲存變量,並且能在之後對這個變量值進行訪問或修改,正是儲存和訪問變量的能力將狀態帶給了程序,那麼,這些變量儲存在哪裡呢?程序需要時又是如何找到他們?這些問題說明需要一套設計良好的規則來儲存變量,並且之後可以方便的找到這些變量,這套規則被稱為作用域。

1、了解編譯原理

  儘管將JS歸類為“動態”或“解釋執行”腳本語言,但事實上它是一門編譯語言。但是與傳統編譯語言不同的是,它不是提前編譯的,編譯結果也不能在分佈式系統中進行移植。JS引擎進行編譯的步驟與傳統的語言非常相似,程序中一段源代碼在執行之前會經歷三個步驟,統稱為“編譯”。

  • 分詞/詞法分析

這個過程會將由字符組成的字符串分解成有意義的代碼塊,這些代碼塊被稱為詞法單元。例如,考慮程序 var a = 2;。這段程序通常會被分解成 為下面這些詞法單元:var、a、=、2 、;。

  • 解析/語法分析

這個過程是將詞法單元流(數組)轉換成一個由元素逐級嵌套所組成的代表了程序語法結構的樹。這個樹被稱為“抽象語法樹”(Abstract Syntax Tree,AST)。var a = 2;的抽象語法樹中可能會有一個叫作VariableDeclaration的頂級節點,接下來是一個叫作 Identifier(它的值是 a)的子節點,以及一個叫作 AssignmentExpression 的子節點。AssignmentExpression 節點有一個叫作 NumericLiteral(它的值是 2)的子節點。

  • 代碼生成

AST轉換為可執行代碼的過程稱被稱為代碼生成,簡單來說就是有某種方法可以將 var a = 2;的AST轉化為一組機器指 令,用來創建一個叫作a的變量(包括分配內存等),並將一個值儲存在a中。

編譯流程如下圖所示:

JS引擎比傳統的編譯語言編譯器複雜很多,在語法分析和代碼生成階段有特定的步驟來對性能進行優化,大部分情況下編譯發生在代碼之前的前幾微秒,在討論作用域背後,js引擎用了各種辦法來保證性能最佳。

Tips:我們平時在寫JS代碼的時候,一個語句結尾要加分號(;),便於JS編譯器編譯。

2、理解作用域

  我們先了解JS編譯過程中幾個名詞,JS引擎,編譯器,作用域。

2.1.名詞介紹

  • JS引擎:從頭到尾負責整個JS程序編譯過程。
  • 編譯器:負責語法分析及代碼生成等。
  • JS引擎:負責收集並維護由所有聲明的標識符(變量)組成的一系列查 詢,並實施一套非常嚴格的規則,確定當前執行的代碼對這些標識符的訪問權限。

2.2.變量賦值

對於var a=2;這段代碼,我們認為這就是申明一個為變量a且初始值為2,實際上,JS引擎認為這裡有兩個完全不同的申明,一個由編譯器在編譯時處理,另一個則由引擎在運行時處理。

處理過程分為兩步:

1.遇到var a,編譯器會詢問作用域是否已經有一個該名稱的變量存在於同一個作用域的集合中。如果是,編譯器會忽略該聲明,繼續進行編譯;否則它會要求作用域在當前作用域的集合中聲明一個新的變量,並命名為a。

2.接下來編譯器會為引擎生成運行時所需的代碼,這些代碼被用來處理a = 2這個賦值操作。引擎運行時會首先詢問作用域,在當前的作用域集合中是否存在一個叫作a的變量。如果是,引擎就會使用這個變量;如果否,引擎會繼續查找該變量。

如果引擎最終找到a變量,就會將2賦值給它。否則就拋出異常。

Tips:聲明提前(hoist)-JS引擎在創建變量時,會將該變量提升到當前作用域的最前面。

總結:變量的賦值操作會執行兩個動作,首先編譯器會在當前作用域中聲明一個變量(如果之前沒有聲明過),然後在運行時引擎會在作用域中查找該變量,如果能夠找到就會對它賦值。

2.3.LHS查詢&RHS查詢

編譯器在編譯過程中的第二步生成了代碼,引擎在執行時,會通過查找變量a來判斷它是否已經聲明過。當變量出現在賦值操作的左側時進行LHS查詢,當變量出現在右側時進行RHS查詢。

console.log(a); //對a的引用時RHS引用,這裏沒有對a賦予任何值,需要查找a的值。

a=2; //對a的引用是LHS引用,因為這裏不關心a的值等於多少,只想為 =2 這個賦值操作找到一個目標(變量a);

LHS和RHS的含義是“賦值操作的左側或右側”並不一定意味着就是“= 賦值操作符的左側或右側”。賦值操作還有其他幾種形式,因此在概念上最好將其理解為“賦值操作的目標是誰(LHS)”以及“去找到XX變量的值,誰是賦值操作的源頭(RHS)”。

3、作用域嵌套

  作用域是根據名稱查找變量的一套規則。實際情況中,通常需要同時顧及幾個作用域。 當一個塊或函數嵌套在另一個塊或函數中時,就發生了作用域的嵌套。因此,在當前作用 域中無法找到某個變量時,引擎就會在外層嵌套的作用域中繼續查找,直到找到該變量, 或抵達最外層的作用域(也就是全局作用域)為止。

參考以下代碼:

var name='peer';
function sayHello(){
  alert('hello '+ name)
}
sayHello();
// 對name的RHS引用無法在函數sayHello完成,但是可以在上一級作用域中完成。

把作用域比喻成一個建築如下圖所示:

LHS和RHS引用都會在當前樓層進行查找,如果沒有找到,就會坐電梯前往上一層樓,如果還是沒有找到就繼續向上,以此類推。一旦抵達頂層(全局作用域),可能找到了你所需的變量,也可能沒找到,但無論如何查找過程都將停止。

4、總結

  作用域是一套規則,用於確定在何處以及如何查找變量(標識符)。LHS和RHS查詢都會在當前執行作用域中開始,如果有需要就會向上級作用域繼續查找目標標識符,這樣每次上升一級作用域,最後抵達全局作用域,無論找到或沒找到都將停止。不成功的RHS 引用會導致拋出ReferenceError異常。不成功的LHS引用會導致自動隱式地創建一個全局變量(非嚴格模式下),掌握這些基本作用域知識能使我們更深入理解JS引擎的編譯過程來編寫更高性能的代碼。

參考資料:
《你不知道的JavaScript》

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※專營大陸空運台灣貨物推薦

※台灣空運大陸一條龍服務

※評比彰化搬家公司費用,南投搬家公司費用收費行情懶人包大公開

※彰化搬家費用,南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

新冠疫情打亂中國貿易 肯亞漁民收入好轉

摘錄自2020年3月24日中時報導

武漢肺炎全球大流行,造成國際物流與貿易的停滯,不過這肯亞漁民來說,卻帶來了意想不到的好處。由於現在中國大陸的冷凍魚片無法進口,因此當地轉而購買肯亞漁民在維多利亞湖捕獲的鮮魚。

路透社報導,中國大陸貿易力量的強勢,使得肯亞當地漁民處境辛苦,根據國際貿易中心(International Trade Center)的數據,以2018年為例,中國大陸銷售給肯亞價值2320萬美元的冷凍魚,佔領了肯亞的魚獲市場,幾乎所有的魚類進口都來自中國大陸。長期以來,肯亞漁民一直抱怨,廉價進口的冷凍漁,幾乎扼殺了當地漁民生計。

然而,武漢肺炎的蔓延,中止了中國大陸的進口業,很快魚肉供應緊缺,使得肯亞消費者轉向購買當地的魚類,對當地漁民而言是個好消息。但是,從較大的經濟角度來看,接下來肯亞會遇到供不應求的麻煩,因為當地漁獲量僅能提供消費量的三分之一。

農林漁牧業
環境經濟
國際新聞
肯亞
武漢肺炎
漁民

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※專營大陸空運台灣貨物推薦

※台灣空運大陸一條龍服務

※評比彰化搬家公司費用,南投搬家公司費用收費行情懶人包大公開

※彰化搬家費用,南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

始於野味的全球疫情 中國仍鼓勵熊膽入藥治武漢肺炎

環境資訊中心綜合外電;黃鈺婷 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※專營大陸空運台灣貨物推薦

※台灣空運大陸一條龍服務

※評比彰化搬家公司費用,南投搬家公司費用收費行情懶人包大公開

※彰化搬家費用,南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

阿里汽車發佈「車秒貸」2.0

4月24日,阿里在北京車展前日發佈了「車秒貸」2.0版本。阿里汽車事業部總經理王立成對該產品的描述是「拿起手機,最快20秒就可以完成最高上限為20萬人民幣(下同)的貸款額度,如果恰好你所在的品牌4S店有現車,手續辦理後就可以直接開走。」車秒貸升級2.0後,通過螞蟻金服旗下的網商銀行的大資料風控模型,車秒貸授信用戶從此前的5000萬擴大到1億。

在車秒貸體系中,網商銀行向汽車金融公司輸出大資料風控模型,説明汽車金融公司來甄別風險、篩選用戶。從車秒貸1.0版本發佈起,網商銀行聯合東風標緻雪鐵龍金融、海馬財務、創富租賃等7家汽車金融公司,全國累計申請車秒貸的消費者超過6萬名。目前,網商銀行正與廣汽匯理、郵政儲蓄銀行、通用金融、日產金融、一汽金融、奇瑞徽銀等多家金融公司洽談合作,進一步擴大業務規模。

據悉,廣汽匯理、郵政儲蓄銀行預期在今年5月正式上線車秒貸產品,其中,廣汽匯理最高貸款額度或將超50萬,屆時,享受車秒貸產品的車型價位也將會全面提升。

王立成介紹說,車秒貸用戶線上上無需任何材料,只要登錄天貓移動用戶端,選取車型和貸款方案,等待極短時間後即可得到一個確定給到的貸款額度,最快一筆授信審批通過只需要20秒,授信額度最高可達汽車指導價的80%。

目前接入「車秒貸」的品牌廠商有奧迪、東風日產、東風雪鐵龍、東風標緻、別克、通用雪佛蘭、吉利、奇瑞、力帆、DS、海馬汽車等33家,已上線的車型共75款乘用車,價格區間為10~30萬 。其中,10~15萬的汽車占比超80%。

汽車廠商之所以願意加入「車秒貸」,一方面是看中這種新型的線上放款模式更加高效,也看中電商平臺能否帶來更多線下無法觸及的用戶。在之前的運作中,阿里汽車發現,線上線下客戶有明顯的差異化,一部分按照線下標準無法成功申請貸款的客戶(如無車或無房),在車秒貸的平臺上獲得貸款的機率更大。

阿里巴巴提供的資料顯示,上海、武漢、蘇州、南京、北京為車秒貸消費密集的城市。但從趨勢上看,通過大資料預測,未來77%的新車需求會在三四五線城市。從消費年齡上看維度較廣,70、80、90後的為主流用戶群體。其中,90後大學畢業生接受度最高。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※專營大陸空運台灣貨物推薦

※台灣空運大陸一條龍服務

※評比彰化搬家公司費用,南投搬家公司費用收費行情懶人包大公開

※彰化搬家費用,南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

Mybatis精講(二)—生命周期

目錄

回顧

  • 上一章節我們通過xml和代碼的方式實現了Mybatis環境的配置。代碼方式只是簡單介紹下。我們也知道我們大部分情況使用的是xml方式的配置。在實際開發中我們那樣開發顯然是不合理的。

  • 上章節提到的組件显示不可能每次執行sql都要重新創建的。這樣性能上肯定是過不去的。今天我們就來簡單聊聊SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper這些組件的生命周期吧。

SqlSessionFactoryBuilder

  • 通過觀察分析這個類我們就知道既然是Builder模式的類,那他的作用就是構建起(孵化器).換句話說這個類不是那麼的重要,因為他唯一的作用就是孵化SqlSessionFactory。在Spring與Mybatis整合的框架中,我相信Spring一定是在構建了SqlSessionFactory之後就將這個類進行回收了。因為後面就不需要了。這裏純屬個人猜想。

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
  try {
    XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
    return build(parser.parse());
  } catch (Exception e) {
    throw ExceptionFactory.wrapException("Error building SqlSession.", e);
  } finally {
    ErrorContext.instance().reset();
    try {
      inputStream.close();
    } catch (IOException e) {
      // Intentionally ignore. Prefer previous error.
    }
  }
}
  • 上面就是我們通過加載xml配置文件的源碼。我們不難發現build核心是通過XMLConfigBuilder這個類去負責解析mybatis-config.xml配置文件並生成Configuration對象。

SqlSessionFactory

  • 看名字就知道是工廠模式。在這裏我們可以把他看成數據庫連接池。既然是工廠就肯定得有產品。SqlSessionFactory的產物就是SqlSession。SqlSession是與數據庫的一次連接。管理數據庫的連接的自然就是連接池了。
  • Mybatis中使用的SqlSessionFactory是DefaultSqlSessionFactory 。 以連接池的角度看待我們不難推斷出SqlSessionFactory應該是個單例 。SqlSessionFactory對應的是數據庫。一個數據庫原則上應該對應一個SqlSessionFactory來管理。這點在Spring中正好無縫連接。把SqlSessionFactory交由spring管理。spring默認是單例模式bean.

openSessionFromDataSource

  • SqlSessionFactory通過openSession方法獲取SqlSession.SQLSession實際上可以看做是一次數據庫的連接。下面我們通過源碼的方式去看看工廠是如何生產SqlSession的。
<!--定義數據庫信息,默認使用development數據庫構建環境-->
<environments default="development">
    <environment id="development">
        <!--jdbc事物管理-->
        <transactionManager type="JDBC"></transactionManager>
        <!--配置數據庫連接信息-->
        <dataSource type="POOLED">
            <property name="driver" value="${database.driver}"/>
            <property name="url" value="${database.url}"/>
            <property name="username" value="${database.username}"/>
            <property name="password" value="${database.password}"/>
        </dataSource>
    </environment>
</environments>

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
  //定義一個事物對象
  Transaction tx = null;
  try {
    //通過配置對象獲取事先配置好的環境對象   這裏對應了xml中的environments標籤  。environments默認develop.所以是develop的environment
    final Environment environment = configuration.getEnvironment();
    //通過環境獲取事物。在environment里配置了JDBC類型的事物==JdbcTransactionFactory;如果沒有配置則默認採用ManagedTransactionFactory
    final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
    //構建事物對象 , 實際就是屬性的賦值
    tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
    //獲取執行器 BatchExecutor、ReuseExecutor、SimpleExecutor , 選擇SimpleExecutor
    //因為默認有緩存,這裡會用CachingExecutor包裹原始Executor , 之後會加載各種插件
    final Executor executor = configuration.newExecutor(tx, execType);
    //返回DefaultSqlSession。寫死
    return new DefaultSqlSession(configuration, executor, autoCommit);
  } catch (Exception e) {
    closeTransaction(tx); // may have fetched a connection so lets call close()
    throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
  } finally {
    ErrorContext.instance().reset();
  }
}

Executor

  • Mybatis的數據庫執行器。Mybatis提供了一共四中Executor.這裏嚴格意義上應該說是三種 BatchExecutor、ReuseExecutor、SimpleExecutor。還有一個CachingExecutor。這裏為什麼不把他算上了。因為這個是一個全局的開關。在settings標籤的cacheEnabled設置的。說道這個標籤大家都知道這個就是二級緩存的開關。所以這裏CachingExecutor就不做介紹了。
  • SimpleExecutor是一種常規執行器,每次執行都會創建一個statement,用完后關閉。
  • ReuseExecutor是可重用執行器,將statement存入map中,操作map中的statement而不會重複創建statement。
  • BatchExecutor是批處理型執行器,doUpdate預處理存儲過程或批處理操作,doQuery提交並執行過程。
  • 關於Executor的選取也是在settings標籤控制的。defaultExecutorType。 默認是simple

SqlSession

  • 每個線程都有一個屬於自己的Sqlsession對象。這裏我們看成是一次Connection。他的生命周期應該是一次完成的事物處理過程。他是一個線程不安全的對象。在多線程操作的時候我們需要注意事物的隔離級別。我們操作時需要注意的是每次處理玩需要將他關閉。否則會造成資源浪費。在Mybaits中已經通過finnally把我們將他釋放了。

Mapper

  • Mapper是一個接口,我們可以將xml看成他的一個實現類。這裏的實現類虛化。通過Java代碼的調用實際將xml對應的sql發送給數據庫並獲取數據結果。

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
  final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
  if (mapperProxyFactory == null) {
    throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
  }
  try {
    return mapperProxyFactory.newInstance(sqlSession);
  } catch (Exception e) {
    throw new BindingException("Error getting mapper instance. Cause: " + e, e);
  }
}
  • 通過上述代碼我們能夠發現。在獲取Mapper的時候先通過類型看是否被註冊了。然後根據類別獲取代理實例。

總結

  • 關於生命周期其實沒什麼重點。這一章節也比較簡單。我們只需要知道我們最終需要的Mapper。然後是如何從配置到獲取Mapper.這過程中哪些是全局的。哪些又適合做成復用的。

# 加入戰隊

微信公眾號

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※專營大陸空運台灣貨物推薦

※台灣空運大陸一條龍服務

※評比彰化搬家公司費用,南投搬家公司費用收費行情懶人包大公開

※彰化搬家費用,南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

擺脫貴金屬光催化劑,澳洲利用奈米晶體降低綠能製氫成本

摘錄自2018年9月29日科技新報報導

澳洲科廷大學發表在《Advanced Materials》的研究指出,已成功研發出不含任何貴金屬與有毒金屬的奈米晶體,可當作環保型光催化劑,為光電解水製氫助一臂之力。該奈米材料由低成本、原料豐富的元素製成,可為能源產業與工業提供更永續、便宜的燃料來源。

科廷大學功能分子與介面研究所教授 Guohua Jia 表示,過去為了打造高效光電解水製氫設備,不得不使用鎘基半導體與鉑、銥和釕等貴金屬來製造光催化劑,雖然成功提升光轉換效率,但這也是邁向大規模綠能製氫的主要阻礙之一,該研究將有助於光電解水製氫與氫燃料車大規模發展。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※專營大陸空運台灣貨物推薦

※台灣空運大陸一條龍服務

※評比彰化搬家公司費用,南投搬家公司費用收費行情懶人包大公開

※彰化搬家費用,南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

萬向電動車有望2017年進入中國市場

日前,有媒體報導稱,萬向收購菲斯科之後的首款車型將命名為Karma Revero,將由萬向旗下的Karma公司在美國生產,計畫7月或8月正式亮相,年底前開始銷售。如果不出意外,大約到2017年,將以進口方式正式進入中國市場銷售。

雖然這款車的價格還沒有確定,但是其競爭對手應該就是特斯拉的Model 3。

萬向製造的首款電動乘用車不僅將競爭對手指向特斯拉,其銷售模式也有望複製特斯拉。目前,萬向正在考慮是否使用直銷的模式來進行銷售。

同時,萬向還模仿特斯拉的管理手段,從通用等跨國公司挖掘高管,負責產品研發、財務、行銷等部門。據瞭解,目前,萬向在美國加州建設的電動車工廠,已進入生產線的試運行階段,將於6月投產。

靜待生產資質

萬向之所以在美國建廠生產,不僅是為兌現收購菲斯科時的承諾,而且也是無奈之舉。

資料顯示,萬向能夠順利收購菲斯科,是因為其在向美國政府提出的《復興計畫》中明確,將在美國建廠解決一些當地就業問題。

更重要的是,目前,萬向並沒有獲得在國內生產電動乘用車的生產資質。

實際上,萬向收購A123和菲斯科後,其轉型計畫就已啟動,在先後獲得專用車和客車生產資質後,電動專用車和電動客車已投入使用。業內有觀點認為,雖然製造電動乘用車和電動商用車有一定差距,但在供應鏈方面可以實現部分共用。

同時,有消息稱,此前萬向已製造了少量電動乘用車,並在杭州試運行,運行的資料和資料也會成為萬向電動乘用車量產的重要支撐。

由此來看,未來,萬向國內工廠的生產條件,以及依託A123電池技術、菲斯科車身技術、寶馬動力總成技術打造的電動車能夠獲得我國相關部門的認可,獲得電動乘用車生產資質,其電動乘用車計畫也將快速成型。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※專營大陸空運台灣貨物推薦

※台灣空運大陸一條龍服務

※評比彰化搬家公司費用,南投搬家公司費用收費行情懶人包大公開

※彰化搬家費用,南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!