全球速度最快電動汽車 時速達644km

據報導,最近摩納哥跑車廠商Venturi開發出了全球速度最快的電動汽車。

這輛名為Venturi Buckeye Bullet 3(VBB3)的電動汽車,由Venturi的Formula E電動方程式團隊和俄亥俄州立大學的汽車研究中心聯合打造而成。該車之前的模型曾在2010年創造了全球電動汽車陸上行駛速度記錄:307英里每小時(mph)。但當前模型的預估速度為372mph,將輕鬆打破這一記錄。Venturi的目標是令VBB3的速度最終達到400mph(約合644km/hr)。

不過高速電動汽車也有一些自己的優勢。和其他電動車一樣,VBB3產生的熱量遠比同等功率的汽油引擎更少,因此VBB3無需冷卻通風口。不過這並不意味著該車“很冷”,實際上,其內部系統包含許多石油潤滑機制和一隻每次行駛前都要加滿冰的箱子。

去年,由於開採和氣候變化等因素造成美國邦納維爾鹽鹼灘退化,Venturi無法對VBB3進行測試,他們希望今年夏天時情況會好一些,這樣他們就能繼續其追求速度的征程。

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

【其他文章推薦】

※USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計、台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

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

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

減少汽車碳排雙管齊下,南韓要衝氫動力汽車

全球各國很少在什麼事情上取得共識,對抗氣候變遷倒是頭一遭,讓各懷鬼胎的人類能夠一致以減少排放溫室氣體為目標。在這個願景下,各國想盡辦法減少碳排放,如台灣廠商將電動機車變成一種時尚,南韓則是立志要大力推廣氫動力汽車。

目前汽車製造商包括現代、豐田都有生產氫動力車,現代在 2013 年開始大量生產氫動力車,主要是在歐洲與加州銷售,豐田是在去年開始販售第一款消費性燃料電池汽車,但因全球氫動力車因為價格太高與缺少加氣站,銷售仍不見起色。   《華爾街日報》報導,巴黎氣候變遷會議之後,南韓宣誓未來五年要增加氫動力車銷售數量從現在的 50 輛到 9,000 輛,2030 年要到 63 萬輛,等於每賣出十輛新車,就有一輛是氫動力汽車。氫動力車結合氫與氧來產生電力,副產品就是從排氣管排放的水蒸氣。   南韓政府將補貼每輛氫動力車 275 萬韓圜,約當 23,250 美元,氫動力車售價大約 8,500 萬韓圜,接近 240 萬台幣,補貼約 3%。   除了補貼,南韓還要增加加氣站從目前的 10 座,到 2030 年的 520 座。南韓宣誓未來五年,減少運輸工具碳排放 11%,約 380 萬噸。低碳排放汽車包括混合動力車與電動車將在 2020 年占南韓總汽車銷售量的 20%,現在約 2%。

(首圖來源:)

(本文授權轉載自《》─〈〉)

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

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

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

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

特斯拉下調2016中國區銷量目標至5000輛

近日,特斯拉CEO伊隆•馬斯克(ElonMusk)表示,將下調2016年中國區銷量目標至5000輛。另外,特斯拉正在努力尋找當地的合作夥伴,希望能在今年上半年順利於國內建廠。

據悉,2015年前9個月,特斯拉在中國銷售了3025台電動汽車,離2014年定下的目標1萬輛相差很遠,業績不佳是馬斯克下調了中國銷售目標的主要原因。

資料顯示,香港已成為特斯拉ModelS全球保有密度最高的城市,在2015年全球共計交付的50,580輛ModelS中,有2,221輛是來自香港的訂單,占全球約4.39%。近兩年,香港政府鼓勵市民使用電動汽車,並在香港推行電動汽車首次免登記稅政策,使電動車註冊量增長了270%,而特斯拉ModelS占到全部電動車份額的80%。

相比而言,大陸市場對特斯拉的政策支持力度顯得不足。馬斯克稱,自己的公司希望能在今年上半年順利於國內建廠,並借此減輕進口稅收方面的壓力,以及爭取更多政府為新能源車專供的政策優惠。

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

【其他文章推薦】

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

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

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

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

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

戴姆勒、特斯拉聯合開發電動版奔馳B級開始投產

電動版奔馳B級是戴姆勒繼Smart ForTwo電動版之後的第二款純電動車,由戴姆勒和特斯拉聯合開發,其電動馬達由特斯拉提供,今年將先後在美國和歐洲上市。

電動版奔馳B級擁有大約200公里的續航里程,0到100km/h加速僅需時7.9秒,最高速度為160km/h。其電動馬達由特斯拉提供,規律達174馬力,同寶馬i3電動車的規律相比還高出8馬力。目前戴姆勒尚未公佈新款奔馳B級電動車的售價。

電動版奔馳B級由戴姆勒位於德國的拉施塔特(Rastatt)工廠負責生產,汽油、柴油及天然氣版本的奔馳B級也在該工廠投產。據戴姆勒一名女發言人透露,電動版奔馳B級在其整個生命週期中的產量預計將達到五位數。

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

【其他文章推薦】

※USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計、台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

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

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

SQL Server 中 `JSON_MODIFY` 的使用

SQL Server 中 JSON_MODIFY 的使用

Intro

SQL Server 從 2016 開始支持了一些 JSON操作,最近的項目里也是好多地方字段直接存成了 JSON,需要了解一下怎麼在SQL Server 中操作 JSON.

JSON支持適用於 SQL Server 2016 及以上版本 和 Azure SQL Database。

最近在項目中很多地方字段都是存一個 JSON 字符串,尤其是針對一些有很多不確定的屬性的數據來說,這樣的信息我們一般都放在一個 Extra 之類的字段保存一個 JSON 字符串,由於不確定性很大,很有可能會遇到要修改這個 JSON 字符串結構的問題,在修改 JSON 對象的某一個值和修改 JSON 的結構時都會用到 JSON_MODIFY,今天就來介紹一下 JSON_MODIFY 的使用

示例

直接來看示例:


-- JSON_MODIFY 測試
DECLARE @testJsonValue NVARCHAR(100) = N'{"name":"John","skills":["C#","SQL"]}';
PRINT @testJsonValue;

-- 適用 append 在數組中追加元素
PRINT JSON_MODIFY(@testJsonValue, 'append $.skills', 'Azure');

-- 無效用法,這樣會把屬性更新為字符串
PRINT JSON_MODIFY(@testJsonValue, '$.skills', '["C#","T-SQL","Azure"]');

-- 修改數組
PRINT JSON_MODIFY(@testJsonValue, '$.skills', JSON_QUERY('["C#","T-SQL","Azure"]'));
-- 修改數組某個元素
PRINT JSON_MODIFY(@testJsonValue, '$.skills[0]', 'CSharp');


-- 增加屬嵌套
PRINT JSON_MODIFY(@testJsonValue, '$.Likes', JSON_QUERY('{"Girl": "Alice"}'));
PRINT JSON_MODIFY(@testJsonValue, '$.Likes', JSON_QUERY('{"Animals": ["Dog","Cat"]}'));

-- 增加 bool 屬性
PRINT JSON_MODIFY(@testJsonValue, '$.ShowAwardsAfterQuizEnds', CONVERT(BIT, 'false'));
PRINT JSON_MODIFY(@testJsonValue, '$.ShowAwardsAfterQuizEnds', CONVERT(BIT, 1));

-- 增加 int 屬性
PRINT JSON_MODIFY(@testJsonValue, '$.TotalWinnersCount', CONVERT(INT, '20'));
PRINT JSON_MODIFY(@testJsonValue, '$.TotalWinnersCount', 20);

