計算機是人思想的一部分,邏輯、秩序、規則…… 不常見的任務須要額外的編程才能解決。git
機器很死板,無趣。程序員
忍受機器後能享受到便利。express
借鑑了天然界以及人類的模式到編程的設計上。編程
編程的規則原理語法很簡單,但創造出知足複雜世界的需求會很難。api
學習中的有些困難和痛苦勢必要的。這樣以後的學習就更容易了。數組
不要妄自菲薄,換換方式,或者歇一歇,而後堅持學習。瀏覽器
計算機結構是龐大的,找到圍繞目標的所需的知識,理解運行原理。安全
計算機很蠢,可是優勢是很快。bash
控制計算機解決問題,就是掌控複雜度的藝術,掌控很差就崩了。。服務器
新的問題每每用舊的眼光和方式解決很差,或者不夠好。
不斷的實踐出錯優化才能融會貫通各類狀況下的考慮,而簡單的閱讀卻沒辦法作到。
從最底層到最接近問題,編程語言存在着不一樣層面的抽象,有時候細節須要忽略,有時候又要操縱細節,這方面作得最好的是C++,而JS是主要面向瀏覽器的。它的不少抽象層級都面向瀏覽器的應用而不是性能,底層,等等。
幹同一件事的代碼能夠寫成不少樣子,是更易閱讀,更省性能仍是寫代碼用的時間最少(這是人和公司最寶貴的東西,除此以外才是金錢花費),取決於你的需求進行平衡取捨。
JS最先是寫瀏覽器交互、特效之類的小腳本。
JS與Java有關,否則爲啥不起別名,但僅僅是爲了蹭市場名聲,技術實現上上大抵都無關。
JS在編程語言中很爛,但它面向新手,使用的人多了,一次次版本更新也變好起來了。曲線救國,人多才是王道。
JS歷史不談,2015年後ES6版本,每一年都有更新,因此快更新瀏覽器與時俱進吧!
JS還在MongoDB中能夠做爲腳本查詢語言、Node.js服務器語言。
不只要學,還要寫出來。這是一門工程學科,實現是根本,學是爲了實現的更好。 Don’t assume you understand them until you’ve actually written a working solution.
語言,瀏覽器,Node.js。也就是能幹什麼,在哪裏幹,還能夠在哪裏幹。
程序的表面之下是龐大的代碼支撐着
計算機中只有數據,數據的信息能夠被解釋爲控制指令、文件內容等。
二進制的bit,binary digit,只有0和1的序列,表明着各類信息。
例如數字13的二進制表示。
0 0 0 0 1 1 0 1
128 64 32 16 8 4 2 1
複製代碼
易失性內存:8g -> 687 1947 6736 bits,687億個比特(嚇了一跳吧~)
管理如此大量的比特們,須要進行分模塊處理,否則會迷失混亂。values, 編程語言中的各類值來劃分不一樣含義的比特信息,值多了抽象出類型,具備一樣的特色,細化下去就是值的不一樣,再向上抽象就是類型的不一樣。
計算機是複雜的,內存也是複雜的,但人的生命是有限的,沒辦法瞭解全部的細節。(這是全部矛盾的源頭)
cost
6
let cost = 6;
6
是cost
綁定的值,仍是這行命令執行6
次。6
給我存在哪一個地方6
能夠共享給其餘變量,仍是不能重複利用的的獨一無二的6
進行的綁定……number, 64bits
if((x-3.14)<0.01)
, 而不是 if(x==3.14)
數字通常還要分出一位用來表示正負,若是還要表示小數就要有更多位的損耗,有各類表示小數的方法,你看想要完成更多的功能,就確定要付出一些東西。
數字的主要功能是用來算術,因此這些東西不是被憑空發明出來的,而是實實在在有用纔會出如今JavaScript中。
二元操做符:+ - * / %
precedence: * / % > + -
%: remainder operator
改變默認優先級:括號
Infinity
, -Infinity
NaN
: not a numberbackticks
,反引號中的string,也叫template literalhalf of 100 is ${100 / 2}
${}
''
""
\
+
操做符:concatenates操做符除了用符號表示,再多了符號不夠用命名關鍵字表示.
操做符的操做數能夠是一個,兩個……
一元操做符:
typeof
: return a string of type of the operand符號的一詞多義:
-(2-1)
:
-
,unary operator,操做的對象是一個,即2-1
的結果,語義是將一個數置負,-
,binary operator,須要兩個操做對象,語義是有兩個數,他們想減信息的存儲最理想狀態是e次方,即2.718,而現實離理想還有段距離,因此目前的計算機是基於二進制的,實際上三進制更理想。不過二進制是第二好的選擇,比十進制不知道高到哪裏去了。
既然是二進制,就免不了這個二的狀態由哪兩個表示,計算機說是0和1,實際上在不一樣器件裏面的表示,有用電平高低的,有用正弦不一樣的,程序利用true
和false
,日常咱們說話用有和沒有,是或者不是,開或者關,若是是三進制那還包括一種狀況,那就是不知
。
比較的結果是個布爾值
字符的比較是按照ASCII碼以及Unicode碼來的,而不是字典中從A到Z的順序,注意Unicode字符是ASCII的超集,而後ASCII中的編碼在Unicode中大小是相同的,所謂的兼容ASCII,無非是前面多8個0。
只有一種值不等於它本身: NaN
,它的含義就是用來表示無心義的結果,因此他也不和其餘無心義結果相等。Oh,shit,難以理解。。
語義:注意它的操做對象是布爾值,不是用來算數的,儘管數字0和1會被變量提高轉換成true 和 false。
&&
||
!
precedence: > == > && > ||
一個三元的邏輯操做符:true ? 1 : 2
, ternary, conditional operator, question mark and a colon
三元操做符短路,意味着有些語句不執行。
短路,左邊算完了若是返回左邊,右邊就不驗證了,稱short-circuit evaluation.
||
左邊true就返回左邊,false就返回右邊。 &&
左邊false就返回左邊,true就返回右邊。
我從未據說過布爾邏輯的處理是這樣的,什麼叫and運算?左邊false,就返回左邊對象?爲何不是返回false?我要你這個運算何用?這種神奇的功能我本身八輩子都用不到
垃圾語言,奇葩設定,毀我青春,****。
WTF爲何不和C++,Java同樣?
Examples of expressions that can be converted to false are:
null;
NaN;
0;
empty string ("" or '' or ``);
undefined.
複製代碼
||
先把左邊轉換成布爾值,是個數就返回左邊,不是個數返回右邊- `0`, `NaN`, `""`, `null`, `undifined`會被算做 `false`
- 其餘的全部算做`true`
複製代碼
- `console.log('bat||'ant') // -> bat`
複製代碼
- `console.log(null||'hi') // -> hi`
複製代碼
||
,使之成爲備胎。設計上的委曲求全,唉,但是Rust語言不火啊,人們並不須要正確,人們須要兼容穩定能用。
null
undefined
JS老是喜歡能處理你給的各類值,也就是對你很包容,但這對於精確的控制卻很差。語言的設計
type coercion
null*8 -> 0
"5" - 1 -> 4字符拼接優先於數值計算。
"5" + 1 -> 51
NaN
若是一旦產生,那麼與此相關的結果仍是會NaN
自動類型轉換和嚴格相等
==
,!=
NaN
null
和 undefined
之間爲true,和其餘爲false===
和!==
磚塊在高樓中才能體現更大的價值。意思是良禽擇木而棲才能發揮更大價值?
可以產生一個值的代碼塊稱之爲表達式,expression。字面值,帶括號,運算式都是expression
expression之間互相組合、嵌套組成了語義更復雜的expression。
expression是某一小段子句,而語句,statement是一句完整的話。程序就是一列語句們的集合。
最簡單的statement是一個expression加上一個分號。(可忽略的分號。。。)
expression產生一個值,而後被周圍的代碼所利用。
而statement隻立足於他本身,除非指定和其餘東西有交集。當改變了屏幕上的文字或者改變了計算機內部的一些狀態,以至於影響後來的語句執行的結果,這就叫作影響,effects。像1;
這種語句確實改變了了計算機內部的東西,但對於別的代碼沒有明顯的做用。
分號這個東西大部分時間可加可不加,可是你懂的總有意外。有時候不加分號會讓會讓兩行代碼變成互相影響的一句statement,爲了安全、不找麻煩,仍是加上吧,否則要認識不少哪些是必須加分號的複雜狀況。
表達式會產生一個值,好比1+2
,可是產生的結果3
,若是不馬上使用它,或找一個空間分給他,它立刻就不見了。
let caught = 5 * 5;
variable or binding
keyword: let
, 聲明+賦值
caught
,就是宣佈要有光!,而後計算機內存裏面就找到一個地方對應着這個caught
.5*5
的結果綁定到了caught
上。caught
,它就會被要麼做爲空間地址,要麼取它的值25
。var
是個歷史遺留問題,const
一次聲明賦值爲常量,鞠躬盡瘁,死然後已。
字母、數字、$
和_
,不能以數字開頭,不能用關鍵字,不能用保留字。
其實就一個原則就行了,字母開頭,各類駝峯表明變量、函數、仍是類。也別起什麼各類奇葩名字,沒事找事。
程序啓動的時候,環境就激活了語言自己的一部分綁定,以及提供交互的一些綁定。
默認環境提供的一些變量類型爲function.
調用、請求函數的執行,稱invoking, calling, applying.
回想數學f(x)=y+1;函數要有輸入x,用括號來表示。稱arguments, 這個參數可能(x,y),也能夠是(x,3,4)
console.log
functionconsole.log 不是一個綁定,它包含了一個句號,對吧,變量名是不容許的,那它是什麼呢? console是一個綁定,.log表明檢索這個綁定的一個名爲log的property。
side effect: 函數的主要做用是用來返回一個值的,那麼顯示一段文字,彈出對話框叫作反作用。(這是函數定義,不是寫代碼的目的。。)
因爲函數要return一個結果,因此它符合一個expression,也就是能夠和另外的expression組合嵌套在一句statement中。console.log(Math.min(1, 3)+1);
prompt中輸入的值爲string,用Number()轉換成number進行計算,其實不用人工轉化下一行計算的時候會自動轉換類型的。。
原先一條路走到黑,如今變成二選一,而後繼續走下面的語句。
if (1 + 1 == 2) console.log("It's true");
通常狀況下代碼要寫的讓人看着方便,大部分都要加大括號,除非一行簡單的if。
多重嵌套的時候每次當下判斷都是二選一,注意合併簡化
2^10 (2 to the 10th power)
do while,for 和 while(){}的區別就是語義上的
continue
純粹爲了易讀性,一個仍是兩個空格、一個仍是多個換行都不影響它的邏輯。但換不換行是有區別的,參考加不加;
的各類規則。
明明有while爲何還要發明for呢?由於經常使用啊,由於代碼邏輯驚人的類似重複的部分人就願意把它封裝成新東西,輕輕一揮,魔法就實現了,多好。
for和while的區別就是while常常須要一個循環計數器,而且每輪循環都必需要改動這個循環計數器,再加上原本的條件判斷,這不就是for啦?
for中不設循環終止判斷,就能夠把判斷挪到循環體中if(){*; *; break;}中,這樣的好處是判斷完以後能夠繼續在for的環境中執行一些語句。也就是說若是有if(){break;},考慮是否能夠放在for語句頭中?
break
若是用原來的機制實現,至關於在原代碼前加了個if,而且添加的一個分支只有一個改變循環條件、而且還要抵消for第三個語句(若是在for語句中)。你看現在你想要的,一個break就能夠解決了。
continue
表明着跳過這句以後的循環體中的代碼,執行for第三部分(若是在for語句中)。而後繼續下一次循環
continue
若是用原來機制實現,至關於原代碼前添加if,而且添加的一個分支什麼都不作,而且還要抵消for第三個語句(若是在for語句中)。
這兩個一個是直接跳出全部循環,一個跳出當前這一輪循環。
當一個變量的變化是由原來的本身進行更新的話,能夠直接在賦值的時候指定什麼操做
counter = counter +1;
// 更簡便的自我更新
counter += 1;
// 對於自個人加一減一,還能夠縮寫
counter ++;
// 在Java中 a++ 和 ++a 實現不同,返回的對象是一份原a對象的拷貝對象,因此值和原a同樣,後者返回的是加完的a對象,因此相對於原a值加一。在JS中還不知道啥實現
複製代碼
注意default:
和break:
,雖然不少時候工具會自動猜想你的意圖,幫你補全一些不嚴謹的邏輯。
一個多狀態的值 --> 多重if的代碼的簡寫模式 --> 就是switch。。經常使用的東西纔會被髮明。
多對多的怎麼辦呢?用函數封裝一下,多個輸入值,每一個值有多個狀態,隨你所願的組合判斷,
一切都是有緣由的,可是全部的事咱們真的須要知道緣由?
有時候代碼並不能層次鮮明的由淺入深,由全局到定位局部信息的導航功能,這個時候須要註釋來快速定位一大坨只有一個名字的代碼究竟是幹什麼的。
VS Code
中快捷鍵Ctrl /
能夠快速判斷當前是HTML仍是CSS仍是JavaScript仍是JSX代碼進行插入相應的註釋。
注意多行嵌套沒有實現(不是不能實現)交錯的處理。以及 //
右邊全算做註釋
Q1:
#
##
###
####
#####
######
#######
複製代碼
A1:
for (let i=0, j=""; i<7; i++) {
j += "#";
console.log(j);
}
複製代碼
Q2:
print number 1-100, 3的倍數用Fizz代替,5的倍數用Buzz代替,如果3和5的倍數,用15代替
複製代碼
A2:
for(let i=1; i<=100; i++) {
let result = new Array();
let string = "";
let number = i;
if(i%3===0) {
string += "Fizz";
}
if(i%5===0) {
string += "Buzz";
}
result.push(string||number);
for(let i of result) {
console.log(i);
}
}
複製代碼
||
的奇葩設定正好幫助返回FizzBuzz或者備胎數字,納愛斯。Chessboard
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
複製代碼
A3:
// 若將該功能封裝爲函數,下面就是輸入的參數變量,n階矩陣,兩種要打印的符號
let size = 8;
let symbol1 = " ";
let symbol2 = "#";
// 橫向重複的最小單元,要進行O(logn) 替換掉 O(n)的重複字符的複製
let symbolSum = symbol1 + symbol2;
let contentOddAddon = size%2==1?symbol1:"";
let contentOdd = repeatCharBinary(symbolSum, Math.floor(size/2)) + contentOddAddon;
// 求偶數行的內容,由奇數行內容轉換,踢掉第一個,再根據最後一個添加適當元素
let contentEvenArray = contentOdd.split("");
contentEvenArray.shift();
contentEvenArray.push((contentEvenArray[contentEvenArray.length-1]==symbol1)?symbol2:symbol1);
let contentEven = contentEvenArray.join("");
// 縱向重複的最小單元,要進行O(logn) 替換掉 O(n)的重複字符的複製
let contentTwoLine = contentOdd + "\n" + contentEven + "\n";
let contentOddLineAddon = size%2===1?contentOdd:"";
let content = repeatCharBinary(contentTwoLine, Math.floor(size/2)) + contentOddLineAddon;
console.log(content);
// 重複某個字符的nlog函數
function repeatCharBinary(char, n) {
// 這個地方須要進行重複計算字符,能夠將代碼封裝爲一個函數
// 線性複製char更改成指數級複製
// 將十進制n轉換爲二進制,除2取餘,對應一、二、四、八、16的權重
// 餘1則存在,那麼將結果加上對應的權重數量的字符串,餘0則表示不存在,那就不加這位的字符串。
let tmp="";
while(n!=0) {
if(n%2==1) {
tmp += char;
}
n = parseInt(n/2); //結果從低位算起,餘1則存在,結果加之,繼續除2餘1,算更高一位
// 以前算每一位的權重是否存在,這一行是算若是存在,對應的字符串長多少,每輪要變爲更低位字符串的兩倍。
char += char;
}
return tmp;
}
複製代碼
搞計算機的是天才麼?不是的,你們只是站在巨人的肩膀上,用別人生產的磚塊壘起本身想要的一面牆。
函數是個很重要的內容。它將一大塊代碼濃縮成一個名字。這樣能夠分解一個大問題的龐大代碼,變成幾個小問題的代碼,只抽象出變化的部分,稱之爲輸入,而後輸入參數進入一樣邏輯的代碼中,產生不一樣的輸出。而僅僅只須要用一個函數名字就能夠關聯變量和邏輯。
優秀的文章常常經過不一樣的詞彙乃至精妙絕倫的句子來體現文章的藝術,而編程不一樣,它只在意能幹成什麼事,因此可能不那麼動聽引人入勝。
編程中的語言就像公式同樣枯燥,但若是懂了就明白它的精確和簡潔,不一樣於文章給人精神上的享受,相似的帳單也很枯燥,但它精確簡潔,而且你須要它的時候,他能知足你。
let area = function(x,y) { return x*y;}
複製代碼
能夠經過綁定到一個變量來重複調用這個函數。
函數功能
做用域只在當前以及子做用域
多級嵌套,lexical scoping
let hi = function() {
};
複製代碼
新建變量的函數綁定,要加分號。
函數綁定的名字呢,還能夠被綁定爲別的東西,因此變量並非函數,他只是個指示器,表明着它可能指向一個數字、字符串、或者是函數等。
聲明式的函數標記, 僅僅聲明,不進行調用
function hello() {}
複製代碼
let hey = (x, y) => {
};
複製代碼
省略了函數名,而後直接將輸入指向輸出。
const square = x => x*x;
複製代碼
,
, 方便往後直接添加.let power = (base, exponent=2) => {
let result;
if(exponent===0) {
result = 1;
} else {
result = base * power(base, exponent-1);
}
return result;
};
console.log(
power(0),
power(1),
power(0,3),
power(2,1),
power(2,2),
power(3),
power(100,3),
power(100,100),
);
複製代碼
函數執行完會把return的值返還到調用它的地方,而後繼續執行接下來的代碼。
call stack: 函數調用的棧
給一個函數多個參數,而函數只要一個的時候,它就取一個而且繼續執行。
而若是給的函數不夠,那麼默認undefined
怎麼樣JS是否是很混蛋?若是程序員無心寫錯了,他都不報錯?
那若是有意寫成這樣,至關於C++ 中的函數重載。
function minus(a, b) {
if (b === undefined) return -a;
else return a - b;
}
複製代碼
哇,好牛逼。。這樣居然實現了減法。。一個數就是減本身,兩個就是互相減
默認參數, 另外指定了則按指定的,無指定的按默認的
funcition area(redius, PI=3.14) {
}
複製代碼
ES2015後改成了正常編程語言的做用域規則。chain scope,子能夠看到父,父不可看到子的變量。 ES2015以前只有function有本身的做用域。
ES2015以前定義的var關鍵字最好用let, const代替。 若是沒有關鍵字直接hi="hi"
,默認是全局做用域
內部做用域能夠調用父做用域的變量,那麼若是父做用域想調用子做用域呢?
讓父函數新建一個子函數,並return這個子函數,子函數能夠訪問它爹,而後新建一個變量承接父函數,這個變量就綁定到了return回的子函數。
若是這個變量是全局的,那麼這個子函數不會回收,因此它爹也不會回收。
一樣不用var新建的變量若是綁定到了一個函數,也是全局變量,不會回收。
因此注意垃圾滿了。儘可能不須要不要用閉包。
這樣引用一個函數實例的一個子函數,稱之爲一個閉包。
函數調用本身叫作遞歸,遞歸要有終止條件return出去.
優雅和速度老是頗有趣的矛盾體。。。更快意味着可能只顧目的,吃相很差看。更好看,可能顧及的就多,妨礙了核心目標。因此以切都是權衡,哪些必需要快不顧長相,快到什麼程度?一樣相反。
一個程序的項目實現的地方有不少,市場、宣傳、技術、組織。而技術之中也有開發效率、機器效率、用戶友好、利於維護等一堆互相矛盾的點,要抓住主要的目的,勢必就要在其餘點上妥協。你不可能用最快的開發速度,寫出最省機器資源、最利於維護擴展、最對用戶友好的代碼。
機器的快速發展,因此程序語言愈來愈高級,庫愈來愈順手,你若是總是擔憂這個地方性能很差,那麼你想一想你有沒有由於自由的呼吸空氣而以爲浪費,有沒有以爲本身跑步呼吸了更多的空氣而浪費?爲何?由於空氣與你的呼吸相比很廉價,一樣在機器相對於人的時間很廉價。因此那段代碼利於你快速理解閱讀、而且最快的知足功能,爲何要去省下幾口空氣呢?除非你掉進了水裏(機器運行吃力),當空氣(性能)真的很重要的時候,再去考慮空氣(性能)。
甚至不少你覺的必定要優化的東西根本不值一提, 就像你多呼吸了兩口空氣同樣可有可無.你收貨的只有沾沾自喜覺得賺到了, 但你失去的是你最寶貴的生命的幾分鐘甚至幾個小時.
還有不少時候你所謂的優化在優化編譯器的專業大師前不值一提, 它甚至原本能夠大幅度自動優化的地方,被你用生澀的奇技淫巧僅僅優化了一點.不要自做聰明, 衡量你生命的付出和換來的產出而不只僅是沾沾自喜.
求從1開始, [+5]或者[*3]獲得指定數的方法
遞歸在多分支的時候實現起來比循環更好。
${ variable }
添加變量.let findIt = target => {
function find(current, history) {
let result;
if (current === target) {
result = history;
} else if (current > target) {
result = null;
} else {
result = find(current + 5, `(${history} + 5)`) ||
find(current * 3, `(${history} * 3)`);
}
return result;
}
return find(1, "1");
}
複製代碼
個人函數, 進化吧! 通常對函數的需求體如今兩方面:
即保證數字爲3, 真的是聞所未聞, 用字符串長度來作判斷讓其一次次的加0直到3位...
function printFarmInventory(cows, chickens) {
let cowString = String(cows);
while (cowString.length < 3) {
cowString = "0" + cowString;
}
console.log(`${cowString} Cows`);
let chickenString = String(chickens);
while (chickenString.length < 3) {
chickenString = "0" + chickenString;
}
console.log(`${chickenString} Chickens`);
}
printFarmInventory(7, 11);
複製代碼
當咱們在農場又加了豬以後, 重複的代碼塊被封裝再一個函數裏面.
function printZeroPaddedWithLabel(number, label) {
let numberString = String(number);
while (numberString.length < 3) {
numberString = "0" + numberString;
}
console.log(`${numberString} ${label}`);
}
function printFarmInventory(cows, chickens, pigs) {
printZeroPaddedWithLabel(cows, "Cows");
printZeroPaddedWithLabel(chickens, "Chickens");
printZeroPaddedWithLabel(pigs, "Pigs");
}
printFarmInventory(7, 11, 3);
複製代碼
函數名字又臭又長, 這裏面有幾個基本的信息
0
, 這叫封裝不變的, 留出變化的接口(函數的輸入)一個名字意思精煉小巧的函數, 不只能讓人一眼看出它的意義, 還可讓別的代碼複用這種基礎的函數, 想想語言自己帶的那些經常使用的函數, 越是通用越是功能單一, 越是能夠互相組合成爲更強大的功能. 想想鍵盤上的26個字符, 不只能打出成千上萬的英文文章, 還能打出漢字來.靠的就是抽象基本模式,使得記憶負擔小, 這叫討人喜歡, 而後互相組合能打出各類字, 這叫功能強大. 若是是無心義的編碼,你要記2k多種沒有規律的基本漢字的編碼, 不討人喜歡吧, 雖然功能也強大.
原則: 不要亂優化修改, 除非你明確的須要, 否則一切從簡,快,正確. 當你僅僅須要一朵花的時候, 那就不要又設置花盆又設置肥料. 要控制住你的衝動, 你優化的東西可能和你的目的沒多大關聯, 僅僅是來自基因的傾向性要讓你熟悉探索周圍環境, 由於你可能沒寫多少有意義的代碼, 卻浪費時間改來改去讓機器內存下降0.01%?那主要任務怎麼辦?
function zeroPad(number, width) {
let string = String(number);
while (string.length < width) {
string = "0" + string;
}
return string;
}
function printFarmInventory(cows, chickens, pigs) {
console.log(`${zeroPad(cows, 3)} Cows`);
console.log(`${zeroPad(chickens, 3)} Chickens`);
console.log(`${zeroPad(pigs, 3)} Pigs`);
}
printFarmInventory(7, 16, 3);
複製代碼
函數能夠用來return一個有用的值, 也能夠side effect.
但主要做用在return的值上面的函數, 才能夠有用的和其餘函數組合.爲啥? 由於side effect就在函數內部, 輸出的信息無法傳給別的函數.
pure function: 不依賴其餘代碼的side effect, 也不輸出本身的side effect. 每次一樣的輸入, 都會產生一樣的輸出. 一個純函數若是在某一個地方正常, 那麼它在全部地方都正常.而其餘函數可能依賴的環境不一樣.
在機器朝向純數學發展的路上時, 純函數確定擁有更嚴謹有效的解決問題的能力, 但... 機器並非純粹的理想產物,它被現實一代代所創造優化, 因此用面向機器的代碼在目前每每更高效, 而純函數做爲高級抽象, 耗費更多的資源.
let min = (x,y) => x>y?y:x;
複製代碼
基本:
let isEven = (x) => {
let result;
switch(x) {
case 0:
result = false;
break;
case 1:
result = true;
break;
default:
result = isEven(x>0?x-2:x+2);
break;
}
return result;
};
console.log(isEven(50));
// → true
console.log(isEven(75));
// → false
console.log(isEven(-1));
// → ??
// 這個屢次判斷正負的語句能夠提早置於外部, 講這個函數封閉爲閉包訪問靜態變量, 使判斷正負只運行一次.
複製代碼
let countChar = (string, char) => {
let cnt = 0;
for(let i=0; i<string.length; i++) {
if(string[i] === char)cnt++;
}
return cnt;
}
console.log(countChar("HelHsdfklkjlkhloHi", "H"))
複製代碼