曼谷空中動物園 環境惡劣成動物空中監獄

摘錄自2019年12月2日公視報導

泰國曼谷一間百貨商場,表面平凡無奇。低樓層賣男女服飾,但商場的頂樓,竟是一座空中動物園,裡面關了多達200隻動物,環境惡劣,是一座名符其實的「空中監獄」。裡頭有母猩猩,一關超過30年,處境孤單淒涼,被認為是全世界最悲傷的動物園之一。動保團體要求關閉動物園,還給動物們應有的生存尊嚴。

泰國曼谷的pata百貨購物中心,六樓跟七樓的頂樓,是已被判定違法的動物園。這隻被關在鐵籠子裡的母猩猩,泰國的譯名是白色小蓮花,小蓮花雖然有人餵食照顧,但生活環境惡劣,充滿惡臭。最可憐的是,牠被關在這座空中動物園已整整36年,過著完全失去自由的生活。為了解救小蓮花,動保團體本周再次出面呼籲,儘快關閉這座空中監獄。他們強調,殘忍的對待動物,決不等於提供人們娛樂的方式。善待動物組織成員奧莉維亞表示,「Pata動物園是我們在亞洲遇見過最糟糕的情況,很顯然,一座百貨公司根本不是該有動物存在的場所。」

母猩猩小蓮花,1983年起被關進這座大鐵籠,從此就沒再踏出外面的世界。她在籠子裡打滾,拔毛,流淚的畫面陸續在網路上流傳。動保人士研判,小蓮花已出現精神疾病,其他包括紅毛猩猩,跟狐猴等動物,也都出現焦躁的情緒反應,看了令人鼻酸。善待動物組織成員奧莉維亞說:「這隻猩猩從1983年起就關在這裡,還有一隻紅毛猩猩也被關這很久了,都已經出現精神疾病的症狀,意味著長期被關著心理已經受創。」

事實上,這間pata百貨公司頂樓的動物園,早已多次遭人檢舉。泰國2014年通過動保法,pata動物園2015年更被判定違反動保法,但當局依舊持續核發經營執照,法律形同虛設。至於動物園的經營者也有話要說,不僅強調當初開設動物園時都諮詢過專業意見,也把小蓮花當作自己的女兒照顧,更堅稱網路上流傳小蓮花看似悲傷的表情,其實那是猩猩原本的長相,被外界誤解。不過也坦承,目前要將裡面200多隻動物移往更大的飼養空間,在經費上確實有困難。pata動物園經營者坎尼特表示,「我們有打算將動物移走,因為我們的空間確實有限。我們也打算繼續飼養這些動物,我們有計畫將動物園移往自然的開放空間,但要這麼做的同時,我也必須承認動物園是社會企業,並非以營利投資為主,因此其他的因素(經費)是最主要的問題。」

但實際走訪過這座空中監獄的泰國動物專家強調,pata動物園的存在是泰國的恥辱,猩猩的基因有超過96%跟人類相似,也跟人類有一樣的情感,被關在籠子裡36年,對他們而言可以想像是無比的折磨與煎熬。不僅是小蓮花,其他動物被關在密不通風,底下又是空氣汙染的空間,失去自由,也磨滅了動物的天性。動保團體大聲疾呼泰國政府,拿出鐵腕手段與同理心,盡快關閉這座空中動物園,早日將動物們移往適合的環境,還給他們原本就該擁有的生存尊嚴。

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

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務

2020年代中期 再生能源將取代燃煤成發電主力 | 解讀《 2019年世界能源展望》報告3/3

環境資訊中心外電;姜唯 翻譯;林大利 審校;稿源:Carbon Brief 前言:國際能源署(IEA)2019年《世界能源展望》報告達810頁,其特點在於描繪出「承諾政策情境」(Stated Policies Scenario, STEPS),反映政府已經說出口的政策的效果。相對地,報告的「永續發展情境」(Sustainable Development Scenario, SDS)描繪出更積極朝向友善氣候的條件,若在此情境下,全球升溫有50%機率限制在1.65°C之內。
太陽光電板設置作業。照片來源:

超大型太陽能?

()根據IEA的STEPS情境,到2020年代中期,再生能源將取代煤炭成為最大的電力來源。到2040年,低碳能源將滿足全世界一半以上的電力需求,在SDS情境中甚至達到85%。

(不過,值得重申的是,今日電力僅佔總能源消耗的1/5,到2040年,這個數字在STEPS中將上升到24%,在SDS中將上升到31%。這是僅靠再生能源無法解決氣候挑戰的諸多原因之一。)

值得注意的是,今年的STEPS中,再生能源的前景大幅提高,2040年的太陽能總量提高了23%,風能提高了11%。非水電再生能源的增加了8%(下圖中的紅線),在2030年代後期超過了煤炭。

再生能源產量的成長大部分被增加的需求用掉,表示其他來源的發電相對不受影響。Carbon Brief的分析顯示,相對於去年的展望報告,2040年需求成長主要來自於2018基準年的需求增加,年複合成長率為2%。

各種能源全球發電量(十億度,TWh,即太瓦時)。 WEO 2019的歷史資料和STEPS以實線標示,WEO 2018以虛線標示。資料來源:國際能源署《 2019年世界能源展望》及上一版。Carbon Brief用Highcharts繪製。

WEO解釋:

由於成本持續降低,太陽光電成為2020年中國和印度最具競爭力的電力來源。到2030年,太陽能在歐盟和美國與其他能源的差距將大大縮小。在STEPS之下,2018年到2030年全球太陽光電的平均成本(均化成本)下降了約50%。

此外WEO強調,風能和太陽能的成本下降使「直接從煤炭轉往再生能源有更堅強的經濟理由」,而不是將天然氣當作通往低碳能源的過渡能源。

它還提到,美國新公布的海上風電競標,歐盟各地的競標價格低於預期,中國再生能源零補貼的趨勢也有所減弱。

IEA最近發表了一份關於海上風電前景的深度探討報告。IEA認為海上風電的技術潛力可滿足當今電力需求的好幾倍,成本更將在十年內與化石燃料相當。

IEA表示,隨著風能和太陽能在電力領域的發展,將面臨越來越多的挑戰:「政策制定者和監管機構必須迅速採取行動,以跟上技術變革的步伐和不斷成長的需求,以確保電力系統的靈活運作。」

太陽能傳說

儘管如前所述,今年的STEPS大幅上修2040年太陽能產出,但與其他預測相比,IEA對該技術的展望相對保守。

IEA對太陽能前景的預測受到許多批評。如下一個圖表的藍色色塊,IEA連續好幾個版本的前景報告上修太陽能容量成長。

(請注意,圖表顯示的是扣除退役後的淨增加。由於絕大多數太陽能容量的增加發生在近期,因此最初期可以忽略不計。IEA假設到2040年將有298GW的太陽能容量退役,也就是說在2030年代和之後,實際增加量會增加,而不是像下面的淨增加量表所示的那樣相對平穩。)

全世界太陽能年淨增加量(百萬瓩,GW)。紅色表示2019年的歷史資料和預估,而藍色表示各版本WEO的中心觀點預測。 WEO 2019 STEPS以黑色標示。資料來源:國際能源署《 2019年世界能源展望》和該報告的過去版本。Carbon Brief使用Highcharts繪製。

