成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

探討奇技淫巧

soasme / 3180人閱讀

摘要:探討奇技淫巧起源在工程實(shí)踐中,我們常常會(huì)遇到一些奇技淫巧。所謂奇技淫巧,就是官方在設(shè)計(jì)或者實(shí)踐中并未想象出的代碼風(fēng)格或者使用場(chǎng)景。那么究竟應(yīng)不應(yīng)在平時(shí)學(xué)習(xí)呢究竟應(yīng)不應(yīng)該在工程中使用呢,或者使用怎么樣的奇技淫巧。

探討奇技淫巧 起源

在工程實(shí)踐中,我們常常會(huì)遇到一些奇技淫巧。所謂奇技淫巧,就是官方在設(shè)計(jì)或者實(shí)踐中并未想象出的代碼風(fēng)格或者使用場(chǎng)景。其實(shí)也就是類似于 react 的 hoc,本來(lái)源自于社區(qū),但是該方案卻成為了官方肯定的方案。那么究竟應(yīng)不應(yīng)在平時(shí)學(xué)習(xí)呢?究竟應(yīng)不應(yīng)該在工程中使用呢,或者使用怎么樣的奇技淫巧。

兩年前。我還沒(méi)有畢業(yè),在大學(xué)的最后一個(gè)學(xué)期中選擇了進(jìn)入前端,同時(shí),被吸引到前端陣營(yíng)中一個(gè)不得不說(shuō)的原因就是 js 的奇技淫巧,同時(shí)個(gè)人是一個(gè)比較獵奇的人,所以就學(xué)了很多關(guān)于 js 的奇技淫巧。

現(xiàn)在這些奇技淫巧要么變成了這門語(yǔ)言不可或缺的一部分,要么隨著時(shí)間的推移而消失,還有一些在不知不覺中卻忘記了,既然這次的文章是介紹這方面的知識(shí),也就多介紹一下之前學(xué)習(xí)的一些例子。

~ 運(yùn)算符 + indexOf

在 es6 includes 尚未推行之前,我們判斷判斷字符串或者數(shù)組包含只能使用 indexOf 這個(gè)方法,但是 indexOf 返回的確實(shí)元素的索引,如果不存在則返回 -1。
因?yàn)樵谥皩?c 語(yǔ)言的時(shí)候,我們往往使用 0 代表成功,1 2 3代表著不同的錯(cuò)誤。因?yàn)?是獨(dú)一無(wú)二的。在類c的語(yǔ)言中是具有 truthy falsy 這個(gè)概念。并不指代bool的 true 與 false。

下表代表了js 的 truthy 以及 falsy。

變量類型 falsy truthy
布爾 false true
字符串 " " 非空字符串
數(shù)值 0 NaN 任何不為falsy的數(shù)值
null
undefined
對(duì)象(數(shù)組), {} 以及 []

對(duì)于數(shù)值而言,我們知道 0 對(duì)于數(shù)值是唯一的,而 -1不是。那么我們可以通過(guò) ~ 運(yùn)算符來(lái)把-1 變?yōu)?0.

~-1
// 0
~1
//-2

解釋下
對(duì)每一個(gè)比特位執(zhí)行非(NOT)操作。NOT a 結(jié)果為 a 的反轉(zhuǎn)(即反碼)。

9 (base 10) = 00000000000000000000000000001001 (base 2)   
         
~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)

因?yàn)樵谟?jì)算機(jī)中第一位代表著 符號(hào)位置。

同時(shí)簡(jiǎn)單理解。對(duì)任一數(shù)值 x 進(jìn)行按位非操作的結(jié)果為 -(x + 1)。
也就是說(shuō)通過(guò) ~ 可以把 -1(且僅僅只是 -1) 變?yōu)?falsy。

var str = "study pwa";
var searchFor = "a";

// 這是 if (str.indexOf("a") > -1) 或者 if ( -1 * str.indexOf("a") <= 0) 條件判斷的另一種方法
if (~str.indexOf(searchFor)) {
  // searchFor 包含在字符串 str 中
} else {
  // searchFor 不包含在字符串 str 中
}
惰性函數(shù)

沒(méi)學(xué)習(xí)惰性函數(shù)時(shí)候,如果創(chuàng)建 xhr,每次都需要判斷。

function createXHR(){
  var xmlhttp;
  try{
    //firfox,opear,safari
    xmlHttp=new XMLHttpRequest();
  } catch(e) {
    try{
      xmlHttp=new ActiveXobject("Msxm12.XMLHTTP");
    } catch(e) {
      try{
        xmlHttp=new ActiveXobject("Microsoft.XMLHTTP")
      } catch(e) {
        alert("您的瀏覽器不支持AJAX")
        return false;
      }
    }
  }
  return xmlHttp;
}

在學(xué)習(xí)完了惰性函數(shù)之后