-- 刪除屬性
PRINT JSON_MODIFY(@testJsonValue, '$.name', NULL);

輸出結果如下圖:

More

注意:

  • 如果要更新的字段沒有是一個 JSON 對象或是一個數組,那麼需要使用 JSON_QUERY ,否則更新的對應的屬性就成了字符串了。

  • 如果是要刪除某一個屬性,把某一個屬性更新為 NULL 即可

  • 如果要增加一個 bool 類型的屬性,需要把對應的值轉換為 BIT 類型

Reference

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

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

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

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

JavaScript入門經典(第7版)讀書筆記

斷斷續續看了十來天,終於看完了,還是學到些東西,這本書還是不錯的,各方面都有涉及。

補充了下之前不完善的JS 知識

筆記一般只記必要的東西。‎

Table of Contents

1 JavaScript 基礎

 

1.1 JavaScript 簡介

 

1.1.1 Web 腳本編程基礎

 

  1. 服務器端和客戶端編程
  2. JavaScript 簡介
  3. JavaScript 起源
  4. 瀏覽器的競爭
  5. <script> 標籤
    • html5 script 標籤不用指定屬性
  6. DOM 簡介
  7. W3C 和標準兼容
  8. window 和 document 對象
  9. 對象表示法
  10. 與用戶交互
  11. document.write()
  12. 讀取 document 對象的屬性

1.2 創建簡單的腳本

 

1.2.1 在 Web 頁面里添加 JavaScript

  1. 把代碼放在 script 標籤內
  2. 通過 src 引用外部 js 文件

1.2.2 編寫 JavaScript 語句

 

  1. 代碼註釋
    • 一般文件名後綴 .min.js 是去掉了空白和註釋

1.2.3 變量

1.2.4 操作符

 

  1. 算術操作符
  2. 操作符優先級
  3. 對字符串使用操作符+

1.2.5 捕獲鼠標事件

 

  1. onClick 事件處理器
    • HTML 里不區分大小寫,所以屬性名 onclick 小寫也可以
  2. onMouseOver 和 onMouseOut 事件處理器
    • 使用 this 引用 HTML 元素

      <img src="1.png" onmouseover="this.src='2.png';">
      

1.3 使用函數

 

1.3.1 基本語法

1.3.2 調用函數

 

  1. 把 JavaScript 代碼放置到頁面的<head>區域
    • 函數放到文檔開頭,確保在調用前已經被定義
    • 函數如果多次定義,會使用最後的定義
  2. 給函數傳遞參數
  3. 多參數
  4. 從函數返回值
    • 如果沒有 return, 會返回 undefined
  5. 匿名函數
    function sayHello() {
        alert("hello");
    }
    
    var sayHello = function() {
        alert("hello");
    }
    

1.4 函數的更多知識

 

1.4.1 變量作用域

 

  1. 使用 this 關鍵字
  2. 使用 let 和 const
    • 塊級作用域 let
  3. 用 const 關鍵字聲明變量

1.4.2 箭頭函數

var sayHello = function() { alert("hello"); };

var sayHello = () => alert('hello');

var myFunc = x => alert(x);

myFunc = (x, y) => alert(x + y);

myFunc = (x, y, z) => {
    let area = x*y + 5;
    let boxes = area / z;
    return boxes;
}

1.4.3 設置默認參數

1.5 DOM 對象和內置對象

 

1.5.1 與用戶交互

 

  1. alert()
    • 術語“模態”的含義
    • confirm()

      var answer = confirm("are you ok?");
      
  2. prompt()
    var answer = prompt("what is your full name?");
    var answer = prompt("what is your full name?", "cai ji");
    

1.5.2 根據 id 選擇元素

var myDiv = document.getElementById("div1");
  1. innerHTML 屬性
    var myDivContents = document.getElementById("div1").innerHTML;
    document.getElementById("div1").innerHTML = "heheda";
    

1.5.3 訪問瀏覽器歷史記錄

alert(history.length);
history.forward();
history.backward();
history.go(-3);
history.go(2);
history.go("baidu.com");

1.5.4 使用 location 對象

  • location 的屬性 .href .protocol .host .hostnmae .port .pathname .search .hash
  1. 用 location 對象導航
    • 兩種導航到新頁面的方式 location.href = “www.baidu.com”; location.replace(“www.baidu.com”); 前者會保留舊頁面在歷史記錄里
  2. 刷新頁面
    • location.reload(); 避免使用緩存 location.reload(true);
  3. 獲取瀏覽器信息: navigator 對象
    • navigator 保留瀏覽器本身的數據
    • navigator 的屬性 .appName .appCodeName .appVersion .language .cookieEnabled .cpuClass .onLine .platform .plugins.length
    • navigator 返回的信息並不準確

1.5.5 日期和時間

 

  1. 創建具有當前日期和時間的 Date 對象
    var mydate = new Date();
    var year = mydate.getFullYear();
    var month = mydate.getMonth();
    var date = mydate.getDate();
    var day = mydate.getDay();    // 星期
    var hours = mydate.getHours();
    var minutes = mydate.getMinutes();
    var seconds = mydate.getSeconds();
    
  2. 創建具有指定日期和時間的 Date 對象
    var d1 = new Date("October 22, 1995 10:57:22");
    var d2 = new Date(95, 9, 22);
    var d3 = new Date(95, 9, 22, 10, 57, 0);
    
  3. 設置和編輯日期與時間
    var mydate = new Date();
    document.write(mydate.getDay());
    mydate.setDate(15);
    document.write(mydate.getDat());
    document.write(mydate.toDateString() + mydate.toTimeString());
    
  4. 利用 Math 對象簡化運算
    • Math 的一些常見方法 .ceil(n) .floor(n) .max(a, b, c, …) .min(a, b, c, …) .round(n) 四舍五入 .random() 返回一個 0 到 1 的隨機數
  5. 取整
  6. 獲得最大值和最小值
  7. 生成隨機數
    function myRand(range) {
        return Math.round(Math.random() * range);
    }
    
  8. 数字常數

    .E 自然常數,約為 2.718 .LN2 2 的自然對數,約為 0.693 .LN10 10 的自然對數,約為 2.302 .LOG2E 以 2 為底 e 的對數,約為 1.442 .LOG10E 以 10 為底 e 的對數,約為 0.434 .PI 圓周率,約為 3.14159 .SQRT12 2 的平方根的倒數,約為 0.707 .SQRT2 2 的平方根,約為 1.414

  9. 關鍵字 with
    with (Math) {
        var myRand = random();
        var biggest = max(2, 3, 5);
        var height = round(11.22);
    }
    

2 JavaScript 編程

 

2.1 数字和字符串

 

2.1.1 數值

 

  1. 整數
  2. 浮點數
  3. 十六進制數,二進制數和八進制數

2.1.2 全局方法

 

  1. toString()
    var x = 13;
    alert(x.toString());
    alert(x.toString(16));
    (11).toString();
    
    
  2. toFixed()
    x.toFixed(0); // "13"
    x.toFixed(3); // "13.000"
    
  3. toExponential()
    var num = 666;
    num.toExponential(4); // "6.6600e+2"
    num.toExponential(6); // "6.660000e+2"
    

2.1.3 Number 對象

 

  1. Number.isNaN()
    • 當試圖把一些非數值當做數值處理,卻無法得到數值時,返回值就是 NaN
    • 示例

      Number.isNaN(3); //false
      Number.isNaN(0 / 0); // true
      
  2. Number.isInteger()
  3. Number.parseFloat() 和 Number.parseInt()
    • 解析的字符串首字符如果是一個数字,函數會持續解析到数字結束
    Number.parseFloat("21.4"); // 21.4
    Number.parseInt("12px",10); // 12
    
  4. 無窮大
    • 表示無窮的關鍵字 Infinity -Infinity
    • isFinite() 會把參數轉換為數值,如果結果是 NaN,正無窮大或負無窮大,函數返回 false

