摘要:快速排序由在年提出。如果定時(shí)器的時(shí)間到了,那么也會(huì)去下一個(gè)階段關(guān)閉的回調(diào)函數(shù),一些準(zhǔn)備關(guān)閉的函數(shù)等的事件輪詢機(jī)制也可以看成是單線程,由上往下執(zhí)行,但是到了第階段,又會(huì)返回第一階段,死循環(huán)。
原生javaScript是中大公司挑人的核心,也是決定你未來(lái)發(fā)展高度的核心。
冒泡排序,快速排序,深度克隆,深度凍結(jié),數(shù)組操作,本章都有。
走遍大江南北,還是原生javaScript最美
感冒給大家更新,希望大家多多點(diǎn)贊,謝謝!
下面是本人一些其他文章和學(xué)習(xí)的文檔 , 全棧工程師一起加油!
Node.js之快速搭建微信公眾號(hào)服務(wù)器
Node.js之快速搭建服務(wù)器+前后端數(shù)據(jù)庫(kù)session交互
ES6教程全篇
你該擁抱的TypeScript
快速排序算法"這應(yīng)該是最簡(jiǎn)單的快速排序?qū)崿F(xiàn),什么是快速排序呢?" "快速排序(Quicksort)是對(duì)冒泡排序的一種改進(jìn)。 快速排序由C. A. R. Hoare在1962年提出。它的基本思想是: 通過一趟排序?qū)⒁判虻臄?shù)據(jù)分割成獨(dú)立的兩部分,其中一 部分的所有數(shù)據(jù)都比另外一部分的所有數(shù)據(jù)都要小,然后再 按此方法對(duì)這兩部分?jǐn)?shù)據(jù)分別進(jìn)行快速排序,整個(gè)排序過程 可以遞歸進(jìn)行,以此達(dá)到整個(gè)數(shù)據(jù)變成有序序列。" function quickSort(arr) { if (arr.length <= 1) { return arr; } var left = [], right = [], baseDot = Math.round(arr.length / 2) base = arr.splice(baseDot, 1)[0]; for (var i = 0; i < arr.length; i++) { if (arr[i] < base) { left.push(arr[i]) } else { right.push(arr[i]) } } return quickSort(left).concat([base], quickSort(right)); } let arr = [5, 3, 4, 12]; const newarr = quickSort(arr); console.log(newarr); "每次遞歸調(diào)用,都會(huì)直到數(shù)組中只有一個(gè)數(shù)字為止,然后 執(zhí)行上下文棧出棧,返回上一個(gè)執(zhí)行上下文循環(huán)遞歸,拼接數(shù)組"冒泡排序算法
"什么是冒泡排序算法?" "冒泡排序(Bubble Sort),是一種計(jì)算機(jī)科學(xué)領(lǐng)域的較簡(jiǎn)單的排序算法。 它重復(fù)地走訪過要排序的元素列,依次比較兩個(gè)相鄰的元素,如果他們的順 序(如從大到小、首字母從A到Z)錯(cuò)誤就把他們交換過來(lái)。走訪元素的工作 是重復(fù)地進(jìn)行直到?jīng)]有相鄰元素需要交換,也就是說該元素已經(jīng)排序完成。 這個(gè)算法的名字由來(lái)是因?yàn)樵酱蟮脑貢?huì)經(jīng)由交換慢慢“浮”到數(shù)列的頂端 (升序或降序排列),就如同碳酸飲料中二氧化碳的氣泡最終會(huì)上浮到頂端 一樣,故名“冒泡排序”。" bubbleSortSoul1 = (arr = []) => { let count = 0; // i為輪數(shù)(因i從0開始 即i深度克隆arr[j]? 如果有這種特殊癖好 那么j就從1開始吧,然后j arr[j + 1]) { let temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } console.log(`bubbleSortSoul1排序完成用了${count}輪`); return arr; }
"為什么我們需要深度克隆?而且面試必問?"
"因?yàn)橐脭?shù)據(jù)類型存儲(chǔ)在堆空間中,當(dāng)兩個(gè)變量同時(shí)指向同一個(gè)地址時(shí), 只要一個(gè)改變,那么另外一個(gè)也會(huì)跟著變,我們的原意是想一個(gè)改變,另 一個(gè)不變,那么就需要重新開拓一個(gè)堆空間出來(lái),所以就有了深度克隆。" "第一種方法(只適用于基礎(chǔ)類型)" const newObj = JSON.parse(JSON.stringify(oldObj)); "第二種方法,涵蓋所有的類型" const getType = (obj)=> { var toString = Object.prototype.toString; var map = { "[object Boolean]" : "boolean", "[object Number]" : "number", "[object String]" : "string", "[object Function]" : "function", "[object Array]" : "array", "[object Date]" : "date", "[object RegExp]" : "regExp", "[object Undefined]": "undefined", "[object Null]" : "null", "[object Object]" : "object", "[object Symbol]" : "symbol" }; if(obj instanceof Element) {//因?yàn)閷?duì)不同標(biāo)簽,toString會(huì)返回對(duì)應(yīng)不同標(biāo)簽的構(gòu)造函數(shù) return "element"; } return map[toString.call(obj)]; } const getRegExp = re => { var flags = ""; if (re.global) flags += "g"; if (re.ignoreCase) flags += "i"; if (re.multiline) flags += "m"; return flags; }; /** * deep clone * @param {[type]} parent object 需要進(jìn)行克隆的對(duì)象 * @return {[type]} 深克隆后的對(duì)象 */ const deepClone = oldObj => { // 維護(hù)兩個(gè)儲(chǔ)存循環(huán)引用的數(shù)組 const oldObjArr = []; const newObjArr = []; const clone = oldObj => { let newObj, proto; const type = getType(oldObj); switch(type){ case "boolean": case "number": case "string": case "null": case "undefined": case "function":{ return oldObj; break; } case "symbol":{ return Symbol(Symbol.keyFor(oldObj).toString()); break; } case "array":{ newObj = []; break; } case "regExp":{ newObj = new RegExp(oldObj.source, getRegExp(oldObj)); if (oldObj.lastIndex) newObj.lastIndex = oldObj.lastIndex; break; } case "date":{ newObj = new Date(oldObj.getTime()); break; } //case "obj": default:{ // 處理對(duì)象原型 proto = Object.getPrototypeOf(oldObj); // 利用Object.create切斷原型鏈 newObj = Object.create(proto); break; } } // 處理循環(huán)引用 const index = oldObjArr.indexOf(oldObj); if (index != -1) {// 如果父數(shù)組存在本對(duì)象,說明之前已經(jīng)被引用過,直接返回此對(duì)象 return newObjArr[index]; } oldObjArr.push(oldObj); newObjArr.push(newObj); /*數(shù)組和對(duì)象都可以用forin語(yǔ)句,雖然數(shù)組使用forin會(huì)有一個(gè)問題(具體看最下面)。 但是這里不會(huì)影響,所以這么用 */ for (let i in oldObj) {// 遞歸 newObj[i] = clone(oldObj[i]); } return newObj; }; return clone(oldObj); } /* 測(cè)試成功 */ function person(pname) { this.name = pname; } const Messi = new person("Messi"); function say() { console.log("hi"); }; const oldObj = { a: say, b: new Array(1), c: new RegExp("ab+c", "i"), d: Messi }; const newObj = deepClone(oldObj); console.log(newObj.a, oldObj.a); //[Function: say] [Function: say] console.log(newObj.b[0], oldObj.b[0]); // undefined undefined console.log(newObj.c, oldObj.c); // /ab+c/i /ab+c/i console.log(newObj.d.constructor, oldObj.d.constructor); // [Function: person][Function: person] "所有的類型都可以被克隆,完美版"
判斷對(duì)象是否一個(gè)數(shù)組的條件是:
Array.isArray(),這個(gè)在安卓的瀏覽器中兼容性一般
arr instanceof Array 這個(gè)兼容性不錯(cuò),可以使用
還有就是arr. _proto_ .consturctor == Array 這個(gè)也是可以的 兼容性應(yīng)該還不錯(cuò)
Object.prototype.tostring.call(arr) == [object Array] 這個(gè)也可以
如何提取用最原生的方法提取一個(gè)對(duì)象內(nèi)部所有屬性的值,并且放在不同數(shù)組中?個(gè)人認(rèn)為第一題和第二題結(jié)合起來(lái),可以用來(lái)處理前后臺(tái)交互的數(shù)據(jù),如果格式很復(fù)雜,也可以使用這兩者的模式結(jié)合,然后把他們分別提取出來(lái)進(jìn)行操作。
const obj = { name: "json", age: 1, friend: "夢(mèng)露", info: { name: "Aron", age: 2, friend: "杰西卡", info: { name: "rose", age: 3, friend: "霉霉", info: { name: "jerry", age: 4, friend: "比伯", info: { name: "damu", age: 5, friend: "XJ", }, }, }, } } let namearr, agearr, friendarr; namearr = []; agearr = []; friendarr = []; check(obj); function check(obj) { const items = Object.getOwnPropertyNames(obj) items.forEach(function (item) { if (Object.prototype.toString.call(obj[item]) == "[object Object]") { check(obj[item]); } else { if (item.toString() === "name") { namearr.push(obj[item]) } else if (item.toString() === "age") { agearr.push(obj[item]) } else if (item.toString() === "friend") { friendarr.push(obj[item]) } } }) } /* 這種方法也是一樣的效果 使用for in循環(huán)代替的Object.getOwnPropertyNames(obj)方法 function check(obj) { for (var item in obj) { if (Object.prototype.toString.call(obj[item]) == "[object Object]") { check(obj[item]); } else { if (item == "name") { namearr.push(obj[item]) } else if (item == "age") { agearr.push(obj[item]) } else if (item == "friend") { friendarr.push(obj[item]) } } } }*/ console.log(`namearr:${namearr}`) console.log(`agearr:${agearr}`) console.log(`friendarr:${friendarr}`)請(qǐng)手寫一個(gè)數(shù)組由小到大排序而且去重,不得使用高階函數(shù)
let arr = [1, 1, 2, 2, 5, 5, "a", "a", "3", "3"] arr = arr.sort(); let realarr = []; for (let i = 0; i < arr.length; i++) { if (i == 0) { realarr.push(arr[i]) } else if (i !== 0 && arr[i] !== arr[i - 1]) { realarr.push(arr[i]) } } console.log(realarr)
### 如何將一個(gè)對(duì)象深度凍結(jié)?
跟上面的數(shù)組面試題一樣,利用了執(zhí)行上下文棧,先進(jìn)的后出,最先凍結(jié)最深層里面的那個(gè)屬性, 再依次返回上一層繼續(xù)凍結(jié) var obj = { name:"王寶強(qiáng)", age:18, wife:{ name:"陳羽凡", age:17, son:{ name:"賈乃亮", age:48, girlFriend:{ name:"吳秀波", age:50, zuo:function () { console.log("翻舊賬") }, foods:["棉花糖","粉色的棉花糖","各種棉花糖",{a:"a"}] } } } }; Object.prototype.deepFreeze = function () { var keys = Object.getOwnPropertyNames(this); var that = this; keys.forEach(function (key) { var val = that[key]; if(Object.prototype.toString.call(val) === "[object Object]" || Object.prototype.toString.call(val) === "[object Array]"){ val.deepFreeze() } }); return Object.freeze(this) } obj.deepFreeze()
## 請(qǐng)使用定時(shí)器和canvas寫一個(gè)隨機(jī)生成多個(gè)彩色泡
請(qǐng)自己定義一個(gè)DOM節(jié)點(diǎn)的R操作,以此作為queryselector在IE8以下的polifill。Document
(function(w){ w.app = {}; w.app.getElementByClassName=function(className){ var allnode=document.getElementsByTagName("*"); console.log(allnode) var arr=[]; for(var i=0;i請(qǐng)你手寫一個(gè)ajax原生javaScript請(qǐng)求? "由于ajax一般用于比較舊的技術(shù),這里不適用ES6語(yǔ)法" var xhr = new XMLHttpRuest(); xhr.onreadystatechange = function () { if (xhr.readyState == 0) { //xhr對(duì)象創(chuàng)建好了 初始化狀態(tài) console.log(0) } if (xhr.readyState == 1) { //代表xhr.send方法還未調(diào)用(還未發(fā)送請(qǐng)求),還可以設(shè)置請(qǐng)求頭相關(guān)信息 console.log(1) } if (xhr.readyState == 2) { //此時(shí)send方法被調(diào)用了 響應(yīng)頭和首行已經(jīng)回來(lái)了 console.log(xhr.getResponseHeader("etag")) console.log(2) } if (xhr.readyState == 3) { console.log(3) } if (xhr.readyState === 4 && xhr.status === 200) { console.log(4) console.log(xhr.responseText); } } xhr.open("GET", "http://localhost:3000/ajax?username=123&password=456"); // xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded"); // xhr.send("username=123&password=456"); xhr.send() }*/ "http://上面是原生的ajax寫法,下面是jQuery中的兩種ajax寫法" " 1. 原生jQuery寫法 " $("#btn").click(function () { $.ajax({ url: "http://localhost:3000/ajax", data: "username=jack&password=123", method: "POST", success: function (data) { console.log(data) }, error: function (error) { console.log(error) } }) "2.簡(jiǎn)寫" $.post("http://localhost:3000/ajax", "username=rose&age=12", (data) => { console.log(data) }) "http://如果是get請(qǐng)求直接上面改成get就可以了,data是服務(wù)器響應(yīng)回來(lái)的數(shù)據(jù)"然后這邊給一下服務(wù)器 Node.js的express代碼 響應(yīng)上面的ajax請(qǐng)求的const express = require("express"); const app = express(); app.use(express.static("public")) app.use(express.urlencoded({ extended: true })); app.get("/ajax", (req, res) => { console.log(req.query) res.send("這是ajax的get請(qǐng)求") }) app.post("/ajax", (req, res) => { res.send("這是ajax的post請(qǐng)求") console.log(req.body) }) app.listen(3000, err => { if (!err) { console.log("端口監(jiān)聽成功"); } else { console.log("端口監(jiān)聽失敗" + err); } })如何使用原生javaScript方法提取一個(gè)多重對(duì)象的值,并且塞到不同對(duì)應(yīng)的數(shù)組中?"這里使用了遞歸,還有Object原型上的方法,執(zhí)行上下文棧先進(jìn)后出的知識(shí)。" const obj = { name: "json", age: 1, friend: "夢(mèng)露", info: { name: "Aron", age: 2, friend: "杰西卡", info: { name: "rose", age: 3, friend: "霉霉", info: { name: "jerry", age: 4, friend: "比伯", info: { name: "damu", age: 5, friend: "XJ", }, }, }, } } let namearr, agearr, friendarr; namearr = []; agearr = []; friendarr = []; check(obj); /* function check(obj) { const items = Object.getOwnPropertyNames(obj) items.forEach(function (item) { if (Object.prototype.toString.call(obj[item]) == "[object Object]") { check(obj[item]); } else { if (item.toString() === "name") { namearr.push(obj[item]) } else if (item.toString() === "age") { agearr.push(obj[item]) } else if (item.toString() === "friend") { friendarr.push(obj[item]) } } }) }*/ function check(obj) { for (var item in obj) { if (Object.prototype.toString.call(obj[item]) == "[object Object]") { check(obj[item]); } else { if (item == "name") { namearr.push(obj[item]) } else if (item == "age") { agearr.push(obj[item]) } else if (item == "friend") { friendarr.push(obj[item]) } } } } console.log(`namearr:${namearr}`) console.log(`namearr:${agearr}`) console.log(`namearr:${friendarr}`)## 請(qǐng)手寫一個(gè)jsonp和cors 解決跨域問題的代碼 ?
"jsonp" document.getElementById("btn").onclick = function () { /* 1. jsonp - 特點(diǎn): 1. 利用script標(biāo)簽天然跨域跨域的特性解決跨域的, 民間推出的 2. 兼容性極好 */ //創(chuàng)建一個(gè)script標(biāo)簽 const script = document.createElement("script"); //設(shè)置了響應(yīng)成功的回調(diào)函數(shù) window.jsoncallback = function (data) { console.log(data); } //設(shè)置script的src屬性, 向指定服務(wù)器發(fā)送請(qǐng)求 script.src = "http://localhost:3000/?callback=jsoncallback"; //添加到body中生效 document.body.appendChild(script); } ------ "cors的解決方法:在Node.js的服務(wù)器代碼中設(shè)置一個(gè)響應(yīng)頭" app.get("/cors", (req, res) => { /* 1. cors 特點(diǎn): - 官方推出解決跨域的方案,使用起來(lái)及其簡(jiǎn)單,只需在服務(wù)器設(shè)置一個(gè)響應(yīng)頭 - 兼容性較差 */ //設(shè)置響應(yīng)頭 res.set("access-control-allow-origin", "*"); //允許所有網(wǎng)址跨域瀏覽器的輪詢機(jī)制請(qǐng)簡(jiǎn)述"1.瀏覽器的事件輪詢機(jī)制 瀏覽器中對(duì)于js依靠js引擎實(shí)現(xiàn),js引擎是單線程,不像java,php這些可以是多線程,高并發(fā)。如果要說到瀏覽器的輪詢機(jī)制,那么我們首先要說的 就是單線程的js引擎,前端的核心編程思維模式是異步編程,無(wú)論是頁(yè)面效果、前后端的數(shù)據(jù)交互,都是以異步為核心,每個(gè)需要異步的場(chǎng)景, 往往伴隨著回調(diào)函數(shù)去執(zhí)行,而單線程的JS引擎是無(wú)法自身做這么多工作,還需要異步線程。 1.每當(dāng)JS引擎解析代碼時(shí)遇到異步代碼時(shí),交給異步線程,繼續(xù)往下解析代碼。 2.異步線程處理這些異步代碼時(shí),一旦他們的所對(duì)應(yīng)的回調(diào)函數(shù)達(dá)到執(zhí)行條件便會(huì)塞進(jìn)異步隊(duì)列中,等待JS引擎的輪詢。 3.JS引擎會(huì)在解析完下面的所有代碼后,再去輪詢異步隊(duì)列,從左到右,依次執(zhí)行,這也是說為什么定時(shí)器的時(shí)間不準(zhǔn)確的原因,在JS 解析代碼時(shí),如果遇到下面代碼特別多的時(shí)候,那么它就沒時(shí)間去輪詢異步隊(duì)列的代碼。 瀏覽器中的輪詢機(jī)制有一個(gè)特殊的 requestAnimationFrame(callbackname),它所對(duì)應(yīng)的回調(diào)函數(shù),是在瀏覽器下一次重繪重排時(shí)執(zhí)行,它是一個(gè)宏任務(wù),有待考證 ,目前看只要觸發(fā)重繪重排就會(huì)調(diào)用回調(diào)函數(shù),可以避免掉幀,優(yōu)化性能,減少重繪重排次數(shù),即使一個(gè)空白頁(yè)面,它也會(huì)重繪重排,所以只要運(yùn)用好, 它是完全可以替代定時(shí)器,還可以使用cancelAnimationFrame(callbackname)清除。 "Node.js中的事件輪詢機(jī)制 Event loop"Node.js的事件輪詢機(jī)制外還有同步代碼,微任務(wù), 要想徹底弄懂Node的代碼執(zhí)行,得結(jié)合下面的微任 務(wù)一起學(xué)習(xí)。" "1.執(zhí)行已經(jīng)到時(shí)間的setTimeout 和 setInterval 2.執(zhí)行延遲到一個(gè)循環(huán)迭代的i/o回調(diào) 3.系統(tǒng)內(nèi)部的 idle prepare等 4.poll 輪詢回調(diào)隊(duì)列,依次取出,同步執(zhí)行,與JS的異步隊(duì)列執(zhí)行有點(diǎn)相像 直到回調(diào)隊(duì)列為空 或者系統(tǒng)奔潰了 如果回調(diào)隊(duì)列沒有內(nèi)容,那么看 之前是否設(shè)置過setImmadiate(),如果有就去下一個(gè)階段,如果沒有,就在當(dāng)前等待新的回調(diào)函數(shù)。 如果定時(shí)器的時(shí)間到了,那么也會(huì)去下一個(gè)階段 5. setImmediate 6.關(guān)閉的回調(diào)函數(shù) ,一些準(zhǔn)備關(guān)閉的函數(shù)等. Node.js的事件輪詢機(jī)制也可以看成是單線程,由上往下執(zhí)行,但是到了第6階段,又會(huì)返回第一階段,死循環(huán)。 "什么是微任務(wù)什么是宏任務(wù)?"想得太多反而不好,把每個(gè)宏任務(wù)看成銀行排隊(duì)的老大爺,把微任務(wù)看成老大爺需要的業(yè)務(wù), 可能他需要辦存款,理財(cái),買紀(jì)念幣等,柜臺(tái)人員不幫老大爺辦完 他所需要的任務(wù) -- 微任務(wù),就不會(huì)切換到下一個(gè)老大爺 -- 宏任務(wù), 但是編程的邏輯不 能完全抽象成現(xiàn)實(shí)生活, 照這種說法,只能先有老大爺才會(huì)有業(yè)務(wù)需要, 。可是在Node中,先執(zhí)行的是微任務(wù),只有微任務(wù)如果有多層,先執(zhí)行最頂層,再往下依次執(zhí) 行)執(zhí)行完后才能去執(zhí)行宏任務(wù),微任務(wù)有兩種,一種是process.nextTick() 中的函數(shù),一種是Promise.then()中的函數(shù),只有他們執(zhí)行完后,才會(huì)去執(zhí)行宏任務(wù):setTim eout ,setIneterval,setImmadie。(即執(zhí)行完了微任務(wù)才會(huì)遵循Node.js的輪詢機(jī)制去執(zhí)行, 一切微任務(wù)優(yōu)先)"
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/102719.html
摘要:在他的重學(xué)前端課程中提到到現(xiàn)在為止,前端工程師已經(jīng)成為研發(fā)體系中的重要崗位之一。大部分前端工程師的知識(shí),其實(shí)都是來(lái)自于實(shí)踐和工作中零散的學(xué)習(xí)。一基礎(chǔ)前端工程師吃飯的家伙,深度廣度一樣都不能差。 開篇 前端開發(fā)是一個(gè)非常特殊的行業(yè),它的歷史實(shí)際上不是很長(zhǎng),但是知識(shí)之繁雜,技術(shù)迭代速度之快是其他技術(shù)所不能比擬的。 winter在他的《重學(xué)前端》課程中提到: 到現(xiàn)在為止,前端工程師已經(jīng)成為研...
摘要:在他的重學(xué)前端課程中提到到現(xiàn)在為止,前端工程師已經(jīng)成為研發(fā)體系中的重要崗位之一。大部分前端工程師的知識(shí),其實(shí)都是來(lái)自于實(shí)踐和工作中零散的學(xué)習(xí)。一基礎(chǔ)前端工程師吃飯的家伙,深度廣度一樣都不能差。開篇 前端開發(fā)是一個(gè)非常特殊的行業(yè),它的歷史實(shí)際上不是很長(zhǎng),但是知識(shí)之繁雜,技術(shù)迭代速度之快是其他技術(shù)所不能比擬的。 winter在他的《重學(xué)前端》課程中提到: 到現(xiàn)在為止,前端工程師已經(jīng)成為研發(fā)體系...
摘要:我從沒有聽到有人問如何做一名優(yōu)秀甚至卓越的前端工程師。作為一個(gè)優(yōu)秀的前端工程師還需要深入了解以及學(xué)會(huì)處理的這些缺陷。再者,優(yōu)秀的前端工程師需要具備良好的溝通能力,因?yàn)榍岸斯こ處熤辽俣家獫M足四類客戶的需求。 我所遇到的前端程序員分兩種: 第一種一直在問:如何學(xué)習(xí)前端? 第二種總說:前端很簡(jiǎn)單,就那么一點(diǎn)東西。 我從沒有聽到有人問:如何做一名優(yōu)秀、甚至卓越的WEB前端工程師...
摘要:我從沒有聽到有人問如何做一名優(yōu)秀甚至卓越的前端工程師。作為一個(gè)優(yōu)秀的前端工程師還需要深入了解以及學(xué)會(huì)處理的這些缺陷。再者,優(yōu)秀的前端工程師需要具備良好的溝通能力,因?yàn)榍岸斯こ處熤辽俣家獫M足四類客戶的需求。 我所遇到的前端程序員分兩種: 第一種一直在問:如何學(xué)習(xí)前端? 第二種總說:前端很簡(jiǎn)單,就那么一點(diǎn)東西。 我從沒有聽到有人問:如何做一名優(yōu)秀、甚至卓越的WEB前端工程師...
摘要:我從沒有聽到有人問如何做一名優(yōu)秀甚至卓越的前端工程師。作為一個(gè)優(yōu)秀的前端工程師還需要深入了解以及學(xué)會(huì)處理的這些缺陷。再者,優(yōu)秀的前端工程師需要具備良好的溝通能力,因?yàn)榍岸斯こ處熤辽俣家獫M足四類客戶的需求。 我所遇到的前端程序員分兩種: 第一種一直在問:如何學(xué)習(xí)前端? 第二種總說:前端很簡(jiǎn)單,就那么一點(diǎn)東西。 我從沒有聽到有人問:如何做一名優(yōu)秀、甚至卓越的WEB前端工程師...
閱讀 3319·2021-11-23 09:51
閱讀 2436·2021-11-09 09:46
閱讀 1476·2019-08-30 15:54
閱讀 3121·2019-08-30 14:22
閱讀 2909·2019-08-29 12:40
閱讀 1629·2019-08-26 10:33
閱讀 1774·2019-08-23 17:09
閱讀 1553·2019-08-23 16:11