IEA將這些連續上修歸因於政府政策隨時間變化,尤其是中國的變化,中國是世界上最大的太陽能市場。

IEA解釋,繼2018年太陽能增長略顯疲軟後,「重新加速年度太陽能佈署,並加大力道確保將太陽能所發電力穩定進入電力系統,對於實現氣候目標和其他永續發展目標至關重要」 。

IEA相對保守的太陽能前景預測似乎部分取決於其對各種發電技術的標準加權平均資本成本的計算,視每個國家的發展階段,設定在7%到8%。

正如IEA對海上風電所做的估算,這可能對特定計畫的均化電力成本(LCOE)產生非常大的影響。 (歐洲海上風電的實際資本成本已接近4%,足以將其LCOE從每千度(MWh)140美元左右降低到100美元。)

另一個因素可能是IEA將重點放在系統「價值」上,而不是前期成本。IEA在WEO 2018發展出的「VALCOE」指標是這麼說明的。

IEA表示,降低成本並不保證能維持競爭力,「因為隨著其發電比例的增加,太陽能的系統價值相對於系統平均值而言往往會下降」。

因為太陽能輸出集中在每天中午時段,容量增加使供電增加,也部分影響了既有太陽能板創造的電價。

有些預測報告同樣考慮了這些因素,卻看好太陽能發電量的增長。到2040年,IEA的STEPS之下每年新增的太陽能不足140GW,而彭博新能源基金會(BloombergNEF)的新能源展望報告則認為,屆時新增的太陽能將超過300GW。這個數字與IEA的SDS中的佈署相同。

彭博新能源基金會還更看好風電容量的增長,預測到2050年,煤炭的電力輸出將下降一半,而非像IEA STEPS所預測的保持穩定。(系列專文3/3)

‘Profound shifts’ underway in energy system, says IEA World Energy Outlook (3/3) by Simon Evans

Supersized solar?

Elsewhere in the electricity sector, the IEA’s central STEPS sees renewables surging and overtaking coal as the largest source of power . By 2040, low-carbon sources would be supplying more than half of the world’s electricity needs – rising to 85% in the SDS.

(It is worth reiterating, however, that electricity accounts for only a fifth of final energy consumption today, a figure that rises to 24% by 2040 in the STEPS or 31% in the SDS. This is one of the many reasons why renewables alone cannot solve the climate challenge.)

Notably, this year’s STEPS has significantly increased the prospects for renewables, raising the solar total for 2040 by 23% and that for wind by 11%. This revision, adding 8% to the total for non-hydro renewables (red lines in the chart, below), sees them overtaking coal in the late 2030s.

The increase in expected renewable output is mostly absorbed by higher demand, meaning that generation from other sources is relatively unaffected. Carbon Brief analysis suggests the increase in 2040 demand relative to last year’s outlook is mainly due to higher demand in the base year 2018, which gets compounded by 2% annual growth.

Global electricity generation, by fuel, terawatt hours. Historical data and the STEPS from WEO 2019 are shown with solid lines while the WEO 2018 is shown with dashed lines. Source: IEA and last year’s edition. Chart by Carbon Brief using .

The WEO explains:

“As a result of continued cost reductions, solar PV becomes the most competitive source of electricity in 2020 in China and India, and largely closes the gap with other sources by 2030 in the European Union and United States. In the Stated Policies Scenario, the global average [levelised cost] of solar PV declines by about 50% from 2018 to 2030.”

It adds that cost declines for wind and solar are “bolstering the economic case for switching directly from coal to renewables”, rather than using gas as a “bridge” to low-carbon sources.

It also points to newly announced for offshore wind, in auctions around the EU and a softening of towards subsidy-free renewables.

The IEA recently published an of the prospects for offshore wind, which it says “has the technical potential to meet today’s electricity demand many times over” at costs set to be competitive with fossil fuels within a decade.

THREAD

Offshore wind has “near limitless” potential & is “set to be competitive with fossil fuels within the next decade”, as costs fall 60% by 2040.

Turbines will soon be as large as the Eiffel Tower.

Pretty amazing stuff from today’s new report.

— Simon Evans (@DrSimEvans)

The IEA says there will be an increasing need to address challenges posed by variable wind and solar as they take hold of the electricity sector: “Policy makers and regulators will have to move fast to keep up with the pace of technological change and the rising need for flexible operation of power systems.”

Solar saga

Despite the large upwards revision in solar output in 2040 under this year’s STEPS, noted above, the IEA’s outlook for the technology remains relatively conservative compared with some others.

The IEA’s outlooks for solar have become something of a for critics of the agency’s work. It has made upwards revisions for solar capacity growth in each successive edition of the outlook, shown in shades of blue in the chart, below.

(Note that the chart shows additions net of retirements. These are initially negligible as the vast majority of solar capacity growth has been recent. The IEA assumes 298GW of solar retirements to 2040, suggesting it expects capacity to switch off after around 25 years. This means that actual additions and beyond, rather than apparently remaining relatively flat as in the net additions chart below.)

Annual net additions of solar capacity around the world, gigawatts. Historical data and an estimate for 2019 are shown in red while central outlooks from successive editions of the WEO are shown in shades of blue. The WEO 2019 STEPS is shown in black. Source: IEA and previous editions of the outlook. Chart by Carbon Brief using .

The IEA attributes these successive upwards revisions largely to shifts in government policy over time, in particular pointing to changes in China, which is the world’s largest market for solar.

Myth 2: underestimates renewables growth.
-False. Additions of renewables lead all sources in all scenarios. Track back and China’s policy changes accelerated global growth. Unfortunately, in the rest of the world, renewables are behind (!) the STEPS equivalent from WEO2009

— Brent Wanner (@WannerBrent)

The IEA argues that following slightly weaker solar growth in 2018, “a renewed acceleration in annual solar PV deployment, alongside enhanced efforts to ensure smooth integration of the resulting solar generation into power systems, is essential to reach climate targets and other sustainable development goals”.

The IEA’s relatively conservative outlook for solar appears to rest partly on its use of a cost of capital for all electricity generation technologies, set at 7-8% depending on each country’s stage of development.

This can have a very large impact on the levelised cost of electricity (LCOE) for a given project, as the IEA with reference to offshore wind. (Actual costs of capital for offshore wind in Europe have been closer to 4%, enough to cut its LCOE from around $140 per megawatt hour to $100/MWh.)

Another factor could be the IEA focus on system “value” rather than , illustrated by the “” metric it developed for the WEO 2018.

The agency says that cost reductions do not guarantee continued competitiveness “because the system value of solar PV tends to decline relative to the system average as its share of generation rises”.

This is because solar output is concentrated in the middle of the day, with additional capacity adding to supply and so partially eroding the price commanded by already-built solar panels.

Despite also considering these sorts of issues, some other outlooks are on solar capacity growth. Whereas the IEA’s STEPS has solar additions of less than 140GW each year by 2040, the  sees solar additions topping 300GW by then. This higher figure is in line with deployment in the IEA’s target-focused SDS.

BloombergNEF is also more bullish on wind capacity growth, with the result that its outlook has electricity output from coal falling by half in 2050, rather than holding steady as in the IEA’s STEPS.

Simon Evans was one of more than 250 external peer reviewers that read sections of the World Energy Outlook in draft form.

※ 全文及圖片詳見:()