2.1.4 Number() 函數

  • 該函數會盡可能返回一個對等的數值,如果失敗,返回 NaN

2.1.5 布爾值

  • 如果布爾值被用作計算,true 為 1, false 為 0
  • JS 里被當做 false 的值
    1. 布爾值 false
    2. 未定義 undefined
    3. null
    4. 0
    5. NaN
    6. “”
  1. 非操作符

2.1.6 null(空) 和 undefined(未定義)

  • undefined 不是關鍵字,是未定義的全局變量

2.2 操作字符串

 

2.2.1 字符串

 

  1. length 屬性
  2. 轉義序列
  3. 字符串方法
    • concat
    • indexOf
    • lastIndexOf
    • repeat var inStr = “a b”; var outStr = inStr.repeat(3)
    • replace
    • split
    • substr string1.substr(4, 11); string1.substr(4);
    • toLowerCase
    • toUpperCase

2.2.2 模板字符串

var name = "aa";
var course = "bb";
var myString = `hell ${name}, welcome ${course}`;

2.3 數組

 

2.3.1 數組

  • JS 的數組能夠存放任何數據類型
  1. 創建新數組
    • 數組也是一個對象 var myArray = new Array(); var myArray = [];
  2. 初始化數組
    var myArray = ['111', '22'];
    myArray[20] = "333e";
    myArray.length
    
  3. 數組的方法
    • concat
    • join 把數組的全部元素連接在一起形成一個字符串 var longDay = myArray.join(“-”);
    • toString 相當於 myArray.join(“,”);
    • indexOf 沒有找到返回-1
    • lastIndexOf
    • slice 可以為負數
    • sort 把數組元素按字母順序排列
    • splice myArray.splice(2, 1, “heheda”); 指向索引為 2 的元素,刪除 1 個元素,插入一個新元素,返回被刪除的元素

2.3.2 如何遍曆數組

 

  1. 使用 forEach()
    • 接受一個函數作為參數,並將函數依次應用與數組中的每個元素

      var myArray = [1, 2, 3, 4];
      function cube(x) {
          console.log(x*x*x);
      }
      myArray.forEach(cube);
      
    • forEach 不返回任何值
  2. 使用 map()
    • 和 forEach 的區別在於 map 會返回和最初數組相同大小的新數組

      var myArray = [1, 2, 3, 4];
      fucntion cube(x) {
          return (x*x*x);
      }
      var newArray = myArray.map(cube);
      
  3. 使用 for-of 訪問數組
    var myArray = [2,3,4,5];
    functionn cube(x) {
        console.log(x*x*x);
    }
    for (var y of myArray) {
        cube(y);
    }
    

2.3.3 三點表示法

 

  1. 組合多個數組
    var array2 = [1, 2, ...array1, 3];
    
  2. 用參數的數組來調用函數
    var myArray = [1, 2, 3];
    alert(Math.min(...myArray));
    
  3. 收集數據
    var [a, b, ...c] = [1, 2, 3, 4, 5];
    

2.4 用 JavaScript 處理事件

  • mousedown 和 mouseup 在 click 前觸發
  • ctrlKey shiftKey altKey metaKey

2.4.1 事件的類型

  • 一些常見事件
    1. 鼠標事件
      • onclick
      • oncontextmenu 鼠標右鍵彈出菜單
      • ondblclick
      • onmousedown
      • onmouseenter 鼠標移動到一個元素上時
      • onmouseleave
      • onmousemove 鼠標在一個元素上移動時
      • onmouseover 鼠標移動到一個元素或其子元素時
    2. 鍵盤事件
      • onkeydown 按下按鍵
      • onkeypress 按下並放開按鍵
      • onkeyup 釋放按鍵
    3. DOM 對象事件
      • onerror 加載一個外部文件出現錯誤時
      • onload
      • onresize
      • onscroll 滾動了元素的滾動條
    4. 表單事件
      • onblur 元素失去焦點時
      • onchange
      • onfocus
      • onreset 重置表單
      • onselect
      • onsubmit

2.4.2 事件處理器

 

  1. 內聯事件處理器
    <a href="http://www.baidu.com" onclick="alert('hello')">baidu</a>
    
  2. 作為 DOM 對象的屬性的事件處理器
    // <a href="xxx" id="a1">aa</a>
    var myLink = document.getElementById('a1');
    myLink.onclick = function() {
        alert("hello");
    }
    
  3. 使用 addEventListener()
    var myLink = document.getElementById('a1');
    function sayHello() {
        alert("hello");
    }
    myLink.addEventListener('click', sayHello);
    myLink.removeEventListener('click', sayHello);
    
  4. 添加多個監聽器
    • 使用 addEventListener 可以對一個事件添加多個函數

2.4.3 event 對象

myInputField = document.getElementById('a');
function myFunction(e) {
    var kc = e.keyCode;
    if (kc == 27) {
        alert("xx");
    }
}
myInputField.addEventListener('keydown', myFunction);
  • event 對象會自動傳遞給事件處理器
  • e.keyCode 表示按下了哪個鍵,27 表示 Escape
  1. 阻止默認行為
    var myLink = document.getElementById('a');
    function refuseAccess(e) {
        alert("wrong");
        e.preventDefault();
    }
    myLink.addEventListener('click', refuseAccess);
    
  2. 事件冒泡和捕獲
    • 嵌套元素時,各層元素都有事件監聽器時,執行順序為冒泡
    • addEventListener 的第三個參數默認為 false,對於嵌套元素,從內向外執行,像冒泡一樣.
  3. 關閉冒泡和捕獲
    function myFunction(e) {
        var kc = e.keyCode;
        e.stopPropagation();
        if (kc == 27) {
            alert("1");
        }
    }
    

2.5 程序控制

 

2.5.1 條件語句

  • 和 C 差不多
  1. if() 語句
  2. 比較操作符
    • = 值和類型都相等
  3. 測試相等性
  4. if 進階
  5. 測試多個條件
  6. switch 語句
  7. 邏輯操作符

2.5.2 循環和控制結構

 

  1. while
  2. do…while
  3. for
  4. 用 break 跳出循環
  5. 用 for…in 在對象集里循環
    var days = [1, 2, 3, 4];
    for (i in days) {
        alert(i);
    }
    

2.5.3 設置和使用定時器

  • 這兩個方法都是 window 對象的方法
  1. setTimeout()
    function hide(elementId) {
        document.getElementById(elementId).style.display='none';
    }
    window.onload = function() {
        setTimtout("hide('id1')", 3000);
    }
    var timer1 = setTimeout("hide('id1')", 3000);
    clearTimeout(timer1);
    
  2. setInterval()
    var timer1 = setInterval("updateClock()", 1000);
    clearInterval(timer1);
    

3 理解 JavaScript 對象

 

3.1 面向對象編程

 

3.1.1 什麼是面向對象編程

3.1.2 創建對象

 

  1. 創建直接實例
    myNewObject = new Object();
    myNewObject.showInfo = myFunc;
    myNewObject.info = 'this is a info';
    
  2. 使用關鍵字 this
    • this 在 HTML 內聯 JS 里指此 HTML 元素,也可指向它所屬的對象
  3. 匿名函數
    myNewObject.showInfo = function() {
        alert(this.info);
    }
    
  4. 使用構造函數
    • 如果要創建一個類的多個實例,可以創建構造函數

      function Car(Color, Year, Make, Miles) {
          this.color = Color;
          this.year = Year;
          this.make = Make;
          this.odometerReading = Miles;
          this.setOdometer = function(newMiles) {
              this.odometerReading = newMiles;
          }
      }
      var car1 = new Car("blue", "1998", "Ford", 77777);
      