function createXHR(){
  // 定義xhr,
  var xhr = null;
  if (typeof XMLHttpRequest!="undefined") {
    xhr=new XMLHttpRequest();
    createXHR=function(){
      return new XMLHttpRequest();  //直接返回一個(gè)懶函數(shù)
    }
  } else {
    try{
      xhr=new ActiveXObject("Msxml2.XMLHTTP");
      createXHR=function(){
        return new ActiveXObject("Msxml2.XMLHTTP");
      }
    } catch(e) {
      try{
        xhr =new ActiveXObject("Microsoft.XMLHTTP");
        createXHR=function(){
          return new ActiveXObject("Microsoft.XMLHTTP");
        }
      } catch(e) {
        createXHR=function(){
          return null
        }
      }        
    }
  }
  // 第一次調(diào)用也需要 返回 xhr 對(duì)象,所以需要返回 xhr
  return xhr;
}

如果代碼被使用于兩次調(diào)用以上則會(huì)有一定的性能優(yōu)化。第一次調(diào)用時(shí)候 把 xhr 賦值并返回,且在進(jìn)入層層 if 判斷中把 createXHR 這個(gè)函數(shù)賦值為其他函數(shù)。

 // 如果瀏覽器中有 XMLHttpRequest 對(duì)象在第二次調(diào)用時(shí)候
  createXHR=function(){
    return XMLHttpRequest();  //直接返回一個(gè)懶函數(shù)
  }

該方案可以在不需要第二個(gè)變量的情況下直接對(duì)函數(shù)調(diào)用進(jìn)行優(yōu)化。同時(shí)對(duì)于調(diào)用方也是透明的,不需要修改任何代碼。

擴(kuò)展運(yùn)算符號(hào)的另類用法

在最近的學(xué)習(xí)中,我看到了一篇關(guān)于 ... (擴(kuò)展運(yùn)算符)的另類用法,The shortest way to conditional insert properties into an object literal, 這篇文章介紹了如何最簡(jiǎn)化的寫出條件性插入對(duì)象屬性。

在沒(méi)有看過(guò)這篇文章時(shí)會(huì)寫出如下代碼:

// 獲得手機(jī)號(hào)
const phone = this.state.phone

const person = {
  name: "gogo",
  age: 11
}

// 如果手機(jī)號(hào)不為空,則添加到person中
if (phone) {
  person.phone = phone
}

但是,看完該文章之后可以寫出這樣的代碼

// 獲得手機(jī)號(hào)
const phone = this.state.phone

const person = {
  name: "gogo",
  age: 11,
  ...phone && {phone}
}

上面的代碼與該代碼功能相同,但是代碼量卻減少很多。

要理解上述代碼的運(yùn)行原理,首先先介紹一下 ... 運(yùn)算符,
對(duì)象的擴(kuò)展運(yùn)算符(...)用于取出參數(shù)對(duì)象的所有可遍歷屬性,拷貝到當(dāng)前對(duì)象之中。

let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }

// 如果是 空對(duì)象,沒(méi)有任何效果
{...{}, a: 1}
// { a: 1 }

// 如果擴(kuò)展運(yùn)算符后面不是對(duì)象,則會(huì)自動(dòng)將其轉(zhuǎn)為對(duì)象。但是如果對(duì)象沒(méi)有屬性,就會(huì)返回空對(duì)象
// {...1} 會(huì)變?yōu)?{...Object(1)} 但是因?yàn)闆](méi)有屬性
{...1} 
// {}

// 同理得到
{...undefined} {...null} {...true}
// 都會(huì)變?yōu)?{}

可以參考 阮一峰的 es6入門的對(duì)象的擴(kuò)展運(yùn)算符

原理是因?yàn)榇a可以如下理解:

const obj = {
  ...(phone && {phone})
}

// 如果 phone 有數(shù)據(jù),&& 執(zhí)行則會(huì)變?yōu)?const obj = {
  ...{phone}
}
// 而對(duì)象擴(kuò)展運(yùn)算符 執(zhí)行就會(huì)變?yōu)?const obj = {
  phone
}

但是 如果 phone 為空字符串或者其他 falsy 數(shù)據(jù),則代碼會(huì)直接短路
const obj = {
  ...false
  ...null
  ...0
  ...undefined
}
則不會(huì)添加任何屬性進(jìn)入對(duì)象
討論與思考

關(guān)于 ~ 操作符 + indexOf 其實(shí)加深了對(duì)位運(yùn)算與比特位的理解。但是在es6之后我們完全可以使用 includes。完全可以不再使用~indexOf。

對(duì)于惰性函數(shù),在typescript中,該代碼是不可以使用的。當(dāng)然,我們可以通過(guò)函數(shù)變量以及增加代碼實(shí)現(xiàn)上述功能。

function createXHR(){}
// 修改為
let createXHR = function() {
  // ...
}

這里也可以看出 ts 不認(rèn)可函數(shù)聲明的函數(shù)名是一個(gè)變量。

對(duì)于擴(kuò)展運(yùn)算符的特殊用法。關(guān)于 typescript 使用,上述代碼是可以在ts中使用的,不過(guò)不可以使用 &&,要使用 三元運(yùn)算符

{
   ...phone ? {phone} : {}
}

但是不建議在ts中使用,因?yàn)樵摯a不會(huì)被代碼ts檢測(cè)到。

