文章加密

;

2024年7月23日 星期二

const numbers = [33, 2, 8]; numbers.sort(); //[2, 33, 8]

quiz:

const numbers = [33, 2, 8]; 

numbers.sort();  //[2, 33, 8]


Solution:

JavaScript is a dynamically typed language, which means that all standard library functionality must, at some point, decide how to work for most, if not all, use-cases.

Always keep in mind that the following array is valid:

const array = ["1", true, 55, 1.421, "foo", {}];


Array.prototype.sort now needs to make a decision on how to handle such scenarios, and the solution is pretty straight-forward:

Convert all values to their string representation (because every value in JavaScript can always be converted to a string!), and then sort them in lexicographic order(字典順序).

Which basically makes sort see the array as this:

const intermediate = ["33", "2", "8"];


And in lexicographic order, no matter how many characters a string has, comparison starts at position 0, and "3" comes before "8".

And in the end, the result is this:

["2", "33", "8"];

console.log(3 > 2 > 1); // false

 console.log(3 > 2 > 1); // false


因為

先比較 3>2 // true

後比較 true > 1

根據之前提及的 coercion變成Boolean(true) > 1 // false



[陷阱] console.log(typeof typeof 1); // string

 console.log(typeof typeof 1); // string


This actually returns "string".

This expression is evaluated from right to left.

The first sub-expression evaluated actually is typeof 1 which will return "number".

Only after that the next sub-expression is evaluated which now is typeof "number" which returns "string".

[陷阱]console.log("This is a string." instanceof String); // false

 console.log("This is a string." instanceof String); // false


This actually returns false.

The reason for that circumstance is that JavaScript distinguishes between primitives and objects.

And "This is a string." is actually a primitive string and not an instance of the object String.

If the code was like this:

new String("This is a string.") instanceof String


you'd actually get the result you would have expected at the beginning.

What instanceof actually does is checking if the String constructor is nested within the prototype chain of the value provided.

In this case, it isn't.

++{String}, prefix-operator, converting the right-side argument to a number

 The plus operator is defined for numbers and strings and as soon as a string is present on either the left or right side, a string concatenation is perfomed.


If we follow the execution path, this is what happens:

// 1st step
'b' + 'a' -> 'ba'
// 2nd step
'ba' + + 'a' // wait a second!

There are two plus operators in this expression. But one of those is actually a prefix-operator, and not a classical plus.
What it does is converting the right-side argument to a number
, but converting 'a' to a number will actually yield NaN!
Let's continue with following the execution path:

// 1st step
'b' + 'a' -> 'ba'
// 2nd step
'ba' + + 'a' -> 'ba' + NaN -> 'baNaN'
// 3rd step
'baNaN' + 'a' -> 'baNaNa'
// 4th step
'baNaNa'.toLowerCase() -> 'banana'

[有未看]the abstract equality comparison algorithm, which is also called the type-coercing equality check.

quiz:

// 1st step
false == '0'

// 2nd step
Number(false) == '0' -> 0 == '0'

// 3rd step 0 == '0' -> 0 == Number('0')

// 4th step
0 == 0 -> 0 === 0 -> true


solution:

there is a hierarchy for type coercion in JavaScript. The coercion process follows a set of rules:

  1. If either operand is a null or undefined, they are considered equal (unless strict equality is being used with the "===" operator).
    先檢查是否null或undefined
  2. If either operand is a boolean, the boolean is converted to a number (false becomes 0, true becomes 1) before comparison.
    布林值轉數字
  3. If one operand is a string and the other is a number, the string is converted to a number before comparison.
    字串和數字比的話,字串轉數字
  4. If one operand is an object and the other is a primitive value, the object is converted to its primitive value before comparison. This can be done using the valueOf() or toString() methods of the object.
  5. If the operands are both strings, they are compared as strings.
後兩個比較深,先跳過

small quiz

 console.log(typeof NaN); // number

console.log(Number([])); // 0

console.log(Number(![])); // 0

console.log(Number([2])); // 2

console.log(Number([0,0])); // NaN


**

undefined means this thing has no value for some reason. Most of the times you encounter undefined it means that something has gone wrong.

On the other hand, null means this thing has no value, I recognise this and it's the way I would like it to be. 看見null表示是編寫者故意設的

