摘要:目前前端主要有以下四種方法會觸發(fā)對應(yīng)的回調(diào)方法方法客戶端回調(diào)客戶端回調(diào)參考地址每日一瞥是團(tuán)隊(duì)內(nèi)部日常業(yè)界動態(tài)提煉,發(fā)布時效可能略有延后。
「ES2015 - ES2018」Rest / Spread Properties 梳理
Three.js 概念梳理
火狐 Nightly 支持 CSS Grids 動畫
換個姿勢起 Node.js 工程
WebView & JS Bridge 筆記
「ES2015 - ES2018」Rest / Spread Properties 梳理第 9 版 ECMAScript 標(biāo)準(zhǔn),官方稱為 ECMAScript 2018(或簡稱 ES2018),已于 2018 年 6 月發(fā)布。從 ES2016 開始,ECMAScript 規(guī)范每年都會發(fā)布新版本,但添加的功能少于以前的主版本。最新版本發(fā)布了 4 個新的 RegExp、Rest / Spread 屬性、Asynchronous Iteration、Promise.prototype.finally。此外,ES2018 從標(biāo)記模板中刪除了轉(zhuǎn)義序列的語法限制。
這里我們對 Rest / Spread Properties 進(jìn)行梳理。
Spread在 ES2015 中一個非常有趣的特性就是 spread operator(擴(kuò)展操作符)。這一操作符是的復(fù)制和合并數(shù)組變得更為簡潔。我們不再需要使用 concat() 方法或 slice() 方法,一個 ... 操作符已經(jīng)足夠:
const arr1 = [10, 20, 30]; // make a copy of arr1 const copy = [...arr1]; console.log(copy); // → [10, 20, 30] const arr2 = [40, 50]; // merge arr2 with arr1 const merge = [...arr1, ...arr2]; console.log(merge); // → [10, 20, 30, 40, 50]
不僅如此,我們還可以將數(shù)組作為一個需要多帶帶一個個傳入?yún)?shù)的函數(shù)的參數(shù)傳入,這么說可能有點(diǎn)繞,看個例子就懂了:
const arr = [10, 20, 30] // equivalent to // console.log(Math.max(10, 20, 30)); console.log(Math.max(...arr)); // → 30
在 ES2018 中,這一語法糖進(jìn)一步擴(kuò)展,對于對象屬性展開復(fù)制的場景也可以發(fā)揮作用。事實(shí)上這一特性從比較早的時候,我們就開始應(yīng)用在了項(xiàng)目中:
const obj1 = { a: 10, b: 20 }; const obj2 = { ...obj1, c: 30 }; console.log(obj2); // → {a: 10, b: 20, c: 30}
在上面的代碼中,... 操作符用于獲取 obj1 的屬性,并賦值給 obj2。在 ES2018 之前,這么做是會拋出異常的。如果存在若干相同 key 的屬性,會選擇后賦值或生成的屬性:
const obj1 = { a: 10, b: 20 }; const obj2 = { ...obj1, a: 30 }; console.log(obj2); // → {a: 30, b: 20}
當(dāng)然,我們還可以使用擴(kuò)展屬性來合并兩個甚至更多對象,當(dāng)然我們也可用通過 Object.assign() 來實(shí)現(xiàn):
const obj1 = {a: 10}; const obj2 = {b: 20}; const obj3 = {c: 30}; // ES2018 console.log({...obj1, ...obj2, ...obj3}); // → {a: 10, b: 20, c: 30} // ES2015 console.log(Object.assign({}, obj1, obj2, obj3)); // → {a: 10, b: 20, c: 30}
不過有意思的是,擴(kuò)展屬性并不總能生成與 Object.assign() 相同的結(jié)果,我們看下下面的場景:
Object.defineProperty(Object.prototype, "a", { set(value) { console.log("set called!"); } }); const obj = {a: 10}; console.log({...obj}); // → {a: 10} console.log(Object.assign({}, obj)); // → set called! // → {}
Object.assign() 會執(zhí)行集成的 setter 屬性,而擴(kuò)展運(yùn)算會忽略 setter。
值得注意的是,擴(kuò)展屬性只會復(fù)制可枚舉屬性。下面的例子中,type屬性不會出現(xiàn)在復(fù)制的對象中,因?yàn)樗?enumerable 屬性被置為 false。
const car = { color: "blue" }; Object.defineProperty(car, "type", { value: "coupe", enumerable: false }); console.log({...car}); // → {color: "blue"}
當(dāng)然,即使是 enumerable 的屬性,繼承過來的仍然會被忽略:
const car = { color: "blue" }; const car2 = Object.create(car, { type: { value: "coupe", enumerable: true, } }); console.log(car2.color); // → blue console.log(car2.hasOwnProperty("color")); // → false console.log(car2.type); // → coupe console.log(car2.hasOwnProperty("type")); // → true console.log({...car2}); // → {type: "coupe"}
上面的代碼中,car2 從 car1 繼承了 color 屬性。因?yàn)閿U(kuò)展運(yùn)算只復(fù)制對象本身的屬性,color 就不含在返回的值中了。
要記住的一點(diǎn)是,擴(kuò)展運(yùn)算做的是對象的淺拷貝。如果一個屬性本身也是對象,那么擴(kuò)展運(yùn)算只會復(fù)制這個對象的引用:
const obj = {x: {y: 10}}; const copy1 = {...obj}; const copy2 = {...obj}; console.log(copy1.x === copy2.x); // → true
copy1 中的 x 屬性與 copy2 的 x 屬性在內(nèi)存中引用的是相同的對象,因此「嚴(yán)格等于」運(yùn)算符返回的是 true。
RestES2015 中引入的另一個有用的特性是 rest parameters,它可以使得我們使用 ... 來把一些值作為數(shù)組返回。舉個例子就明白了:
const arr = [10, 20, 30]; const [x, ...rest] = arr; console.log(x); // → 10 console.log(rest); // → [20, 30]
這里,arr 的第一個項(xiàng)賦值給了 x,而剩下的項(xiàng)被復(fù)制給了 rest。這個模式我們稱之為 array destructuring,中文翻譯為「數(shù)組解構(gòu)」,這個模式在 Ecma 技術(shù)委員會決定將其帶到對象中后變得非常的流行:
const obj = { a: 10, b: 20, c: 30 }; const {a, ...rest} = obj; console.log(a); // → 10 console.log(rest); // → {b: 20, c: 30}
在這段代碼中,通過結(jié)構(gòu)的方式,我們復(fù)制了可枚舉屬性并復(fù)制到新的對象中。注意,rest 屬性總是出現(xiàn)在對象的最后,否則就會拋出異常:
const obj = { a: 10, b: 20, c: 30 }; const {...rest, a} = obj; // → SyntaxError: Rest element must be last element
同樣需要注意的是,如果在同一個對象中使用多個 rest,也會導(dǎo)致錯誤,除非這些 rest 是嵌套的形式:
const obj = { a: 10, b: { x: 20, y: 30, z: 40 } }; const {b: {x, ...rest1}, ...rest2} = obj; // no error const {...rest, ...rest2} = obj; // → SyntaxError: Rest element must be last element兼容性
Chrome | Firefox | Safari | Edge |
---|---|---|---|
60 | 55 | 11.1 | No |
Chrome Android | Firefox Android | iOS Safari | Edge Mobile | Samsung Internet | Android Webview |
---|---|---|---|---|---|
60 | 55 | 11.3 | No | 8.2 | 60 |
對應(yīng) Node.js,兼容性如下:
8.0.0 (需要 --harmony 運(yùn)行時 flag)
8.3.0 (完全支持)
源地址:https://css-tricks.com/new-es...
Three.js 概念梳理Three.js 是一款運(yùn)行在瀏覽器中的 3D 引擎,我們可以用它創(chuàng)建各種三維場景。今天我們來對這一塊進(jìn)行一些初步的學(xué)習(xí)和梳理。
兼容性Three.js 基于 WebGL 進(jìn)行封裝,因此其兼容性由 WebGL 在不同瀏覽器的兼容性決定。其中,WebGL 的兼容性如下:
可以看出,WebGL 的兼容性還是不錯的。
然而 WebGL 2 的兼容性就不那么好了,
可以看到,Safari 對 WebGL 2 的支持還不是很好,而知名的 TensorFlow.js 的瀏覽器版本就是基于 WebGL 2,因此 TensorFlow.js 在 Safari 上就有些無力了。
小工具在了解的過程中發(fā)現(xiàn)了一個不錯的工具,可以查看當(dāng)前瀏覽器對 WebGL 1.0/2.0 的支持情況。
概念點(diǎn)和關(guān)系梳理 火狐 Nightly 支持 CSS Grids 動畫在火狐瀏覽器 Nightly (66) 版本中,CSS Grids 的軌跡可以動畫化了,可以看看視頻,效果很酷炫。
這一效果用 CSS 動畫以及 grid-template-columns 和 grid-template-rows 即可實(shí)現(xiàn),具體 Demo 可見這里。
源地址:https://twitter.com/jensimmon...
換個姿勢起 Node.js 工程 通常起 Node.js 項(xiàng)目的姿勢通常我們會使用 npm 來起一個新的 Node.js 工程:
$ npm init
npm 接下來會問一系列的問題,并根據(jù)我們的回答來生成 package.json。然后呢?我們不可避免的從 Github 上的一些倉庫里 copy & paste 一個 .gitignore 模板來用。當(dāng)然如果我們玩的是開源項(xiàng)目,還得記得附上一些 LICENSE 文件來聲明我們使用的協(xié)議。
但這樣也太沒效率了!如果每次都這么搞一遍,真的能忍?
更有效率的方式這周我在推上看到這么一條:
這四條指令足以把我手動做的這些事都做掉,而且還不止,然后我們就能夠成功的創(chuàng)建起一個工程了。下面我們逐條解釋下這四條的作用:
npx license mit 會使用 license 包來下載該協(xié)議對應(yīng)的選項(xiàng),這里的例子是指 MIT 協(xié)議。
npx gitignore node 使用 gitignore 包來從 GitHub 倉庫自動下載對應(yīng)的 .gitignore 文件。
npx covgen 使用 covgen 包來生成 Contributor Covenant(參與者公約)。
npm init -y 會自動選擇 npm init 詢問的那些問題的默認(rèn)選項(xiàng)。
自定義 npm init是的,npm 支持一些自定義配置。我們可以通過在命令行輸入 npm config list 來看下 npm 的配置。當(dāng)然如果只想看與 npm init 相關(guān)的配置項(xiàng),可以搭配使用 grep:
npm config list | grep init
我可以設(shè)置許多默認(rèn)配置:作者姓名、作者電子郵件、作者 URL、許可證和版本。如果要設(shè)置它們,我們可以在命令行中輸入下面對應(yīng)語句,或者使用 npm config edit 在文本編輯器中打開配置文件。使用命令行很簡單,你可以設(shè)置所有五個默認(rèn)值:
npm set init.author.name "Your name" npm set init.author.email "[email protected]" npm set init.author.url "https://your-url.com" npm set init.license "MIT" npm set init.version "1.0.0"
當(dāng)你已經(jīng)做好自定義配置后,npm init -y 就會直接生成你想要的配置了。
最后這樣你就可以換個姿勢來開啟一個 Node 工程啦!
源地址:https://philna.sh/blog/2019/0...
WebView & JS Bridge 筆記這一篇是總結(jié)了一些文檔和博客的筆記。
什么是 WebView對于這個問題,我們可以谷歌一下,去開發(fā)者官方文檔看看文檔是怎么說的:
總結(jié)下來就一句話:WebView 就是個用于展示頁面的 View??梢钥吹?android.webkit.WebView 繼承自 android.view.View,只要接觸過一些 native 的東西,大致就知道它是類似 div 一樣的東西。View 本身是 widget 的基類,而 widget 就是用來創(chuàng)建交互 UI 的組件(如按鈕、文字域之類)。
那么 WebView 可以做什么呢?
首先,WebView 只可以讓你在 app 的界面上展示網(wǎng)頁內(nèi)容,但不具備通常瀏覽器的完整功能,如導(dǎo)航控制、地址欄等。當(dāng)然,WebView 使得開發(fā)者可以將 web 頁面嵌到 app 上,在一些場景下是一種不錯的模式。
其次,你可以通過一些 native 技術(shù)來為 WebView 提供一些 bridge,從而獲得一些原生能力,這也就是我們通常所說的 js bridge。但是現(xiàn)實(shí)總是殘酷的,我們可以看下這一段:
國產(chǎn)手機(jī)的廠商基本在出廠時都自帶了瀏覽器,查看系統(tǒng)應(yīng)用時,發(fā)現(xiàn)并沒有內(nèi)置 com.android.webview 或者com.google.android.webview 包,這些瀏覽器并不是簡單地套了一層 WebView 的殼,而是直接使用了 Chromium 內(nèi)核,至于有沒有魔改過內(nèi)核源碼,不得而知。國產(chǎn)出品的瀏覽器,如 360 瀏覽器、QQ 瀏覽器、UC 瀏覽器,幾乎都魔改了內(nèi)核。值得一提的是,騰訊出品的 X5 內(nèi)核,號稱頁面渲染流暢度高于原生內(nèi)核,客戶端減少了 WebView 帶來坑的同時,增加了前端適配的難度,功能實(shí)現(xiàn)上需要有更多地考慮。JS Bridge 基本原理
JS Bridge 是為了支持 JavaScript 與 native 相互通信的模塊(庫/組件),有了 JS Bridge 我們就能夠在 WebView 里使用一些 native 提供的能力。
JavaScript 調(diào)用 native 的方式大致可以有三類:注入映射、攔截 schema、攔截方法。
下面以安卓為例來解釋下兩種思路:
注入映射類的方式:
//定義好 Java 接口對象 public class SDK extends Object { @JavascriptInterface public void hello(String msg) { System.out.println("Hello World"); } } //Webview 中調(diào)用 WebView webview = (WebView) findViewById(R.id.webview); webview.addJavascriptInterface(new SDK(), "sdk"); webview.loadUrl("http://imnerd.org"); //注入后加載頁面
可以看到 addJavascriptInterface 方法定義了映射,我們就可以通過 sdk.hello() 來執(zhí)行 native 方法了。不過這個方法存在安全問題,這里僅作演示。
作為對比,我們看看 iOS 的,意思是差不多的:
- (void)webViewDidFinishLoad:(UIWebView *)webView { self.jsContext = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; self.jsContext[@"hello"] = ^() { NSLog(@"Hello World"); }; }
攔截 schema 的方式:
這一種方式我們很容易理解,我們可以約定 url 的 schema,當(dāng)發(fā)生 url 跳轉(zhuǎn)時,如果符合約定的 schema,就交給客戶端來攔截相應(yīng)操作。
攔截方法的方式
JS 的一些方法執(zhí)行時會觸發(fā)客戶端中的一些回調(diào),因此可以通過對前端參數(shù)進(jìn)行識別來執(zhí)行對應(yīng)的客戶端代碼。目前前端主要有以下四種方法會觸發(fā)對應(yīng)的回調(diào)方法:
JS 方法 | Android 客戶端回調(diào) | iOS 客戶端回調(diào) |
---|---|---|
alert | onJsAlert | runJavaScriptAlertPanelWithMessage |
prompt | onJsPrompt | runJavaScriptTextInputPanelWithPrompt |
confirm | onJsConfirm | runJavaScriptConfirmPanelWithMessage |
參考地址:
https://developer.android.com...
https://juejin.im/post/5a94f9...
https://juejin.im/post/5abca8...
https://75team.com/post/andro...
「每日一瞥」是團(tuán)隊(duì)內(nèi)部日常業(yè)界動態(tài)提煉,發(fā)布時效可能略有延后。文章可隨意轉(zhuǎn)載,但請保留此 原文鏈接。
非常歡迎有激情的你加入 ES2049 Studio,簡歷請發(fā)送至 caijun.hcj(at)alibaba-inc.com 。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/101313.html
摘要:當(dāng)引擎開始執(zhí)行腳本是的時候,會先創(chuàng)建一個全局執(zhí)行上下文,并將其到當(dāng)前執(zhí)行棧,無論何時一個函數(shù)被調(diào)用,就會創(chuàng)建一個新的函數(shù)執(zhí)行上下文并壓入棧中。當(dāng)函數(shù)執(zhí)行完畢,執(zhí)行棧會將其彈出,并把控制權(quán)交給當(dāng)前棧的下一個上下文。 showImg(https://segmentfault.com/img/remote/1460000017516912?w=1200&h=630); 從過去直到 Reac...
showImg(https://segmentfault.com/img/remote/1460000018793640?w=900&h=500); 簡介 安全、注入攻擊、XSS 13歲女學(xué)生被捕:因發(fā)布 JavaScript 無限循環(huán)代碼。 這條新聞是來自 2019年3月10日 很多同學(xué)匆匆一瞥便滑動屏幕去看下一條消息了,并沒有去了解這段代碼是什么,怎么辦才能防止這個問題。事情發(fā)生后為了抗議日本...
摘要:配置在設(shè)置項(xiàng)中確認(rèn)包含增加設(shè)置項(xiàng),值為一個字符串路徑,必須以結(jié)尾在模板中這樣引用在的目錄存放靜態(tài)文件開發(fā)期間使用極度低效時有別的做法注意默認(rèn)為,一個列表,表示獨(dú)立于的靜態(tài)文件存放位置。 配置 1.在INSTALLED_APPS設(shè)置項(xiàng)中確認(rèn)包含django.contrib.staticfiles 2.增加STATIC_URL設(shè)置項(xiàng),值為一個字符串(路徑),必須以‘/’結(jié)尾 3.在模板中...
閱讀 2797·2021-11-24 09:39
閱讀 2558·2021-11-23 09:51
閱讀 1871·2021-11-17 09:33
閱讀 1752·2021-10-22 09:54
閱讀 1884·2021-08-16 11:00
閱讀 3436·2019-08-30 15:53
閱讀 1743·2019-08-30 13:19
閱讀 2915·2019-08-30 12:49