作者

如果有一件事是重要的,如果能為孩子實現一個願望,那就是人類與大自然和諧共存。

於特有生物研究保育中心服務,小鳥和棲地是主要的研究對象。是龜毛的讀者,認為龜毛是探索世界的美德。

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

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

美頂尖企業和工會領袖 表態支持巴黎氣候協定

摘錄自2019年12月3日中央通訊社報導

美國一流企業執行長和工會領導人今天(3日)公開呼籲,要求美國續留巴黎氣候協定,避免全球氣溫上升。他們表明,對抗氣候變遷,將會保護美國經濟,並創造更多就業及商業機會。

這群領導人包括蘋果(Apple)、特斯拉(Tesla)、聯合利華公司(Unilever)和荷蘭皇家殼牌集團(Royal Dutch Shell)的執行長。他們在馬德里舉辦的聯合國氣候會議發表聲明說,對抗全球暖化的巴黎氣候協定,將促進經濟健全,並得以建立有競爭力公司。

美國是造成暖化溫室氣體的全球最大排放國之一,總統川普政府計劃退出2015年巴黎氣候協定。該協定是經過將近200個國家談判達成的協議,目標是將全球升溫抑制在「遠低於」攝氏2度,理想是攝氏1.5度以內。

川普堅稱巴黎氣候協定將耗費美國數以兆計美元、喪失數以百萬計就業機會,並妨礙石油、天然氣、煤炭和製造產業。美國上個月正式啟動退出程序。

這批75位企業高層表明支持巴黎氣候協定,並稱他們總共雇用超過200萬美國員工,而工會領導人則代表1250萬名勞工。他們說:「留在巴黎氣候協定會強化我們在全球市場的競爭力,讓美國處於引領發展新科技的地位,新科技將能支援轉型過渡、供養我們的勞工和社區,並創造持久的就業和企業。」

國際勞工組織(ILO)表示,在推廣更環保經濟政策下,全球將能在2030年前創造2400萬個新工作。它並指出,永續能源產業提供的工作,將會超出其他領域砍掉的估計約600萬個工作。

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

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務

全球氣候風險持續攀升 富裕國家也一樣 最新排名出爐:日本第一 台灣排第75

環境資訊中心記者 陳文姿、彭瑞祥報導

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

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

JS面試題-<變量和類型>-JavaScript的數據類型

前言

  整理以前的面試題,發現問js數據類型的頻率挺高的,回憶當初自己的答案,就是簡簡單單的把幾個類型名稱羅列了出來,便沒有了任何下文。其實這一個知識點下可以牽涉發散出很多的知識點,如果一個面試者只是羅列的那些名詞出來,可能面試官都不願意繼續問下去了,這該算是js基礎的基礎了。如果這個問題沒有很好的回答,其他問題仍舊沒有突出的亮點,很可能就過不了。

  在網上看了一個體系,可作為大致的學習檢閱自己的途徑,按照清單上的知識檢測自己還有哪些不足和提升,最後形成自己的知識體系。在工作、學習甚至面試時,可以快速定位到知識點。

1. JavaScript規定了幾種語言類型 2. JavaScript對象的底層數據結構是什麼 3. Symbol類型在實際開發中的應用、可手動實現一個簡單的 Symbol 4. JavaScript中的變量在內存中的具體存儲形式 5. 基本類型對應的內置對象,以及他們之間的裝箱拆箱操作 6. 理解值類型和引用類型 7. null和 undefined的區別 8. 至少可以說出三種判斷 JavaScript數據類型的方式,以及他們的優缺點,如何準確的判斷數組類型 9. 可能發生隱式類型轉換的場景以及轉換原則,應如何避免或巧妙應用 10. 出現小數精度丟失的原因, JavaScript可以存儲的最大数字、最大安全数字, JavaScript處理大数字的方法、避免精度丟失的方法

 

一、JavaScript規定了幾種語言類型

  問:講一下js的數據類型?

  答:js的數據類型分為簡單數據類型和複雜數據類型;

簡單數據類型有六種,分別是String(字符串)、Number(数字)、Null(空)、undefined(未定義)、boolean(布爾值)、symbol(符號),表示不能再繼續分下去的類型,在內存中以固定的大小存儲在棧中,按值訪問;

複雜數據類型是指對象,這裡有常見的array、function、object等,本質上是一組無序的鍵值對組成。它的值大小不固定,所以保存在堆中,但在棧中會存儲有指向其堆內存的地址,按引用來訪問。js不允許直接訪問內存中的位置,也就是說不能直接操作對象的內存空間。也就是說,當我們想要訪問應用類型的值的時候,需要先從棧中獲得對象的地址指針,然後通過地址指針找到其在堆中的數據。

需要注意的是,

1、簡單數據類型中的boolean、number、string不是由內置函數new出來的,儘管他們有對應的引用類型;

2、symbol是ES6引入的一種新的原始數據,表示獨一無二且不可改變的值。通過 Symbol 函數調用生成,由於生成的 symbol 值為原始類型,所以 Symbol 函數不能使用 new 調用;

3、將一個變量賦值給另一個變量時,基礎類型複製的是值,賦值完成兩個變量在沒有任何關係;而對象類型的複製的是地址,修改一個變量另一個變量也會跟着一起變化。(如何解決這個問題?關於深拷貝and淺拷貝)

二、JavaScript對象的底層數據結構是什麼

這個問題目前對我來說,不能夠理解到底是想問什麼,還有問題,看到一篇這個文章,轉載《從chrome源碼看js object的實現》:

三、Symbol類型在實際開發中的應用、手動實現一個簡單的 Symbol

(暫未學習總結)

四、JavaScript中的變量在內存中的具體存儲形式

  js的數據類型分為簡單數據類型和複雜數據類型;在內存中,簡單數據類型以固定的大小存儲在棧中;複雜數據類型存儲在堆中,且大小不固定,同時在棧中會存儲其指向堆地址的指針。

因為這裏問的是內存中的存儲形式,所以我一直注意的是內存中堆棧,後來忽然看到一篇文章寫了數據結構中的堆和棧就有一點懵,先簡單記錄一下相關知識點。

內存的堆棧:

  是一種物理結構,用於存放不同數據的內存空間,分為棧區和堆區。

1)棧內存:

  棧(stack)是向低地址擴展的數據結構,是一塊連續的內存區域;一般來說其大小是系統預先規定好的,存儲大小已知的變量(函數的參數值、局部變量的值等)。由操作系統自動申請分配並釋放(回收)空間,無需程序員控制,這樣的好處是內存可以及時得到回收。但棧的大小有限,如果申請的空間超過棧的剩餘空間,就會提示棧溢出(一般無窮次的遞歸調用或大量的內存分配會引起棧溢出)。

在分配內存的時候類似於數據結構中的棧,先進后出的原則,即從棧低向棧頂,依次存儲。棧是向下增長,即從高地址到低地址分配內存,且內存區域連續、每個單元的大小相同。如下圖:

 2)堆內存:

  在現代程序中,在編譯時刻不能決定大小的對象將被分配在堆區。一般由程序員分配釋放,例如;c++和Java語言都為程序員提供了new(或malloc()),該語句創建的對象(或指向對象的指針),然後使用delete(或free())語句釋放。如果程序員不主動釋放,程序結束時由OS回收。 在內存分配的時候方式類似於鏈表,堆是向上增長,即從低地址到高地址擴展,是不連續的內存區域。如下圖:

數據結構的堆棧:

  是一種抽象的數據存儲結構,

棧:一種連續存儲的數據結構,特點是存儲的數據先進后出,只能在棧頂一端對數據項進行插入和刪除。

堆:是一棵完全二叉樹結構(知識點未掌握)

 五、基本類型對應的內置對象,以及他們之間的裝箱拆箱操作

1)基本包裝類型

 

  問:有了基本類型為什麼還要包裝類型?

  答:為了便於操作基本類型值,ECMAScript提供了3個特殊的引用類型:Boolean、Number和String, 每當讀取一個基本類型值的時候,後台會創建一個對應的基本包裝類型的對象,從而能夠調用一些方法來操作這些基本類型。每個包裝類型都映射到同名的基本類型。

2)裝箱和拆箱

    裝箱就是把基本類型轉換為對應的內置對象,這裏可分為隱式和顯式裝箱。     拆箱就是與裝箱相反,把對象轉變為基本類型的值。        Ⅰ 隱式裝箱 在讀取模式下,訪問基本類型值(即讀取基本類型的值),就會創建基本類型所對應的基本包裝類型的一個對象,從而讓我們能夠調用一些方法來操作這些數據。這個基本包裝類型是臨時的,操作基本類型值的語句一經執行完畢,就會立即銷毀新創建的包裝對象。

var s1 = “stringtext”; var s2 = s1.substring(2);

如上面的例子,第一行變量s1是一個基本類型的字符串,第二行調用了s1的substring()方法,並將結果保存在了s2中。 基本類型值不是對象,從邏輯上講它們不應該有方法。其實這裏就包含了隱式裝箱,後台自動完成了一系列的處理。當第二行代碼訪問s1時,訪問過程處於一種讀取模式,即從內存中讀取這個字符串的值。 在讀取字符串時,後台會完成一下處理。

(1)創建String類型的一個實例      =>  var s1 = new String(“stringtext”); (2)在實例上調用指定的方法        =>  var s2 = s1.substring(2); (3)摧毀這個實例                 =>  s1 = null;

注:①上面s1 = null;這種做法叫做解除引用,一旦有數據不再有用,通過設置其值為null來是釋放其引用;一般適用於大多數全局變量和全局對象的屬性。   ②
引用類型和基本包裝類型的主要區別:就是對象的生存期。使用new操作符創建的引用類型的實例,在執行流離開當前作用域之前都一直保存在內存中。而自動創建的基本包裝類型的對象,則只存在於一行代碼的執行瞬間,然後立即被銷毀,因此我們不能在運行時為基本類型值添加屬性和方法。

var s1 = “stringtext”; s1.color = “red”; //在這一句話執行完的瞬間,第二行創建的String就已經被銷毀了。 console.log(s1.color);//執行這一行代碼時又創建了自己的String對象,而該對象沒有color屬性。 //undefine

   Ⅱ 顯式裝箱 通過New調用Boolean、Number、String來創建基本包裝類型的對象。不過,不建議顯式地創建基本包裝類型的對象,儘管它們操作基本類型值的能力相當重要,每個基本包裝類型都提供了操作相應值的便捷方法。 Object構造函數會像工廠方法一樣,根據傳入值的類型返回相應基本包裝類型的實例。

var obj = new Object(“stringtext”); console.log(obj instanceof String); //true

    Ⅲ 拆箱 把對象轉變為基本類型的值,在拆箱的過程調用了JavaScript引擎內部的抽象操作,ToPrimitive(轉換為原始值),對原始值不發生轉換處理,只針對引用類型。 JavaScript引擎內部的抽象操作ToPrimitive()是這樣定義的,
 ToPrimitive(input [, PreferredType])
該操作接受兩個參數,第一個參數是要轉變的值,第二個是PreferredType為可選參數,只接受Number或String,作用是設置想要轉換原值時的轉換偏好。最後使input轉換成原始值。
如果PreferredType被標誌為Number,則會進行下面的操作來轉換input。 ①如果輸入的是一個原始值,則直接返回它; ②否則,如果輸入的值是一個對象,則調用該對象的valueOf()方法,如果valueOf()方法的返回值是一個原始值,則返回這個原始值; ③否則,調用這個對象的toString()方法,如果toString方法的返回值是一個原始值,則返回這個原始值; ④否則,拋出TypeError異常; 如果PreferredType被標誌為String,則轉換操作的第二步和第三步的順序會調換。即 ①如果輸入的是一個原始值,則直接返回它; ②否則,如果輸入的值是一個對象,則調用該對象的 toString()方法,如果toString()方法的返回值是一個原始值,則返回這個原始值; ③否則,調用這個對象的valueOf()方法,如果valueOf()方法的返回值是一個原始值,則返回這個原始值; ④否則,拋出TypeError異常; 如果沒有PreferredType的值會按照這樣的規則來自動設置: Date類型的對象會被設置為String,其他類型的值被設置為Number  

inputTpye result
Null 不轉換,直接返回
Undefined 不轉換,直接返回
Number 不轉換,直接返回
Boolean 不轉換,直接返回
String 不轉換,直接返回
Symbol 不轉換,直接返回
Object 按照下列步驟進行轉換

  參考文章: 《js隱式裝箱》                   《[譯]JavaScript在中,{} + {}等於多少?》                      原文《javaScript在中,what is {} + {} in javascrupt    ?》 

六、理解值類型和引用類型

js包含兩種數據類型,基本數據類型和複雜數據類型,而其對應的值基本類型的值指的是簡單的數據段,引用類型指的是那些可能有多個值構成的對象。可以從三個方面來理解:動態的屬性、複製變量的值、傳遞參數

1)、動態的屬性

定義基本類型值和引用類型值的方式類似,即創建一個變量併為該變量賦值。兩者的區別在於,對於引用類型的值,我們可以為其添加屬性和方法,也可以改變和刪除其屬性和方法;對於基本類型的值,我們不能為其動態地添加屬性。

var person = new Object(); //創建一個對象並將其保存在變量person中 person.name = “Song”; //為該對象添加一個名為name的屬性,並賦值為Song console.log(person.name); //訪問name這個屬性 //Song

2)、複製變量的值

在從一個變量向另一個變量複製基本類型值和引用類型值時,兩則也是不同的,這主要是由於基本類型和引用類型在內存中存儲不同導致的。

  Ⅰ基本類型的值 基本類型的值是存在棧中,存儲的即是基本類型的值;如果從一個變量向另一個變量複製的時候,就會重新創建一個變量的新值然後將其複製到為新變量分配的位置上,此時兩個變量各自擁有屬於自己的獨立的內存空間,因此兩者可以參与任何操作而不會相互影響。

var a = 1; var b = a; b = 2; console.log(a);//1 console.log(b);//2

 內存變化大致如下:

  Ⅱ複製引用類型的值

引用類型的值存儲在堆中,同時在棧中會有相應的堆地址(指針),指向其在堆的位置。此時如果我們要複製一個引用類型時,複製的不是堆內存中的值,而是將棧內存中的地址複製過去,複製操作結束后,兩個對象實際上都指向堆中的同一個地方。因此改變其中一個對象(堆中的值改變),那麼會影響到另一個對象。

 