3.1.3 用 prototype 擴展和繼承對象

 

  1. 擴展對象
    function Person(personName) {
        this.name = personName;
        this.info = 'a';
        this.showInfo = function() {
            alert(this.info);
        }
    }
    var person1 = new Person('adam');
    var person2 = new Person('hehe');
    Person.prototype.sayHello = function() {
        alert(this.name + 'say hello');
    }
    
  2. 繼承對象
    function Pet() {
        this.animal = "";
    }
    function Dog() {
        this.breed = "";
    }
    Dog.prototype = new Pet();
    

3.1.4 封裝

function a(b, c, d) {
    function kk(m, n) {
        return m + n;
    }
}

3.2 對象進階

 

3.2.1 類

  • 新引入的 class 關鍵字和 constructor

    function Pet() {
        this.animal = "";
        this.setAnimal = function(newAnimal) {
            this.animal = newAnimal;
        }
    }
    
    class Pet {
        constructor(animal) {
            this.animal = animal;
        }
        setAnimal(newAnimal) {
            this.animal = newAnimal;
        }
    }
    
  1. 使用 getter 和 setter
    • 下劃線前綴防止被重複調用
    class Pet {
        constructor(animal, name) {
            this.animal = animal;
            this.name = name;
        }
        get name() {
            return this._name;
        }
        set name(n) {
            n = n.charAt(0).toUpperCase() + n.slice(1).toLowerCase();
            this._name = n;
        }
    }
    
  2. Symbol
    • 創建的 Symbol 一定是唯一的傳的參數只是說明

      var myname = Symbol('nickname');
      myCat[myname] = 'heheda';
      

3.2.2 對象繼承

 

  1. 使用 extends 和 super
    class Dog extends Pet {
        constructor(name, breed) {
            super(name);
            this.breed = breed;
        }
    }
    

3.2.3 使用功能檢測

if (document.getElementById) {
    // do something
} else {
    // other
}
  • typeof

    if (typeof document.getElementById == 'function') {
        // do something
    } else {
        // other
    }
    
  • typeof 的返回值 “number” “string” “boolean” “object” null undefined

3.3 DOM 腳本編程

 

3.3.1 DOM 節點

 

  1. 節點類型
    • nodeType 每種節點類型都有一個關聯的數值,保存在屬性 nodeType
      1. 元素
      2. 屬性
      3. 文本
      4. CDATA 區域
      5. 實體引用
      6. 實體
      7. 執行指令
      8. HTML 註釋
      9. 文檔
      10. 文檔類型(DTD)
      11. 文檔片段
      12. 標籤
    • childNodes 屬性

      function countListItems() {
          var olElement = document.getElementById("toDoList");
          var count = 0;
          for (var i = 0; i < olElement.childNodes.length; i++) {
              if (olElement.chiodNodes[i].nodeType == 1)
                  count++;
          }
      }
      window.onload = countListItems;
      
    • firstChild lastChild myElement.childNodes[0] myElement.childNodes[myElement.childNodes.length – 1];
    • parentNode 屬性
    • nextSibling previousSibling
  2. 使用 nodeValue
  3. 使用 nodeName

3.3.2 用 getElementsByTagName() 選擇元素

  • 基本用法 var myDics = document.getElementsByTagName(“div”);
  • document.getElementsByClassName()

3.3.3 讀取元素的屬性

var myNode = document.getElementById("id1");
alert(myode.getAttribute("title"));

3.3.4 Mozilla 的 DOM 查看器

 

  1. 創建新節點
    • 創建步驟
      1. 創建新節點
        • createElement() var newDiv = document.createElement(“div”);
        • createTextNode() var newTextNode = document.createTextNode(“heheda”);
        • cloneNode() var myDiv = document.getElementById(“id1”); var newDiv = myDiv.cloneNode(true) true 代表會複製子節點一般需要修改 id 值
      2. 添加到 DOM 樹
  2. 操作子節點
    • appendChild() var newText = document.createTextNode(“heheda”); var myDiv = document.getElementById(“id1”); myDiv.appendChild(newText);
    • insertBefore() var newPara = document.createElement(“p”); var myDiv = document.getElementById(“id1”); var para2 = document.getElementById(“para2”); myDiv.insertBefore(newPara, para2);
    • para.replaceChild(new, old)
    • removeChild()

      var myDiv = document.getElementById("id1");
      var myPara = document.getElementById("para2");
      var removedItem = myDiv.removeChild(myPara);
      alert(removedItem.getAttribute("id"));
      
  3. 編輯元素屬性
    var myPara = document.getElementById("para1");
    myPara.setAttribute("title", "opening paragraph");
    
  4. 動態加載 JavaScript 文件
    var scr = document.createElement("script");
    scr.setAttribute("src", "newScript.js");
    document.head.appendChild(scr);
    

3.4 JSON 簡介

 

3.4.1 JSON 是什麼

  • 使用 JSON 表示法時,對象可以方便的轉換為字符串來進行存儲和轉換
  • JSON 的真正優雅之處在於對象在 JSON 里以普通 JS 代碼錶示,因此可以利用 JS “自動” 解析功能
  1. JSON 語法
    var jsonObject = {
        "param1": "value1",
        "param2": "value2"
    }
    

3.4.2 訪問 JSON 數據

  • eval 函數參數:
    1. 表達式
    2. 表達式字符串
    3. 字符串,其中是括號包含的 json
var x = eval(1*2);
eval("a=1;b=2;document.write(a+b);");
var user = '{"user":"admin", "location": "spain"}';
var myObject = eval('(' + user + ')');
  1. 使用直接瀏覽器 JSON 支持
    • 最新瀏覽器都對 JSON 提供直接支持,所以可以不用 eval 函數
    • 瀏覽器會創建一個名為 JSON 的 JS 對象來管理 JSON 的編碼和解碼,這個對象有兩個方法,stringify() 和 parse()
  2. 使用 JSON.parse()
    var Mary = '{"h": 1.9, "age": 12}';
    var myObject = JSON.parse(Mary);
    var out = "";
    for (i in myObject) {
        out += i + " = " + myObject[i] + "\n";
    }
    alert(out);
    

3.4.3 JSON 的數據序列化

 

  1. 使用 JSON.stringify()
    var Dan = new Object();
    Dan.height = 1.85;
    Dan.age = 41;
    Dan.eyeColor = "blue";
    alert(JSON.stringify(Dan));
    

3.4.4 JSON 數據類型

  • 參數部分的規則
    1. 不能是 JS 保留的關鍵字
    2. 不能数字開頭
    3. 特殊字符只能有下劃線和美元符號
  • 值可以是以下數據類型
    1. 數值
    2. 字符串
    3. 布爾值
    4. 數組
    5. 對象
    6. null

3.4.5 模擬關聯數組

  • 在 JS 中,object[“property”] 和 object.property 是對等的
var conference = {"a": "1", "b": "2"};
alert(conference["a"]);
alert(conference.a);

3.4.6 使用 JSON 創建對象

  • 用方括號表示數組 var categories = [“news”, “sports”];
  1. 屬性

    var user = {“a”: 1, “b”: 2}; var name = user.a;

  2. 方法
    var user = {
        "a": 1,
        "setName": function(newName) {
            this.username = newName;
        }
    }
    user.setName("heheda");
    
    • 當 JSON 作為通用數據交換格式時,值不能放函數
  3. 數組
    var bookListObject = {
        "a": [1, 2, 3]
    }
    var book = bookListObject.a[1];
    
  4. 對象