typeof(undefined)Should output ← "undefined"
typeof(null)Should output ← "object"
This is regarded by many as a mistake in the language.
It's too late to fix it now so we'll have to deal with it.

[有未看]String.raw`C:\Developmentml` ,讓跳脫字元無效的方法(但不要把html什麼的放進去,單純的字串就好,不然要再多看看)

 未看https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw



有一點比較特別的是,如果將 \ 放在字串的最後,會導致當成判斷字串的引號被當成跳脫序列而產生錯誤。

2024年5月1日 星期三

黄子弘凡 這見識 這麼年輕有點猛,累了看一看

https://zhuanlan.zhihu.com/p/675860025 

1.过去改变不了,未来展望不到,现在凑合着过吧。

2.没有什么水逆 ,你只是在给自己的好运蓄力。

3.大家可以放肆的去热爱生活的同时,也更加热爱自己,当你热爱生活的时候,我觉得生活也会更加的热爱你,让每天都可以成为幕圆满的每一天。

4.没有人能够决定你的选择是对是错。

5.我很幸运,把自己的热爱变成了事业。

6.选择音乐从来不是一件勇敢的事,坚持才是。

7.我有自己的坚持,有自己的追求,也有自己想要的更多的东西,不是我贪心,只是我想获得更多的尝试。

8.一定要快乐,要幸福,做自己想做的,要自由。

9.我觉得自己现在就是一颗想燃烧,但是燃烧了一半就是半燃烧的一颗恒星!

10.未到结局,焉知生死,不到最后,你永远不知道自己能创造出什么机会和可能。

11.灯光老师麻烦把灯关一下谢谢,这个时候不需要有我们有她们就够了。

12.也许那是最后无悔与忠贞,才是成长的真谛吧。

13.难熬的时候终归是难熬的,过了这段时间会是一片彩虹。

14.我不怕熬夜,不怕失败,我可以重来。

15.什么时候不满意自己,那就打碎不满意的自己。

16.我希望每一个年轻人在寻找自己梦想的同时,都不要只停留在自己的想象里。

17.枯燥的过程机械的反复练习,才是你走进自己心之所向的唯一途径。

18.我摔倒了就爬起来,爬起来下次接着摔呗,下一次要更华丽的摔到。

19.年轻人正处在一个积极接触外界的一个阶段,被误解、否定、偏见在所难免。但是一个年轻人想要证明自己,想要获得认可,除了不被个人情绪打倒,更重要的是学习如何成为一个更好的大人。

20.我觉得做什么事儿都是要有野心的,要给自己定一个也许攀登都攀登不到的一个高度。如果你连给自己设立目标的勇气胆量都没有,我觉得真的是,搬砖吧。

21.其实有的时候如果你可以简单的伸出一只援手,在我们生活的这样的一个环境中,当我们真的感受到别人的爱的同时,我们也要自己主动的敞开心扉去爱身边的一个人,我觉得如果这样的话,可以让整个环境可以变得越来越暖。

22.现在回想起这段时光,其实我记得 其实不是辛苦其实我觉得更多的是对自己的感谢,因为选择了一条更难的路,并锻炼出了更结实的羽翼。

23.多经历一些坏事才是好事,开心的日子是短暂的,痛苦的日子是永恒的。

24.一条自由的鱼,想去哪就去哪,至少在我这个年龄,我有底气说这个话,我是自由的。

25.我们之中有的人会在外界的压力下变得畏首畏尾也看的人会因自我的迷茫而放弃自己热爱的方向,青年虽竟满力量,也充满着苦恼,就像不同年龄段之间的群体,他们很难相互理解每个人在成长的过程中都会经历自身和外界的强烈碰撞。

2024年4月12日 星期五

webpack速成

https://www.youtube.com/watch?v=uP6KTupfyIw

https://github.com/scps960740/Webpack-crash-course-2021-bruceFE/blob/master/webpack.config.js

https://webpack.js.org/concepts/