var obj1 = {     name:”Song” }; var obj2 = obj1; obj2.name = “D”; //改變obj2的name屬性的值,則將obj1的也改變了。 console.log(obj1.name); // D 

 

注:關於深拷貝和淺拷貝

3)、傳遞參數

 ECMAScript中所有函數的參數都是按值傳遞的,無論在向參數傳遞的是基本類型還是引用類型。(我的理解:正因為是按值傳遞的,所以我們才可以利用此來完成深拷貝)

有一道關於證明引用類型是按值傳遞還是按引用傳遞的題目如下:

function test(person){
person.age = 26;
person = {
  name:'yyy',
  age:30
}
return person
}
const p1 = {
  name:'yck',
  age:25
};
const p2 = test(p1);
console.log(p1);
console.log(p2);

首先當我們從一個變量向另一個變量複製引用類型的值時,這個值是存儲在棧中的指針地址,複製操作結束后,兩個變量引用的是同一個對象,改變其中一個變量,就會影響另一個變量。

而在向參數傳遞引用類型的值時,同樣是把內存中的地址複製給一個局部變量,所以在上述代碼中,將p1的內存地址指針複製給了局部變量person,兩者引用的是同一個對象,這個時候在函數中改變變量,就會影響到外部。

接下來相當於從新開闢了一個內存空間,然後將此內存空間的地址賦給person,可以理解為將剛才指向p1的指針地址給覆蓋了,所以改變了person的指向,當該函數結束后便釋放此內存。

(此圖作為自己的理解,不代表實際,很有可能實際並不是這樣操作的。)

所以在person.age = 26;這句話執行后把p1內存里的值改變了,打印出來p1是{name: “yck”, age: 26}  p2是{name: “yyy”, age: 30}

而我理解的如果按引用傳遞,則相當於person的指向是和p1也一樣,所以後續只要是對person進行了操作,都會直接影響p1。

因此在這種情況下,打印出來p1和p2都是{name: “yyy”, age: 30}

七、null和 undefined的區別

1)、null類型    

        《高程》上解釋:null值表示一個空對象指針,所以這也是使用typeof操作符檢測null值時會返回”object”的原因。

var car = null; console.log(typeof car); //object

             一般來說,我們要保存對象的變量在還沒有真正保存對象之前可以賦值初始化為null,其他的基礎類型在未賦值前默認為undefined,這樣一來我們直接檢查變量是否為null可以知道相應的變量是否已經保存了一個對象的引用。 即如果定義的變量準備在將來保存為對象,那麼我們將該變量初始化為null,而不是undefined。 2)、undefined類型         在使用var申明變量但未對其初始化時,這個變量的值就是undefined。

var s; console.log(s == undefined); //true

3)、null和undefined的區別     一般來說undefined是派生自null的值,因此null == undefined  是為true,因為它們是類似的值;如果用全等於(===),null ===undefined會返回false ,因為它們是不同類型的值。以此我們可以區分null和undefined。

八、至少可以說出三種判斷 JavaScript數據類型的方式,以及他們的優缺點,如何準確的判斷數組類型

  問:判斷js數據類型有哪幾種方式,分別有什麼優缺點?怎麼樣判斷一個值是數組類型還是對象?(或者typeof能不能正確判斷類型)

  答:一般來說有5種常用的方法,分別是typeof、instanceof、Object.prototype.toString()、constructor、jquery的type();

1)對於typeof來說,在檢測基本數據類型時十分得力,對於基本類型,除了null都可以返回正確類型,對於對象來說,除了function都返回object。

基本類型

  typeof “somestring”   // ‘string’
  typeof true        // ‘boolean’
  typeof 10          // ‘number’
  typeof Symbol()    // ‘symbol’
  typeof null        // ‘object’ 無法判定是否為 null
  typeof undefined   // ‘undefined’

複雜類型

  typeof {}           // ‘object’
  typeof []           // ‘object’  如果需要判斷數組類型,則不能使用這樣方式
  typeof(() => {})    // ‘function’

 

注:怎麼使用複合條件來檢測null值的類型?

var a = null;

(!a && typeof a === “object”);     // true

 

2)對於instanceof來說,可以來判斷已知對象的類型,如果使用instanceof來判斷基本類型,則始終返回false。

其原理是測試構造函數的prototype是否出現在被檢測對象的原型鏈上;所有的複雜類型的值都是object的實例,在檢測一個引用類型值和Object構造函數時,instanceof操作符始終返回true。

[] instanceof Array         //true  -》 無法優雅的判斷一個值到底屬於數組還是普通對象 ({}) instanceof Object         //true (()=>{}) instanceof Function         //true

而且在《高程》上還看到說一個問題,如果不是單一的全局執行環境,比如網頁中包含多個框架,那麼實際上存在兩個以上不同的全局執行環境,從而存在兩個以上不同版本的Array構造函數,如果從一個框架向另外一個框架傳入數組,那麼傳入的數據與在第二個框架中原生創建的數組分別具有各自不同的構造函數。eg:例如index頁面傳入一個arr變量給iframe去處理,則即使arr instanceof Array還是返回false,因為兩個引用的Array類型不是同一個。並且constructor可以重寫所以不能確保萬無一失。

對於數組來說,相當於new Array()出的一個實例,所以arr.proto === Array.prototype;又因為Array是Object的子對象,所以Array.prototype.proto === Object.prototype。因此Object構造函數在arr的原型鏈上,便無法判斷一個值到底屬於數組還是普通對象。

注:判斷變量是否為數組的方法

3)通用但比較繁瑣的方法Object.prototype.toString() 

該方法本質是利用Object.prototype.toString()方法得到對象內部屬性[[Class]],傳入基本類型也能夠判斷出結果是因為對其值做了包裝。

Object.prototype.toString.call({})  ===  ‘[object Object]’      ——-> true;
Object.prototype.toString.call([])   ===  ‘[object Array]’  ——-> true;
Object.prototype.toString.call(() => {})  ===  ‘[object Function]’  ——-> true;
Object.prototype.toString.call(‘somestring’)  ===  ‘[object String]’  ——-> true;
Object.prototype.toString.call(1)  ===  ‘[object Number]’  ——-> true;
Object.prototype.toString.call(true)  ===  ‘[object Boolean]’  ——-> true;
Object.prototype.toString.call(Symbol()) ===  ‘[object Symbol]’  ——-> true;
Object.prototype.toString.call(null)   ===  ‘[object Null]’  ——-> true;
Object.prototype.toString.call(undefined)  === ‘[object Undefined]’  ——-> true;

Object.prototype.toString.call(new Date())   ===  ‘[object Date]’  ——-> true;
Object.prototype.toString.call(Math)  === ‘[object Math]’  ——-> true;
Object.prototype.toString.call(new Set())  ===  ‘[object Set]’  ——-> true;
Object.prototype.toString.call(new WeakSet())  ===  ‘[object WeakSet]’  ——-> true;
Object.prototype.toString.call(new Map())  ===  ‘[object Map]’  ——-> true;
Object.prototype.toString.call(new WeakMap())  ===  ‘[object WeakMap]’  ——-> true;

4)根據對象的constructor判斷

 