3.4.7 JSON 安全性

  • eval() 能執行任何 JS 命令,對於來源不明的 JSON 數據可能存在安全問題,安全的辦法是使用內置 JSON 解析器,它只識別 JSON 文本而不會執行腳本命令

4 用 JavaScript 操作 Web 界面

 

4.1 HTML 與 JavaScript 編程

 

4.1.1 HTML5 的新標籤

  • section
  • header
  • footer
  • nav
  • article
  • aside
  • figure
  • figcaption
  • summary

4.1.2 一些重要的新元素

 

  1. 用<video> 回放視頻
  2. 用 canPlayType() 測試可用的格式
    • media.canPlayType(“video/webm”);
  3. 控制回放
    var myVideo = document.getElementById("vid1").play();
    var myVideo = document.getElementById("vid1").pause();
    
  4. 用<audio> 標籤播放聲音
    var soundElement = document.createElement('audio');
    soundElement.setAttibute('src', 'sound.ogg');
    soundElement.play();
    soundElement.currentTime = 12;
    
  5. 用<canvas> 在頁面上繪圖

4.1.3 拖放

4.1.4 本地存儲

  • 兩個對象 localStorage sessionStorage

    if (typeof(Storage) != "undefined") {
        localStorage.setItem("key", "value");
        localStorage["key"] = "value";
        alert(localStorage.getItem("key"));
        alert(localStorage["key"]);
    }
    

4.1.5 操作本地文件

 

  1. 查看瀏覽器的支持情況
    • if (window.File && window.FileReader && window.FileList)

4.2 JavaScript 和 CSS

 

4.2.1 CSS 簡介

 

  1. 從內容分離樣式
  2. CSS 樣式聲明
  3. 在哪裡保存樣式聲明

4.2.2 DOM 的 style 屬性

4.2.3 用 className 訪問類

4.2.4 DOM 的 styleSheets 對象

 

  1. 啟用,禁用和切換樣式表

4.3 CSS3 簡介

5 與 JavaScript 工具相關的高級技術

 

5.1 讀取和寫入 cookie

 

5.1.1 什麼是 cookie

 

  1. cookie 的局限性

5.1.2 使用 document.cookie 屬性

 

  1. 數據的編碼和解碼
    var str = 'hehe (aa) .';
    document.write(str + '<br />' + escape(str));
    

5.1.3 cookie 組成

  • cookieName 和 cookieValue
  • domain 用於指明 cookie 屬於哪個域,如果為 a.com ,則 b.a.com 可以訪問這個 cookie
  • path 指定可以使用 cookie 的路徑
  • secure 表明瀏覽器把 cookie 發給服務器時,是否要使用 SSL 標準
  • expires 以 UTC 標準的過期時間

5.1.4 編寫 cookie

var cookieDate = new Date ( 2018, 05, 15 );
var user = "heheda";
document.cookie = "username=" + escape(user)  + ";expires=" + cookieDate.toUTCString();

5.1.5 編寫一個函數來寫 cookie

5.1.6 讀取 cookie

5.1.7 刪除 cookie

  • 把一個 cookie 的失效日期設置為今天之前即可

5.1.8 在一個 cookie 里設置多個值

5.2 用正則表達式匹配模式

 

5.2.1 創建正則表達式

  • JS 里兩種生成正則表達式的方法
  1. 使用正則表達式字符串字面量
    • var myRegExp = FooBar;

      var myRepExp = /FooBar/;
      if (document.getElementById("txt").value.search(myRegExp) == -1) {
          alert("not found");
      } else {
          alert("The string occurs");
      }
      
    • 正則表達式修飾符

    i 不區分大小寫 g 全局匹配,而不是找到第一個匹配就停止 m 多行匹配 var aa = /stupid/gi;

    • 方括號[]指定範圍
    • 處理特殊字符的快捷方式,元字符 \w 等
    • 正則表達式限定符 + 重複次數等
  2. 使用 JS 的 RegExp 對象
    var myPattern = new RegExp("Foobar");
    var result = /boy/.exec("heheda");
    console.log(result[0]);
    myPattern.test("this is a test");
    var result = myPattern.exec(myString);
    
  3. 對正則表達式使用字符串方法
    • match search replace split

      var myString = "heheda dada";
      var outString = myString.match(/\d+/g);
      
      var myString = "1 ;2 3;4 5";
      var outString = myString.split(/\s*;\s*/);
      
      myString.replace(/stupid/ig, "cupid");
      
    • 用一個函數作為 replace() 的參數

      function CtoF(match) {
          return ((match * 9) / 5) + 32;
      }
      var myString = "for 1 and 5";
      myString = myString.replace(/\d+/g, CtoF);
      

5.3 理解並使用閉包

 

5.3.1 回顧作用域的相關知識

5.3.2 從一個函數返回另一個函數

5.3.3 實現閉包

  • 閉包是訪問父作用域的一個函數,即便是在該作用域已經結束之後.
  1. 傳遞參數
    function sayHi(visitor) {
        let msg = visitor + ' says: hello world!';
        return function logMessage() {
            console.log(msg);
        }
    }
    
  2. 編輯一個閉包變量
    function sayHi(visitor) {
        let msg = visitor + ' says: ';
        return function logMessage(extra) {
            msg = msg + extra;
            console.log(msg);
        }
    }
    var helloPhil = sayHi("Phil");
    var helloSue = sayHi("Sue");
    
  3. 閉包和變量
    • 閉包也允許將一些數據和操作這些數據的函數關聯起來
    function sayHi(visitor) {
        let msg = visitor + ' says: hello world';
        return function logMessage() {
            console.log(msg);
        }
    }
    var helloPhil = sayHi("Phil");
    helloPhil()
    
    
    • 對象提供了靈活性,但是到處都可以修改,容易出現錯誤.

5.4 用模塊組織代碼

 

5.4.1 為何使用模塊

 

  1. 模塊使得代碼更容易維護
  2. 模塊幫助復用代碼
  3. 模塊有助於整齊的全局作用域

5.4.2 模塊基礎知識

  • 一個文件一個模塊,模塊中的內容對外部不可見.
  • 模塊是通過 CORS 跨源資源共享來獲取的
  1. 如何包含一個 JS 模塊
    • JS 要求對模塊使用相對路徑

      <head>
        <script type="module" src="./myModule.js"></script>
      </head>
      
  2. nomodule 關鍵字

    <script nomodule src=“fallback-option.js”></script>

5.4.3 導出

function fun1(x) {
    alert(x);
}
export func1;
  1. 一個簡單的示例模塊
    function convertCtoF(c) {
        return (c*1.8) + 32;
    }
    function convertFtoC(c) {
        return (f-32) / 1.8;
    }
    export {convertCtoF, convertFtoC}
    
    export var a = "something";
    export function func1() {console.log("hello");};
    
  2. 如何在導出時重命名
    export var distance = arr[1];
    export {arr as routeProperties };
    
  3. 具名的和默認的導出
    function mmToInches(d) {
        return d/25.4;
    }
    export default mmToInches;
    

5.4.4 導入

import {convertCtoF, convertFtoC} from './tempConvert.js';
  1. 默認導入
    function mmToInches(d) {
        return d/25.4;
    }
    export default mmToInches;
    
    import toInches from './convert.js';
    console.log(toInches(100));
    
  2. 如何在導入的過程中重命名

    import {convertCtoF as cF } from ’./tempConvert.js’;

  3. 如何把一個模塊導入為一個對象

    import * as temps from ’./tempConvert.js’;

6 專業技能

 

6.1 良好的編程習慣

 

6.1.1 避免過度使用 JS