To get started you only need to understand its Core Concepts:

  • Entry
  • Output
  • Loaders  // 處理閱讀非js的檔案(webpack 預設只讀懂js)



    babel用來協處處理最新的js可以被讀懂

    https://babeljs.io/setup#installation
    preset-env 是目前最新的意思


    (css 類似的如postcss)









    **https://webpack.js.org/guides/asset-modules/#root 







    Asset Modules allow one to use asset files (fonts, icons, etc) without configuring additional loaders.

    Prior to webpack 5 it was common to use:

    Asset Modules types replace all of these loaders by adding 4 new module types:

    • asset/resource emits a separate file and exports the URL. Previously achievable by using file-loader.
    • asset/inline exports a data URI of the asset. Previously achievable by using url-loader.
    • asset/source exports the source code of the asset. Previously achievable by using raw-loader.
    • asset automatically chooses between exporting a data URI and emitting a separate file. Previously achievable by using url-loader with asset size limit.

    When using the old assets loaders (i.e. file-loader/url-loader/raw-loader) along with Asset Modules in webpack 5, you might want to stop Asset Modules from processing your assets again as that would result in asset duplication. This can be done by setting the asset's module type to 'javascript/auto'.


  • Plugins 
    // 處理刪除檔案夾裡的檔案
    // HtmlWebpackPlugin: 在build出來的檔名加入動態hash後,自動動態產生相應的html等行為





    以./base.html內的template為模板產生新的html(我想vue或react等不會需要這樣)

另外MiniCssExtractPlugin是讓build出來的css從html裡獨立出來成自己一個檔案,可設定filename參數加入hash




        還有如CopyWebpackPlugin

**補充 devtool: 'source-map'可以讓build出來的檔案多出xxxx.map,這會在瀏覽器看source時可以看到非production被編譯過的版本的code,協助debug



build 會把檔案build出來


dev會起server,沒特別設置時抓的是當前目錄資料夾,如果有index.html就會顯示它,它裡面要載入剛build出來的output.js









2024年4月11日 星期四

react 速成

https://www.youtube.com/watch?v=zqV7NIFGDrQ
https://github.com/scps960740/React-crash-course-2021-bruceFE

 1. Hook: 在编程领域,钩子(hook)是一种技术,允许开发人员在代码的特定点插入自定义代码(like function),以便在程序执行过程中执行特定的操作或修改程序行为。

https://react.dev/reference/react/hooks


**useState is a React Hook that lets you add a state variable to your component. 

const [name, setName] = useState('Edward');

function handleClick() {
setName('Taylor');
setAge(a => a + 1);
  setNumber(function(prev){
    return prev + 100
  })
// ...


<div name={name} />

父子層自動雙向綁定,不用emit


**useEffect is a React Hook that lets you synchronize a component with an external system.(所以當update btn click,應使用useEffect將資料傳給後端,而不是在btn上掛update function)

就像vue的watch with immediate: true

const Home = () => {

  useEffect(() => {

    // 綁定的事件

    return()=>{  // 這個很少用

        // 取消綁定的事件 

    }

  }, [watch的變數]) 

 //如果沒有變數,就是只執行最初的一次,後面沒有監聽(感覺這個是比較不正規的做法嗎嗎嗎???)

//[watch的變數可以不只一個

}


**useRef is a React Hook that lets you reference a value that’s not needed for rendering.


2. jsx

**jsx 就像vue裡的template

**只要想在jsx裡用js就要用大括號

例如:

// List.js   // 這是個component

const arr = [1, 2, 3]

const List = () =>{

    return <div className="list">

       

            arr.map(item => <div>{item}</div>)

        }

        </div>

}

export default List


3. Why shouldn't I use index as key in render a array?

Using the index as a key when rendering an array in React is generally discouraged for a few reasons:


Stability: Indexes may change if items are added, removed, or reordered in the array. This can lead to unnecessary re-renders and potentially affect component state or cause unexpected behavior.


Performance: React uses keys to efficiently update and reconcile the DOM. When using the index as the key, React may have to re-render more components than necessary, impacting performance.


Component State: If components in the array have internal state or rely on lifecycle methods, using the index as the key can lead to inconsistencies or errors when components are re-ordered or removed.


Instead, it's recommended to use a unique identifier for each item in the array as the key. This ensures stability, improves performance, and helps maintain component state integrity. If the array items don't have a unique identifier, consider adding one or using a library like uuid to generate unique keys.


solution 1

use uuid package  如下