[].constructor === Array     ——–> true var d = new Date(); d.constructor === Date     ———> true (()=>{}).constructor === Function   ——-> true 注意: constructor 在類繼承時會出錯 eg: function A(){}; function B(){}; A.prototype = new B(); //A繼承自B var aobj = new A(); aobj.constructor === B  ——–> true; aobj.constructor === A   ——–> false; 而instanceof方法不會出現該問題,對象直接繼承和間接繼承的都會報true:

5)jquery的type()

如果對象是undefined或null,則返回相應的“undefined”或“null”, jQuery.type( undefined ) === “undefined” jQuery.type() === “undefined” jQuery.type( null ) === “null” 如果對象有一個內部的[[Class]]和一個瀏覽器的內置對象的 [[Class]] 相同,我們返回相應的 [[Class]] 名字。  jQuery.type( true ) === “boolean” jQuery.type( 3 ) === “number” jQuery.type( “test” ) === “string” jQuery.type( function(){} ) === “function” jQuery.type( [] ) === “array” jQuery.type( new Date() ) === “date” jQuery.type( new Error() ) === “error” // as of jQuery 1.9 jQuery.type( /test/ ) === “regexp”

6)如何判斷一個數組?

var  a = [];

a.instanceof  Array;  ——–> true

a.constructor === Array  ——–> true

Object.prototype.toString.call(a)   ===  ‘[object Array]’  ——–> true

Array.isArray([]);      ——–> true

九、可能發生隱式類型轉換的場景以及轉換原則,應如何避免或巧妙應用

(暫未整理)

十、出現小數精度丟失的原因、 JavaScript可以存儲的最大数字以及最大安全数字、JavaScript處理大数字的方法、避免精度丟失的方法

  問:0.1+0.2 === 0.3 為什麼是false?

  答:在ECMAScript數據類型中的Number類型是使用IEEE754格式來表示的整數和浮點數值,所謂浮點數值就是該數值必須包含一個小數點,並且小數點後面必須至少有一位数字。而在使用基於IEEE754數值的浮點運算時出現參數舍入的誤差問題,即出現小數精度丟失,無法測試特定的浮點數值。

  ①在進行0.1+0.2的時候首先要將其轉換成二進制。

  0.1 => 0.0001 1001 1001 1001…(無限循環)   0.2 => 0.0011 0011 0011 0011…(無限循環)   ②由於 JavaScript 採用 IEEE 754 標準,數值存儲為64位雙精度格式,數值精度最多可以達到 53 個二進制位(1 個隱藏位與 52 個有效位)。如果數值的精度超過這個限度,第54位及後面的位就會被丟棄,所以在相加的時候會因為小數位的限制而將二進制数字截斷。   0.0001 1001 1001 1001…+0.0011 0011 0011 0011… = 0.0100110011001100110011001100110011001100110011001100   ③再轉換成十進制就成了0.30000000000000004,而非我們期望的0.3

在《js權威指南》中有指出:

Javascript採用了IEEE-745浮點數表示法(幾乎所有的編程語言都採用),這是一種二進製表示法,可以精確地表示分數,比如1/2,1/8,1/1024。遺憾的是,我們常用的分數(特別是在金融的計算方面)都是十進制分數1/10,1/100等。二進制浮點數表示法並不能精確的表示類似0.1這樣 的簡單的数字,上訴代碼的中的x和y的值非常接近最終的正確值,這種計算結果可以勝任大多數的計算任務:這個問題也只有在比較兩個值是否相等時才會出現。 這個問題並不是只在javascript中才會出現,在任何使用二進制浮點數的編程語言中都會出現這個問題。 所以說,精度丟失並不是語言的問題,而是浮點數存儲本身固有的缺陷。只不過在 C++/C#/Java 這些語言中已經封裝好了方法來避免精度的問題,而 JavaScript 是一門弱類型的語言,從設計思想上就沒有對浮點數有個嚴格的數據類型,所以精度誤差的問題就顯得格外突出。   javascript的未來版本或許會支持十進制数字類型以避免這些舍入問題,在這之前,你更願意使用大整數進行重要的金融計算,例如,要使用整數‘分’而不是使用小數‘元’進行貨比單位的運算。

   問:怎麼避免精度丟失?

   答:一般常用的有四個方法,第一個是設置一個“能夠接受的誤差範圍”,在這個範圍內,可認為沒有誤差;第二個是使用三方的類庫math.js;第三是使用toFixed()方法;第四是封裝一個計算類(加、減、乘、除)。   ①ES6在Number對象上面,新增了一個極小的常量Number.EPSILON,它表示1與大於1的最小浮點數之間的差,它是實際上是javascript能夠表示的最小精度(可以接受的最小誤差範圍),誤差如果小於這個值,就可以認為已經沒有意義了,即不存在誤差。

Number.EPSILON === Math.pow(2, -52) // true      說明這個值Number.EPSILON是等於 2 的 -52 次方

  寫一個誤差檢測函數,來判斷0.1 + 0.2 === 0.3   設置誤差範圍為 2 的-50 次方(即
Number.EPSILON * Math.pow(2, 2)),即如果兩個浮點數的差小於這個值,我們就認為這兩個浮點數相等。

  function withinErrorMargin (left, right) {  
         return Math.abs(left - right) < Number.EPSILON * Math.pow(2, 2);
  }
    withinErrorMargin(0.1 + 0.2, 0.3)    //true

  ②math.js是一個廣泛應用於JavaScript 和 Node.js的數學庫,它的特點是靈活表達式解析器,支持符號計算,內置大量函數與常量,並提供集成解決方案來處理不同的數據類型,如数字,大数字,複數,分數,單位和矩陣。

  ③toFixed()方法   定義:toFixed() 方法可把 Number 四舍五入為指定小數位數的数字。   用法:NumberObject.toFixed(num) 其中num是必須的,規定小數的位數,是 0 ~ 20 之間的值,包括 0 和 20,有些實現可以支持更大的數值範圍。如果省略了該參數,將用 0 代替。 然而實際上,並不是完美的,可能你開發時候測試的幾個實例恰巧都是你想要的結果,可能在實際上線后遇到大量的數據后發現出問題了,不能正確的計算。一般是在遇到最後一位是5的時候,就不是’四舍五入”,eg:2.55.toFixed(1)   //  2.5,而我們齊期望的是2.56。 我有查這個產生誤差的原因,有人說是“銀行家的舍入規則”,即四舍六入五考慮,這裏“四”是指≤4 時捨去,”六”是指≥6時進上。”五”指的是根據5後面的数字來定,當5後有數時,舍5入1;當5后無有效数字時,需要分兩種情況來講:5前為奇數,舍5入1;5前為偶數,舍5不進(0是偶數)。但在某些情況下也是不成立。

2.65.toFixed(1)  //2.6    結果正確     2.45.toFixed(1)  //2.5    希望得到的結果是2.4 2.35.toFixed(1)   //2.4    結果正確

由於無法解決這種問題,所以看到有一些是以項目需求為準重寫符合要求的函數,在Math.round(x)來擴展解決toFixed()四舍五入不精確的問題。  原本round(x) 方法可把一個数字四舍五入為最接近的整數,其中x是必須的且必須是数字。雖然解決了四舍五入的問題,但卻沒有直接解決保留小數點后多少位的問題,因而需要重寫符合需求的函數。