6.1.2 編寫易讀和易維護的代碼

 

  1. 明智地使用註釋
    • 代碼較長地函數或對象地簡要說明
    • 對易混淆或易誤解代碼地註釋
    • 原作者自己地技巧或經驗
    • 關於代碼修改地註釋
  2. 使用適當地文件名稱,屬性名稱和方法名稱
  3. 盡量復用代碼
  4. 不要假設

6.1.3 平穩退化

6.1.4 漸進增強

 

  1. 分離樣式,內容和代碼

6.1.5 代碼分離的 JS

 

  1. 脫離 HTML
  2. 僅把 JS 作為性能增強手段

6.1.6 功能檢測

6.1.7 妥善處理錯誤

 

  1. 使用 try 和 catch

6.2 調試代碼

 

6.2.1 調試簡介

 

  1. 錯誤類型
    • 語法錯誤
    • 運行時錯誤
    • 邏輯錯誤
  2. 選擇程序員地編輯器
  3. 用 alert() 進行簡單調試

6.2.2 更高級地調試

 

  1. 控制台
    • console console.log() console.warn() console.info() console.error()
  2. 分組消息
    • console.group() console.groupEnd() 之間的 log 信息會分組显示
  3. 用斷點停止代碼執行
  4. 條件性斷點
  5. 從代碼中啟動調試器
    • debugger;
  6. 驗證 JS

6.3 繼續深入學習

 

6.3.1 為什麼要使用庫

6.3.2 庫能做什麼

  • 一般庫的功能
    1. 封裝 DOM 方法
    2. 動畫
    3. 拖放
    4. Ajax

6.3.3 一些常見的庫和框架

 

  1. Prototype 框架
    • 優勢在於 DOM 擴展和 Ajax 處理
  2. Dojo
    • 能夠簡化創建程序和用戶界面的工作
  3. React
    • 主要用於構建用戶界面
  4. Node.js
    • 允許在服務器上編寫和執行 JS
  5. jQuery
    • 簡化了 HTML 文檔轉換,事件處理,動畫等多種工作