import { v4 } from "uuid";


const Edit = ({ add, submittingStatus }) => {

  const [note, setNote] = useState("");

  function noteChange(e) {

    setNote(e.target.value);

  }


  const [date, setDate] = useState("");

  function dateChange(e) {

    setDate(e.target.value);

  }


  const [time, setTime] = useState("");

  function timeChange(e) {

    setTime(e.target.value);

  }


  // TODO del

  console.log(note, date, time);


  function addItem() {

    submittingStatus.current = true

    add(function (prevData) {

      return [       

        {

          id: v4(),

          note,

          date,

          time,

        },

        ...prevData,

      ];

    });

  }


4. 快速模擬後端給資料json-server

https://www.npmjs.com/package/json-server


5.Idempotent

https://ihower.tw/blog/archives/6483

idempotent 的意思是如果相同的操作再執行第二遍第三遍,結果還是跟第一遍的結果一樣 (也就是說不管執行幾次,結果都跟只有執行一次一樣)

根據 HTTP 的規格,GET, HEAD, PUT 和 DELETE 是 idempotent,相同的 Request 再執行一次,結果還是一樣。只有 POST 和 PATCH 不是 idempotent,POST 再執行一遍,會再新增一筆資料,PATCH 則是有不能保證 idempotent 的可能性(徵求例子)。POST 和 PATCH 都不是 idempotent 的操作,這也是為什麼 Github API 裡用 POST 當做 PATCH 的相容取代方案。

另一個 HTTP Methods 特性是”Safe”,這比較簡單,只有 GET 和 HEAD 是 Safe 操作。Safe 特性會影響是否可以快取(POST/PUT/PATCH/DELETE 一定都不可以快取)。而 Idempotent 特性則是會影響可否 Retry (重試,反正結果一樣)。

Safe?Idempotent?
GETYY
POSTNN
PATCHNN
PUTNY
DELETENY
透過 Idempotent 的特性,有時候可以幫助你判斷該用哪一個 HTTP Methods。回到前面講 PUT 好像不太好用,例如以瀏覽器為主的 HTML 應用表單,要麻是 POST 新增資料,要麻就是用 PATCH 部分更新已經存在的資料(你不會希望用 PUT 修改個人資料的時候,每次都要重傳照片吧),因此比較少用到 PUT。這也是為什麼 Rails 4 把表單修改的 PUT 改成 PATCH Method,透過 Rails 鷹架產生出來的 update,其實符合的是 PATCH 行為而不是 PUT。

不過還是有一些我認為蠻適合用PUT的情境,例如訂閱東西該用POST還是PUT呢?

POST /subscriptions
# 還是
PUT /subscriptions/{something_id}
訂閱東西只有兩個狀態,”已訂閱”或”沒有訂閱”,這個訂閱的操作再重送幾次,還是”已訂閱”,所以我認為蠻符合 PUT 的 idempotent 特性。而對應的取消訂閱 API 想當然就是

DELETE /subscriptions/{something_id}
另外一個我覺得有趣又實用的 PUT 例子是,設計 API 给可以離線 offline 使用的行動裝置(例如iPhone)。支援 offline 產生的資料,通常會使用 UUID 來產生 ID,這樣就不需要透過中央伺服器管控 ID,方便裝置之間的同步。這樣的情境下,新增資料的 REST API 其實可以提供兩種:

POST /items # 參數帶 uuid=4937973d-e349-460a-a6ad-38625125b24a。如果不帶uuid則由server來產生uuid
# 和
PUT /items/4937973d-e349-460a-a6ad-38625125b24a
對行動裝置的 client 來說,用POST的問題在於離線環境的不穩定,有可能POST之後沒有收到回傳,因此行動裝置不確定有沒有同步成功,這時候要再重試(retry),但是用 POST 就爆炸了,因為 server 會再新建一筆 uuid 重複的資料。但是用 PUT 就沒有問題了,PUT 是 Idempotent 的操作,可以重送沒有關係 (可以再搭配 Conditional PUT 的機制,用 ETag 和 Last-Modified Headers 確保沒有覆蓋衝突)

如果是沒有 offline 需求的 client,例如第三方應用,那麼就可以用 POST /items 這個 API,交由 server 來產生 uuid。