function RoundNum(n, m){ //n表示需要四舍五入的數,m表示需要保留的小數位數
var newNum = Math.round(n * Math.pow(10, m)) / Math.pow(10, m) ;
//首先將要保留的小數位數的小數部分轉成整數部分,利用冪函數將n乘以10的m次方
//然後利用Math.round()方法進行四舍五入處理
//最後再除以10的m次方還原小數部分
//注:此時還未能將所有数字正確轉換。例如將1.0001保留3位小數我們想要的結果是1.000,而此時newNum裏面的值是1
//所以還需要處理此種特殊情況,即保留的小數位上全0
var newSNum = newNum.toString();
//這一步將剛才進行處理過的數轉換成字符串
var rs = newSNum.indexOf('.'); //利用indexOf查找字符串中是否有.,它返回某個指定的字符串值在字符串中首次出現的位置,不存在則返回-1
if (rs < 0) {
rs = newSNum.length;
newSNum += '.';
}
while (newSNum.length <= rs + m) { //在末尾加0
newSNum += '0';
}
return newSNum;
}

console.log(RoundNum(1.0005, 3)); //得到1.001

  ④封裝一個計算類(加、減、乘、除)

(暫未實際寫過)

  問:JavaScript可以存儲的最大数字以及最大安全数字

  答:最大数字是Number.MAX_VALUE、最大安全数字是Number.MAX_SAFE_INTEGER。Number.MAX_VALUE大於Number.MAX_SAFE_INTEGER,我的理解是js可以精確表示最大安全数字以內的數,超過了最大安全数字但沒超過最大数字可以表示,但不精確,如果超過了最大数字,則這個數值會自動轉換成特殊的Infinity值。

由於內存的限制,ECMAScript並不能保存世界上所有的數值,ECMAScript能夠表示的最小數值是Number.MIN_VALUE,能夠表示的最大數值是Number.MAX_VALUE。超過數值是正值,則被轉成Infinity(正無窮),如果是負值則被轉成-Infinity(負無窮)。如果在某次返回了正或負的Infinity值,那麼該值將無法繼續參与下一次的計算,所以我們需要確定一個數值是不是有窮的,即是不是位於最小和最大的數值之間,可以使用isFinite()函數,如果該函數參數在最小和最大數值之間時會返回true。注意,如果參數類型不是數值,Number.isFinite一律返回false

JavaScript 能夠準確表示的整數範圍在-2^532^53之間(不含兩個端點),超過這個範圍,無法精確表示這個值。ES6 引入了Number.MAX_SAFE_INTEGERNumber.MIN_SAFE_INTEGER這兩個常量,用來表示這個範圍的上下限。Number.isSafeInteger()則是用來判斷一個整數是否落在這個範圍之內。

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

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務

(25)ASP.NET Core EF查詢(複雜查詢運算符、原生SQL查詢、異步查詢)

1.複雜查詢運算符

在生產場景中,我們經常用到LINQ運算符進行查詢獲取數據,現在我們就來了解下生產場景經常出現幾種複雜查詢運算符。

1.1聯接(INNER JOIN)

藉助LINQ Join運算符,可根據每個源的鍵選擇器連接兩個數據源,並在鍵匹配時生成值的元組。

var query = from blog in _context.Set<Blog>()
            join post in _context.Set<Post>()
                on blog.BlogId equals post.BlogId
            select new { blog, post };

SQL:

SELECT [blog].[BlogId], [blog].[Createtime], [blog].[Updatetime], [blog].[Url], [post].[PostId], [post].[BlogId], [post].[Content], [post].[Title]
FROM [Blog] AS [blog]
INNER JOIN [Post] AS [post] ON [blog].[BlogId] = [post].[BlogId]

SQL Server Profiler:

1.2左聯接(Left Join)

雖然Left Join不是LINQ運算符,但關係數據庫具有常用於查詢的Left Join的概念。LINQ查詢中的特定模式提供與服務器上的LEFT JOIN相同的結果。

var query = from blog in _context.Set<Blog>()
            join post in _context.Set<Post>()
                on blog.BlogId equals post.BlogId into grouping
            from post in grouping.DefaultIfEmpty()
            select new { blog, post };

SQL:

SELECT [blog].[BlogId], [blog].[Createtime], [blog].[Updatetime], [blog].[Url], [post].[PostId], [post].[BlogId], [post].[Content], [post].[Title]
FROM [Blog] AS [blog]
LEFT JOIN [Post] AS [post] ON [blog].[BlogId] = [post].[BlogId]

SQL Server Profiler:

1.3分組(GroupBy)

LINQ GroupBy運算符創建IGrouping<TKey, TElement>類型的結果,其中TKey和TElement可以是任意類型。此外,IGrouping實現了IEnumerable<TElement>,這意味着可在分組后使用任意LINQ運算符來對其進行組合。

var query = from blog in _context.Set<Blog>()
            group blog by blog.Url into g
            select new
            {
                g.Key,
                Count = g.Count()
            };

SQL:

SELECT [blog].[Url] AS [Key], COUNT(*) AS [Count]
FROM [Blog] AS [blog]
GROUP BY [blog].[Url]

SQL Server Profiler:

分組的聚合運算符出現在Where或OrderBy(或其他排序方式)LINQ運算符中。它在SQL中將Having子句用於Where子句。

var query = from blog in _context.Set<Blog>()
            group blog by blog.Url into g
            where g.Count() > 0
            orderby g.Key
            select new
            {
                g.Key,
                Count = g.Count()
            };

SQL:

SELECT [blog].[Url] AS [Key], COUNT(*) AS [Count]
FROM [Blog] AS [blog]
GROUP BY [blog].[Url]
HAVING COUNT(*) > 0
ORDER BY [Key]

SQL Server Profiler:

EF Core支持的聚合運算符如下所示:
●Avg
●Count
●LongCount
●Max
●Min
●Sum

1.4SelectMany

藉助LINQ SelectMany運算符,可為每個外部元素枚舉集合選擇器,並從每個數據源生成值的元組。

var query0 = from b in _context.Set<Blog>()
                from p in _context.Set<Post>()
                select new { b, p };

var query1 = from b in _context.Set<Blog>()
                from p in _context.Set<Post>().Where(p => b.BlogId == p.BlogId).DefaultIfEmpty()
                select new { b, p };

var query2 = from b in _context.Set<Blog>()
                from p in _context.Set<Post>().Select(p => b.Url + "=>" + p.Title).DefaultIfEmpty()
                select new { b, p };

SQL:

SELECT [b].[BlogId], [b].[Createtime], [b].[Updatetime], [b].[Url], [p].[PostId], [p].[BlogId], [p].[Content], [p].[Title]
FROM [Blog] AS [b]
CROSS JOIN [Post] AS [p]

SELECT [b].[BlogId], [b].[Createtime], [b].[Updatetime], [b].[Url], [t0].[PostId], [t0].[BlogId], [t0].[Content], [t0].[Title]
FROM [Blog] AS [b]
CROSS APPLY (
    SELECT [t].[PostId], [t].[BlogId], [t].[Content], [t].[Title]
    FROM (
        SELECT NULL AS [empty]
    ) AS [empty]
    LEFT JOIN (
        SELECT [p].[PostId], [p].[BlogId], [p].[Content], [p].[Title]
        FROM [Post] AS [p]
        WHERE [b].[BlogId] = [p].[BlogId]
    ) AS [t] ON 1 = 1
) AS [t0]