const phone = "123"

// 定義接口
interface Person {
  name: string;
}

// 不會(huì)爆出 error
const person: Person = {
  name: "ccc",
  ...phone ? {phone} : {}
}

該代碼是與 ts 嚴(yán)重相悖的,ts首要就是類型定義,而使用該代碼逃出了 ts 的類型定義,這個(gè)對(duì)于語(yǔ)言上以及工程維護(hù)上是無(wú)法接受的。
同樣的代碼,我認(rèn)為 js 是可以接受的(但是未必要在工程中使用),但是 ts 確實(shí)無(wú)法接受的,這也是不同的語(yǔ)言之間的差異性。

在關(guān)于這片文章的評(píng)論中,最大的論點(diǎn)在于 為什么要使用最簡(jiǎn)的代碼,最好的代碼應(yīng)該是不言自明的。

而作者也相對(duì)而言探討了自己的一些看法,應(yīng)該學(xué)習(xí)一些自己不理解的東西。同時(shí)如果一個(gè)東西能夠解釋來(lái)龍去脈,完全可以從原理性解釋,那么值得學(xué)習(xí)與使用。同時(shí)我個(gè)人其實(shí)是和作者持著相同意見的。

總結(jié)

js 是一門靈活的語(yǔ)言(手動(dòng)滑稽)。

應(yīng)該多學(xué)習(xí)一些奇技淫巧,因?yàn)楹芏嗥婕家赏硪恍┗旌系闹R(shí),往往會(huì)有一些新奇的思考與體驗(yàn)(怎么我想不出來(lái)?)同時(shí),在別人使用了奇技淫巧時(shí)候我可以迅速理解。

在項(xiàng)目中是否使用此類代碼要取決團(tuán)隊(duì)類型,以及項(xiàng)目體系,并非個(gè)人喜惡。

鼓勵(lì)一下

如果你覺得這篇文章不錯(cuò),希望可以給與我一些鼓勵(lì),在我的 github 博客下幫忙 star 一下。
博客地址

參考資料

The shortest way to conditional insert properties into an object literal

對(duì)象的擴(kuò)展運(yùn)算符

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/104422.html

相關(guān)文章

  • 數(shù)據(jù)庫(kù)

    摘要:編輯大咖說(shuō)閱讀字?jǐn)?shù)用時(shí)分鐘內(nèi)容摘要對(duì)于真正企業(yè)級(jí)應(yīng)用,需要分布式數(shù)據(jù)庫(kù)具備什么樣的能力相比等分布式數(shù)據(jù)庫(kù),他們條最佳性能優(yōu)化性能優(yōu)化索引與優(yōu)化關(guān)于索引與優(yōu)化的基礎(chǔ)知識(shí)匯總。 mysql 數(shù)據(jù)庫(kù)開發(fā)常見問(wèn)題及優(yōu)化 這篇文章從庫(kù)表設(shè)計(jì),慢 SQL 問(wèn)題和誤操作、程序 bug 時(shí)怎么辦這三個(gè)問(wèn)題展開。 一個(gè)小時(shí)學(xué)會(huì) MySQL 數(shù)據(jù)庫(kù) 看到了一篇適合新手的 MySQL 入門教程,希望對(duì)想學(xué) ...

    mengbo 評(píng)論0 收藏0
  • 數(shù)據(jù)庫(kù)

    摘要:編輯大咖說(shuō)閱讀字?jǐn)?shù)用時(shí)分鐘內(nèi)容摘要對(duì)于真正企業(yè)級(jí)應(yīng)用,需要分布式數(shù)據(jù)庫(kù)具備什么樣的能力相比等分布式數(shù)據(jù)庫(kù),他們條最佳性能優(yōu)化性能優(yōu)化索引與優(yōu)化關(guān)于索引與優(yōu)化的基礎(chǔ)知識(shí)匯總。 mysql 數(shù)據(jù)庫(kù)開發(fā)常見問(wèn)題及優(yōu)化 這篇文章從庫(kù)表設(shè)計(jì),慢 SQL 問(wèn)題和誤操作、程序 bug 時(shí)怎么辦這三個(gè)問(wèn)題展開。 一個(gè)小時(shí)學(xué)會(huì) MySQL 數(shù)據(jù)庫(kù) 看到了一篇適合新手的 MySQL 入門教程,希望對(duì)想學(xué) ...

    shuibo 評(píng)論0 收藏0
  • CSS開發(fā)

    摘要:譯十六進(jìn)制顏色揭秘原文地址原文作者譯文出自掘金翻譯計(jì)劃本文永久鏈接教程入門篇關(guān)于是一款進(jìn)行柵格布局的輔助工具,它讓開發(fā)者擺脫了冗雜的數(shù)學(xué)計(jì)算,同時(shí)降低了樣式與結(jié)構(gòu)的耦合程度。 【譯】CSS 十六進(jìn)制顏色揭秘 原文地址:CSS Hex Colors Demystified 原文作者:Dave Gash 譯文出自:掘金翻譯計(jì)劃 本文永久鏈接:https://github.com/xitu/...

    warkiz 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<