6.3.4 jQuery 入門

 

  1. 在頁面里引用 jQuery
    • 本地下載 <script src=“jquery-3.3.1.js”></script>
    • 遠程 <script src=“”></script>
  2. jQuery 的$(document).ready 處理器
    • 類似於 window.onload

      $(document).ready(function() {
          // code
      });
      
  3. 選擇頁面元素
    • $(“”) 即可選擇 HTML 元素 $(“span”) $(“#elem”) //id $(“.classname”) $(“div#elem”) $(“ul li a.menu”) / 類為 menu,且嵌套在列表項里的錨點 $(“p > span”) / p 的直接子元素 span $(“input[type=password]”) $(“p:first”) $(“p:even”) // 全部偶數段落 $(“:header”) //標題元素 $(“:button”) $(“:radio”) $(“:checkbox”) $(“:checked”)
  4. 操作 HTML 內容
    • html() 類似於 innerHTML

      var htmlContent = $("#elem").html();
      $("#elem").html("<p>here </p>");
      
    • text() 只是獲取文本內容

        var textContent = $("#elem").text()
        $("#elem").append("<p>hehe </p>");
      
    • attr()

      var title = $("#elem").attr("title");
      $("elem").attr("title", "new title");
      
  5. 显示和隱藏元素
    • JS 中 document.getElementById(“elem”).style.visibility = “visible”;
    • show()

      $("div").show();
      $("#elem").show("fast", function() {
          // 操作
      });
      
    • hide()

      $("#elem").hide("slow", function() {
          // 隱藏之後的操作
      });
      
    • toggle()

      $("#elem").toggle(1000, function() {
          // xx
      });
      
  6. 命令鏈
    • jQuery 大多數方法都返回一個 jQuery 對象

      $("#elem").fadeOut().fadeIn();
      $("#elem").text("Hello ").fadeOut().fadeIn();
      
  7. 處理事件
    • 常用方法

      $("a").click(function() {
          //
      });
      function hello() {
          alert("hello");
      }
      $("a").click(hello);
      $("a").on("click", hello);
      
    • 常見事件 blur focus hover keypress change mousemove resize scroll submit select

6.3.5 The jQuery UI

  • jQuery UI 提供了高級的效果和可以主題化的掛件
  1. jQuery UI 是什麼
    $("#datepicker").datepicker();
    

6.3.6 Ajax 簡介

 

  1. Ajax 入門
  2. XMLHttpRequest 對象
    • XMLHttpRequest 能夠建立與服務器的連接,發送 http 請求而不需要加載相應的頁面
    • 默認 xhr 只能對同域發起請求,除非服務端做了設置
  3. 創建 request 對象
    • var request = new XMLHttpRequest();
  4. 方法和屬性
    • 屬性 onreadystatechage readyState responseText responseXML status statusText
    • 方法 abort() getAllResponseHeaders() getResponseHeader(x) open(’method’,’URL’,’a’) // a 默認為 true,表示異步 send(content) setRequestHeader(’x’,’y’)
  5. 與服務器通信
  6. 在服務器端發生了什麼
  7. 處理服務器響應
  8. 還有更容易的方法,不是嗎?

6.3.7 用 jQuery 實現 Ajax

  • load()

    $(function() {
        $("#elem").load("newContent.html");
    });
    
    $(function() {
        $("#elem").load("newContent.html #info");
    });
    
  • get() post()

    $.get("serverScript.php",
          {param1: "value1", param2: "value2"},
          function(data) {
              alert("server response: " + data);
          });
    
  • ajax()
  • 對錶單數據進行序列化 var formdata = $(’#form1’).serialize();

6.3.8 Node.js 簡介

  • Node.js 使用 V8 JavaScript 引擎
  1. 使用一種非阻塞的代碼模式

Author: cat

Created: 2019-11-13 Wed 22:40

 

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

【其他文章推薦】

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

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

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

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

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

Python語言基礎05-函數和模塊的使用

本文收錄在

在分享本章節的內容之前,先來研究一道數學題,請說出下面的方程有多少組正整數解。

事實上,上面的問題等同於將8個蘋果分成四組每組至少一個蘋果有多少種方案。想到這一點問題的答案就呼之欲出了。

可以用Python的程序來計算出這個值,代碼如下所示。

"""
輸入M和N計算C(M,N)

Version: 0.1
Author: along
"""
m = int(input('m = '))
n = int(input('n = '))
fm = 1
for num in range(1, m + 1):
    fm *= num
fn = 1
for num in range(1, n + 1):
    fn *= num
fmn = 1
for num in range(1, m - n + 1):
    fmn *= num
print(fm // fn // fmn)

輕鬆得出答案為:35

 

1. 函數的作用

  不知道大家是否注意到,在上面的代碼中,我們做了3次求階乘,這樣的代碼實際上就是重複代碼。編程大師Martin Fowler先生曾經說過:“代碼有很多種壞味道,重複是最壞的一種!”,要寫出高質量的代碼首先要解決的就是重複代碼的問題。對於上面的代碼來說,我們可以將計算階乘的功能封裝到一個稱之為“函數”的功能模塊中,在需要計算階乘的地方,我們只需要“調用”這個“函數”就可以了。

1.1 定義函數

  在Python中可以使用def關鍵字來定義函數,和變量一樣每個函數也有一個響亮的名字,而且命名規則跟變量的命名規則是一致的。在函數名後面的圓括號中可以放置傳遞給函數的參數,這一點和數學上的函數非常相似,程序中函數的參數就相當於是數學上說的函數的自變量,而函數執行完成后我們可以通過return關鍵字來返回一個值,這相當於數學上說的函數的因變量。

在了解了如何定義函數后,我們可以對上面的代碼進行重構,所謂重構就是在不影響代碼執行結果的前提下對代碼的結構進行調整,重構之後的代碼如下所示。

def factorial(num):
    """求階乘"""
    result = 1
    for i in range(1, num + 1):
        result *= i
    return result

m = int(input('m = '))
n = int(input('n = '))
# 當需要計算階乘的時候不用再寫循環求階乘而是直接調用已經定義好的函數
print(factorial(m) // factorial(n) // factorial(m - n))

  說明: Python的math模塊中其實已經有一個factorial函數了,事實上要計算階乘可以直接使用這個現成的函數而不用自己定義。下面例子中的一些函數在Python中也都是現成的,我們這裡是為了講解函數的定義和使用才把它們又實現了一遍,實際開發中不建議做這種低級的重複性的工作。

 

2. 函數的參數

  函數是絕大多數編程語言中都支持的一個代碼的”構建塊”,但是Python中的函數與其他語言中的函數還是有很多不太相同的地方,其中一個顯著的區別就是Python對函數參數的處理。在Python中,函數的參數可以有默認值,也支持使用可變參數,所以Python並不需要像其他語言一樣支持,因為我們在定義一個函數的時候可以讓它有多種不同的使用方式,下面是兩個小例子。

from random import randint

def roll_dice(n=2):
    """搖色子"""
    total = 0
    for _ in range(n):
        #print(_)
        total += randint(1, 6)
        #print(total)
    return total

def add(a=0, b=0, c=0):
    """三個數相加"""
    return a + b + c


# 如果沒有指定參數那麼使用默認值搖兩顆色子
print(roll_dice())
# 搖三顆色子
print(roll_dice(3))
print(add())
print(add(1))
print(add(1, 2))
print(add(1, 2, 3))
# 傳遞參數時可以不按照設定的順序進行傳遞
print(add(c=50, a=100, b=200))

  我們給上面兩個函數的參數都設定了默認值,這也就意味着如果在調用函數的時候如果沒有傳入對應參數的值時將使用該參數的默認值,所以在上面的代碼中我們可以用各種不同的方式去調用add函數,這跟其他很多語言中函數重載的效果是一致的。

 

2.1 函數的可變參數

  其實上面的add函數還有更好的實現方案,因為我們可能會對0個或多個參數進行加法運算,而具體有多少個參數是由調用者來決定,我們作為函數的設計者對這一點是一無所知的,因此在不確定參數個數的時候,我們可以使用可變參數,代碼如下所示。

# 在參數名前面的*表示args是一個可變參數
def add(*args):
    result = 0
    for num in args:
        result += num
    return(result)

# 在調用add函數時可以傳入0個或多個參數
print(add())
print(add(1))
print(add(1, 2))
print(add(1, 2, 3))
print(add(1, 3, 5, 7, 9))

 

3. 用模塊管理函數

  對於任何一種編程語言來說,給變量、函數這樣的標識符起名字都是一個讓人頭疼的問題,因為我們會遇到命名衝突這種尷尬的情況。最簡單的場景就是在同一個.py文件中定義了兩個同名函數,由於Python沒有函數重載的概念,那麼後面的定義會覆蓋之前的定義,也就意味着兩個函數同名函數實際上只有一個是存在的。

def foo():
    print('hello, world!')

def foo():
    print('goodbye, world!')

# 下面的代碼會輸出什麼呢?
foo()

   當然上面的這種情況我們很容易就能避免,但是如果項目是由多人協作進行團隊開發的時候,團隊中可能有多個程序員都定義了名為foo的函數,那麼怎麼解決這種命名衝突呢?答案其實很簡單,Python中每個文件就代表了一個模塊(module),我們在不同的模塊中可以有同名的函數,在使用函數的時候我們通過import關鍵字導入指定的模塊就可以區分到底要使用的是哪個模塊中的foo函數,代碼如下所示。

(1)先在同級目錄下,創建2個py文件

module1.py

def foo():
    print('hello world')

module2.py

def foo():
    print('goodbye world')

 

(2)直接使用模塊使用函數

test.py

from module1 import foo
foo()

from module2 import foo
foo()

 

(3)也可以按照如下所示的方式來區分到底要使用哪一個foo函數。

test.py

import module1 as m1
import module2 as m2

m1.foo()
m2.foo()

 

(4)但是如果將代碼寫成了下面的樣子,那麼程序中調用的是最後導入的那個foo,因為後導入的foo覆蓋了之前導入的foo。

test.py

from module1 import foo
from module2 import foo

foo()

from module2 import foo
from module1 import foo

# 輸出hello, world!
foo()

  需要說明的是,如果我們導入的模塊除了定義函數之外還中有可以執行代碼,那麼Python解釋器在導入這個模塊時就會執行這些代碼,事實上我們可能並不希望如此,因此如果我們在模塊中編寫了執行代碼,最好是將這些執行代碼放入如下所示的條件中,這樣的話除非直接運行該模塊,if條件下的這些代碼是不會執行的,因為只有直接執行的模塊的名字才是”__main__”。

module3.py

def foo():
    pass

def bar():
    pass

# __name__是Python中一個隱含的變量它代表了模塊的名字
# 只有被Python解釋器直接執行的模塊的名字才是__main__
if __name__ == '__main__':
    print('call foo()')
    foo()
    print('call bar()')
    bar()

test.py

import module3
# 導入module3時 不會執行模塊中if條件成立時的代碼 因為模塊的名字是module3而不是__main__

 

4. 練習

練習1

實現計算求最大公約數和最小公倍數的函數。

參考答案:

def gcd(x, y):
    """求最大公約數"""
    #(x, y) = (y, x) if x > y else (x, y)
    if x > y:
        (x, y) = (y, x)
    else:
        (x, y)
    for factor in range(x, 0, -1):
        if x % factor == 0 and y % factor == 0:
            return factor

def lcm(x, y):
    """求最小公倍數"""
    return x * y // gcd(x, y)

print(gcd(9,12))
print(lcm(9,12))

 

練習2

實現判斷一個數是不是迴文數的函數。

參考答案:

def is_palindrome(num):
    """
    判斷一個數是不是迴文數
    迴文數是指將一個正整數從左往右排列和從右往左排列值一樣的數
    """
    temp = num
    total = 0
    while temp > 0:
        total = total * 10 + temp % 10
        temp //= 10
    return total == num

 

練習3

實現判斷一個數是不是素數的函數。

參考答案:

def is_prime(num):
    """判斷一個數是不是素數"""
    for factor in range(2, num):
        if num % factor == 0:
            return False
    return True if num != 1 else False

print(is_prime(1))

 

練習4

寫一個程序判斷輸入的正整數是不是迴文素數。

參考答案:

if __name__ == '__main__':
    num = int(input('請輸入正整數: '))
    if is_palindrome(num) and is_prime(num):
        print('%d是迴文素數' % num)
    else:
        print('%d不是迴文素數' % num)

 

  注意:通過上面的程序可以看出,當我們將代碼中重複出現的和相對獨立的功能抽取成函數后,我們可以組合使用這些函數來解決更為複雜的問題,這也是我們為什麼要定義和使用函數的一個非常重要的原因。

 

5. 變量作用域

(1)最後,我們來討論一下Python中有關變量作用域的問題

def foo():
    b = 'hello'

    # Python中可以在函數內部再定義函數
    def bar():
        c = True
        print(a)
        print(b)
        print(c)

    bar()
    # print(c)  # NameError: name 'c' is not defined


if __name__ == '__main__':
    a = 100
    # print(b)  # NameError: name 'b' is not defined
    foo()

  上面的代碼能夠順利的執行並且打印出100、hello和True,但我們注意到了,在bar函數的內部並沒有定義a和b兩個變量,那麼a和b是從哪裡來的。

  我們在上面代碼的if分支中定義了一個變量a,這是一個全局變量(global variable),屬於全局作用域,因為它沒有定義在任何一個函數中。在上面的foo函數中我們定義了變量b,這是一個定義在函數中的局部變量(local variable),屬於局部作用域,在foo函數的外部並不能訪問到它;但對於foo函數內部的bar函數來說,變量b屬於嵌套作用域,在bar函數中我們是可以訪問到它的。bar函數中的變量c屬於局部作用域,在bar函數之外是無法訪問的。事實上,Python查找一個變量時會按照“局部作用域”、“嵌套作用域”、“全局作用域”和“內置作用域”的順序進行搜索(由小到大),前三者我們在上面的代碼中已經看到了,所謂的“內置作用域”就是Python內置的那些標識符,我們之前用過的input、print、int等都屬於內置作用域。

  其中,在foo函數中調用bar函數的變量c,會報錯;因為讀不到此變量。

 

(2)再看看下面這段代碼,我們希望通過函數調用修改全局變量a的值,但實際上下面的代碼是做不到的。

def foo():
    a = 200
    print(a)  # 200

if __name__ == '__main__':
    a = 100
    foo()
    print(a)  # 100

   在調用foo函數后,我們發現a的值仍然是100,這是因為當我們在函數foo中寫a = 200的時候,是重新定義了一個名字為a的局部變量,它跟全局作用域的a並不是同一個變量,因為局部作用域中有了自己的變量a,因此foo函數不再搜索全局作用域中的a。

 

(3)如果我們希望在foo函數中修改全局作用域中的a,代碼如下所示。

def foo():
    global a
    a = 200
    print(a)  # 200

if __name__ == '__main__':
    a = 100
    foo()
    print(a)  # 200

  我們可以使用global關鍵字來指示foo函數中的變量a來自於全局作用域,如果全局作用域中沒有a,那麼下面一行的代碼就會定義變量a並將其置於全局作用域。

  同理,如果我們希望函數內部的函數能夠修改嵌套作用域中的變量,可以使用nonlocal關鍵字來指示變量來自於嵌套作用域,請大家自行試驗。

  在實際開發中,我們應該盡量減少對全局變量的使用,因為全局變量的作用域和影響過於廣泛,可能會發生意料之外的修改和使用,除此之外全局變量比局部變量擁有更長的生命周期,可能導致對象佔用的內存長時間無法被垃圾回收。事實上,減少對全局變量的使用,也是降低代碼之間耦合度的一個重要舉措,同時也是對的踐行。減少全局變量的使用就意味着我們應該盡量讓變量的作用域在函數的內部,但是如果我們希望將一個局部變量的生命周期延長,使其在定義它的函數調用結束后依然可以使用它的值,這時候就需要使用,這個我們在後續的內容中進行講解。

  說明: 很多人經常會將“閉包”和混為一談,但實際上它們並不是一回事,如果想了解這個概念,可以看看的解釋。

說了那麼多,其實結論很簡單,從現在開始我們可以將Python代碼按照下面的格式進行書寫,這一點點的改進其實就是在我們理解了函數和作用域的基礎上跨出的巨大的一步。

def main():
    # Todo: Add your code here
    pass

if __name__ == '__main__':
    main()

 

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

【其他文章推薦】

※USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計、台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

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

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

COP25氣候峰會失敗的關鍵:巴黎協定第六條 嚴格國家訂《聖荷西原則》走自己的路

環境資訊中心記者 姜唯翻譯 林大利審校

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

【其他文章推薦】

※USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計、台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

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

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

特斯拉要在中國蓋工廠了!將在 2016 年中前完成選址

看來,特斯拉(Tesla)在中國的電動車銷量似乎不如外界先前預期差。特斯拉執行長馬斯克(Elon Musk)日前在香港參加科技論壇前夕受訪表示,特斯拉在中國的營運「相當良好」,將在中國設立工廠,並預計在 2016 年中前完成廠房選址。

雖然在受訪時,馬斯克未透露特斯拉在中國的具體銷售數字,但馬斯克表示,特斯拉在中國的營運狀況目前「相當良好」,似乎不受先前在中國的銷量遠低於預期影響,並表示,要在中國開啟特斯拉電動車製造計畫,正在尋找當地的合作夥伴與工廠,預計在 2016 年中前完成中國工廠選址。   與其他非中國的汽車製造商相同,特斯拉之所以要在中國興建工廠,關鍵的因素便在於要規避中國政府對進口車徵收的進口稅,以減少貨運開銷,讓特斯拉的電動車在中國市場更有競爭力。此外,中國政府鼓勵新能源汽車的發展,也是因素之一。   目前特斯拉在中國 7 個主要城市設有 15 個業務據點、超過 340 個超級充電站及逾 1,600 個充電樁。其中,光是香港就有 42 個超級充電站,使其成為特斯拉在中國快速擴張的充電網路中,充電站密度最高的城市,而特斯拉在香港的銷量也遠高於中國其他城市,2015 年 Model S 銷售量為 2,221 台,占了特斯拉 2015 年在中國所有銷量的 80%。   香港的電動車熱潮也讓馬斯克看見特斯在其中的潛在市場龐大。在 2014 年至 2015 年間,香港的電動車登記數字就飆升了 270%,馬斯克認為,之所以會有如此驚人的成長,歸因於香港政府的「優良政策」,帶動了電動車的銷量。此外,馬斯克透露,Model X 將會在 2016 下半年,隨著特斯拉在香港的新服務中心進軍香港。

(首圖來源: CC BY 2.0)

(本文授權轉載自《》─〈〉)

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

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

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

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

豐田「未來」多國上路,台灣氫燃料車未來何在?

日本豐田汽車在去年推出FCEV氫燃料電池車「Mirai(未來)」,目前已在日本、德國、比利時、丹麥、美國等多個國家上市。目前台灣因欠缺相關法規與氫能政策,仍無法讓FCEV上路,或讓氫燃料電池技術廣泛使用。

豐田的Mirai是全球首輛FCEV,電力來自氫燃料電池;運轉時只會產生水,沒有任何廢氣與污染物,且「加氫」也只需要3分鐘就能行駛650公里。日本相當重視氫燃料電池技術,致力於打造「氫社會」,目標在2020年時讓FCEV的市佔率達到1%。目前除了豐田之外,本田汽車也將在今年推出另一款FCEV。

總統當選人蔡英文日前試乘Mirai,負責接待的和泰汽車協理黃明顯表示,目前台灣只有汽油車、柴油車與電動車的檢驗標準,FCEV無法可用,因此自然不能上路。若要在台灣引進FCEV,則政府須就汽車法規與氫燃料政策進行探討,才有可能看到台灣FCEV的「未來」。

豐田Mirai的訂價大約是700萬日幣,日本民眾在國內購買時享有補助,僅需約500萬日幣就能購置。加上日本計畫將2020東京奧運的選手村打造純氫氣功能的「氫氣城」,相關規章與建設正如火如荼展開當中。相較之下,台灣尚無適用法規,自然也就還沒有引入氫燃料的機會。

FCEV較有疑慮的問題是加氫站的設置。除了FCEV與加氫站的數量需到達一定規模才能具有較好的經濟效益外,由於氫容易燃燒,因此加氫站以及相關管線、設備都需就安全性進行多考量,並解決周遭居民的疑慮。Mirai 採用高纖維儲存氫氣,若氫氣外洩時將會自動啟動隔離閥,也有快速揮散氫氣的功能,藉此確保Mirai的行車安全。

(圖:Honda於FC EXPO 2016 展出的氫燃料電池車)

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

【其他文章推薦】

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

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

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

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