SELECT [b].[BlogId], [b].[Createtime], [b].[Updatetime], [b].[Url], [t0].[c]
FROM [Blog] AS [b]
CROSS APPLY (
    SELECT [t].[c]
    FROM (
        SELECT NULL AS [empty]
    ) AS [empty]
    LEFT JOIN (
        SELECT ([b].[Url] + N'=>') + [p].[Title] AS [c]
        FROM [Post] AS [p]
    ) AS [t] ON 1 = 1
) AS [t0]

SQL Server Profiler:

好了,這裏就不多寫關於LINQ其他示例了,如果需要了解的小夥伴們,可以移步“”這裏了解。

2.原生SQL查詢

有一些複雜業務場景,使用LINQ查詢可能會導致SQL查詢效率低下並不適用,那麼這時候就需要到原生SQL查詢了。EF Core為我們提供FromSql擴展方法基於原始SQL查詢。 FromSql只能在直接位於DbSet<>上的查詢根上使用。

var blogs = _context.Blog.FromSql("SELECT * FROM dbo.Blog").ToList();

原生SQL查詢可用於執行存儲過程。

var blogs = _context.Blog
    .FromSql("EXECUTE dbo.GetMostPopularBlogs")
    .ToList();

2.1原始SQL查詢使用參數化

向原始SQL查詢引入任何用戶提供的值時,必須注意防範SQL注入攻擊。除了驗證確保此類值不包含無效字符,還要將值與SQL文本參數化處理。
下面的示例通過在SQL查詢字符串中包含形參佔位符並提供額外的實參,將單個形參傳遞到存儲過程。雖然此語法可能看上去像String.Format語法,但提供的值包裝在DbParameter中,且生成的參數名稱插入到指定{0}佔位符的位置。

var url = "http://blogs.msdn.com/webdev";
var blogs = _context.Blog
    .FromSql("EXECUTE dbo.GetMostPopularBlogForUrl {0}", url)
.ToList();

SQL:

exec sp_executesql N'EXECUTE dbo.GetMostPopularBlogForUrl @p0
',N'@p0 nvarchar(4000)',@p0=N'http://blogs.msdn.com/webdev'

SQL Server Profiler:


還可以構造DbParameter並將其作為參數值提供。由於使用了常規SQL參數佔位符而不是字符串佔位符,因此可安全地使用FromSql:

var urlParams = new SqlParameter("Url", "http://blogs.msdn.com/webdev");
var blogs = _context.Blog
    .FromSql("EXECUTE dbo.GetMostPopularBlogForUrl @Url", urlParams)
.ToList();

SQL:

exec sp_executesql N'EXECUTE dbo.GetMostPopularBlogForUrl @Url
',N'@Url nvarchar(28)',@Url=N'http://blogs.msdn.com/webdev'

SQL Server Profiler:

2.2使用LINQ編寫SQL

可使用LINQ運算符在初始的原始SQL查詢基礎上進行組合。EF Core將其視為子查詢,並在數據庫中對其進行組合。下面的示例使用原始SQL查詢,該查詢從表值函數 (TVF) 中進行選擇。然後,使用LINQ進行篩選和排序,從而對其進行組合。

var searchTerm = "http://blogs.msdn.com/visualstudio";
var blogs = _context.Blog
    .FromSql($"SELECT * FROM dbo.Blog")
    .Where(b => b.Url == searchTerm)
    .Include(c=>c.Post)
    .OrderByDescending(b => b.Createtime)
.ToList();

SQL:

exec sp_executesql N'SELECT [b].[BlogId], [b].[Createtime], [b].[Updatetime], [b].[Url]
FROM (
    SELECT * FROM dbo.Blog
) AS [b]
WHERE [b].[Url] = @__searchTerm_1
ORDER BY [b].[Createtime] DESC, [b].[BlogId]',N'@__searchTerm_1 nvarchar(4000)',@__searchTerm_1=N'http://blogs.msdn.com/visualstudio'

exec sp_executesql N'SELECT [b.Post].[PostId], [b.Post].[BlogId], [b.Post].[Content], [b.Post].[Title]
FROM [Post] AS [b.Post]
INNER JOIN (
    SELECT [b0].[BlogId], [b0].[Createtime]
    FROM (
        SELECT * FROM dbo.Blog
    ) AS [b0]
    WHERE [b0].[Url] = @__searchTerm_1
) AS [t] ON [b.Post].[BlogId] = [t].[BlogId]
ORDER BY [t].[Createtime] DESC, [t].[BlogId]',N'@__searchTerm_1 nvarchar(4000)',@__searchTerm_1=N'http://blogs.msdn.com/visualstudio'

SQL Server Profiler:

3.異步查詢

當在數據庫中執行查詢時,異步查詢可避免阻止線程。異步查詢對於在客戶端應用程序中保持響應式UI非常重要。 異步查詢還可以增加Web應用程序中的吞吐量,即通過釋放線程,以處理其他Web應用程序中的請求。

public async Task<IActionResult> Index()
{
    var id1 = Thread.CurrentThread.ManagedThreadId.ToString();

    var blogs = await _context.Blog.ToListAsync();

    var id2 = Thread.CurrentThread.ManagedThreadId.ToString();

    return View(blogs);
}

當我們運行以上代碼時候,通過在關鍵字await上下文加入兩段獲取線程ID代碼,我們會看到如下結果:

看到兩段線程代碼輸出ID結果沒有?從上圖可以觀察到,當我們在進入某個視圖或者方法時候,執行到await某一個方法,當前線程不會一直等待下去,會立馬回收到線程池,供其他地方調用!當該await方法返回數據時候,才從線程池調用空閑線程執行await方法下文餘下的步驟。所以UI界面才不會進入假死狀態。

參考文獻:

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

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

前國務卿柯瑞 找柯林頓、狄卡皮歐「結盟」抗暖化

摘錄自2019年12月2日世界新聞網報導

全球暖化和氣候變遷的影響已經成為國安問題,甚至被喻為將可能導致「第三次世界大戰」,前國務卿柯瑞(John Kerry)近日召集許多有影響力人士,如國會議員、軍事專家及好萊塢名人等,組成跨黨派聯盟——「第零次世界大戰」(World War Zero),聯合對抗氣候變遷。

該組織成員除了前總統柯林頓(Bill Clinton)和卡特(Jimmy Carter),也聚集許多好萊塢名人如影星李奧納多‧狄卡皮歐(Leonardo DiCaprio)、史汀(Sting)及艾希頓庫奇(Ashton Kutcher)等人;該組織成員目前約60人,目標是在明年募到超過1000萬元資金,並舉辦跨黨派的「氣候會談」。

柯瑞在1日連同組織成員之一,共和黨籍前加州州長阿諾‧史瓦辛格( Arnold Schwarzenegger),對於聯盟的成立發言表示:「沒有任何國家真正把事情做好,他們甚至把問題變得更糟,所以我們才召集這些人」。

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

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務

2020年生物多樣性總體檢 15項保育人士尚未關注的重大威脅與機會

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

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

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

孟加拉 氣候脆弱國家的綠能百分百之路

文:陳秉亨(蠻野心足生態協會理事長)

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

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務

青年與未來世代日開跑 以能力建置實踐巴黎協定

文:林佳儀(政大外交所)

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

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務