摘要:面試筆記,該部分為下部分。構(gòu)造函數(shù)模式使用自定義的構(gòu)造函數(shù)與普通函數(shù)一樣,只是用它來創(chuàng)建對象,定義對象類型如的屬性和方法。使用原型來添加屬性共享一個(gè)原型對象的方法原型是指向原型對象的,這個(gè)原型對象與構(gòu)造函數(shù)沒有太大關(guān)系,唯一的關(guān)系
js&jq面試筆記,該部分為下部分。
字符串相關(guān) 1、定義一個(gè)方法,用于將string中的每個(gè)字符之間加一個(gè)空格,并輸出如:"hello" -> "h e l l o" function joinSpace(str){ return str.split("").join(" ") }2、JavaScript中如何檢測一個(gè)變量是一個(gè)String類型?請寫出函數(shù)實(shí)現(xiàn)
方法1 function isString(obj){ return typeof(obj) === "string"? true: false; // returntypeof obj === "string"? true: false; } 方法2 function isString(obj){ return obj.constructor === String? true: false; } 方法3 function isString(obj){ return Object.prototype.toString.call(obj) === "[object String]"?true:false; } 如: var isstring = isString("xiaoming"); console.log(isstring); // true3、請用js去除字符串空格?
方法一:使用replace正則匹配的方法 去除所有空格: str = str.replace(/s*/g,""); 去除兩頭空格: str = str.replace(/^s*|s*$/g,""); 去除左空格: str = str.replace( /^s*/, “”); 去除右空格: str = str.replace(/(s*$)/g, ""); str為要去除空格的字符串,實(shí)例如下: var str = " 23 23 "; var str2 = str.replace(/s*/g,""); console.log(str2); // 2323 方法二:使用str.trim()方法 str.trim() //局限性:無法去除中間的空格,實(shí)例如下: var str = " xiao ming "; var str2 = str.trim(); console.log(str2); //xiao ming 同理: str.trimLeft(),str.trimRight() //分別用于去除字符串左右空格。 方法三:使用jquery,$.trim(str)方法 $.trim(str) 局限性:無法去除中間的空格,實(shí)例如下: var str = " xiao ming "; var str2 = $.trim(str) console.log(str2); // xiao ming4、你如何獲取瀏覽器URL中查詢字符串中的參數(shù)?
//測試地址為:http://www.runoob.com/jquery/misc-trim.html?channelid=12333&name=xiaoming&age=23 function showWindowHref(){ var sHref = window.location.href; var args = sHref.split("?"); if(args[0] == sHref){ return ""; } var arr = args[1].split("&"); var obj = {}; for(var i = 0;i< arr.length;i++){ var arg = arr[i].split("="); obj[arg[0]] = arg[1]; } return obj; } var href = showWindowHref(); // obj console.log(href["name"]); // xiaoming5、js 字符串操作函數(shù)
//這里只是列舉了常用的字符串函數(shù),具體使用方法,請參考網(wǎng)址。 concat() 將兩個(gè)或多個(gè)字符的文本組合起來,返回一個(gè)新的字符串。 indexOf() 返回字符串中一個(gè)子串第一處出現(xiàn)的索引。如果沒有匹配項(xiàng),返回 -1 。 charAt() 返回指定位置的字符。 lastIndexOf() 返回字符串中一個(gè)子串最后一處出現(xiàn)的索引,如果沒有匹配項(xiàng),返回 -1 。 match() 檢查一個(gè)字符串是否匹配一個(gè)正則表達(dá)式。 substr() 返回從string的startPos位置,長度為length的字符串 substring() 返回字符串的一個(gè)子串。傳入?yún)?shù)是起始位置和結(jié)束位置。 slice() 提取字符串的一部分,并返回一個(gè)新字符串。 replace() 用來查找匹配一個(gè)正則表達(dá)式的字符串,然后使用新字符串代替匹配的字符串。 search() 執(zhí)行一個(gè)正則表達(dá)式匹配查找。如果查找成功,返回字符串中匹配的索引值。否則返回 -1 。 split() 通過將字符串劃分成子串,將一個(gè)字符串做成一個(gè)字符串?dāng)?shù)組。 length 返回字符串的長度,所謂字符串的長度是指其包含的字符的個(gè)數(shù)。 toLowerCase() 將整個(gè)字符串轉(zhuǎn)成小寫字母。 toUpperCase() 將整個(gè)字符串轉(zhuǎn)成大寫字母。6、判斷一個(gè)字符串中出現(xiàn)次數(shù)最多的字符,統(tǒng)計(jì)這個(gè)次數(shù)
var str = "asdfssaaasasasasaa"; var json = {}; for (var i = 0; i < str.length; i++) { if(!json[str.charAt(i)]){ //判斷json中是否存在當(dāng)前str.charAr(i)的值 json[str.charAt(i)] = 1; //如果不存在,則將其存放在json中,并且賦值為1,相當(dāng)于出現(xiàn)的次數(shù)為1 }else{ json[str.charAt(i)]++; //如果存在,則這個(gè)字符的值加1,相當(dāng)于次數(shù)加1 } }; var iMax = 0; var iIndex = ""; for(var i in json){ if(json[i]>iMax){ //判斷當(dāng)前json中的鍵值(相當(dāng)于當(dāng)前鍵所在字符的次數(shù))是否大于iMax iMax = json[i]; iIndex = i; } } console.log("出現(xiàn)次數(shù)最多的是:"+iIndex+"出現(xiàn)"+iMax+"次");數(shù)組(Array)對象 1、Array相關(guān)的屬性和方法
Array 對象屬性
constructor 返回對創(chuàng)建此對象的數(shù)組函數(shù)的引用。 var test=new Array(); if (test.constructor==Array){ document.write("This is an Array"); } length 設(shè)置或返回?cái)?shù)組中元素的數(shù)目。 prototype 使您有能力向?qū)ο筇砑訉傩院头椒ā?/pre>Array 對象方法
join() 把數(shù)組的所有元素放入一個(gè)字符串。元素通過指定的分隔符進(jìn)行分隔。 var arr = ["xiao","lin","qiqi","mingtian"]; var arr2 = arr.join(","); console.log(arr2); // 根據(jù)","隔開返回的字符串為:"xiao,lin,qiqi,mingtian" pop() 刪除并返回?cái)?shù)組的最后一個(gè)元素。 var arr = [2,3,4,5]; var arr2 = arr.pop(); console.log(arr2); // 刪除的數(shù)組的最后一個(gè)元素為:5 console.log(arr); // 刪除元素之后的數(shù)組為:[2, 3, 4] shift() 刪除并返回?cái)?shù)組的第一個(gè)元素 var arr = [2,3,4,5]; var arr2 = arr.shift(); console.log(arr2); // 刪除的數(shù)組的第一個(gè)元素為:2 console.log(arr); // 刪除元素之后的數(shù)組為:[3, 4,5] push() 向數(shù)組的末尾添加一個(gè)或更多元素,并返回新的長度。 var arr = [2,3,4,5]; var arr2 = arr.push(6); console.log(arr2); // 返回的數(shù)組長度:5 console.log(arr); // [2, 3, 4, 5, 6] unshift() 向數(shù)組的開頭添加一個(gè)或更多元素,并返回新的長度。 var arr = ["xiao","ming","qiqi","aiming"]; var arr1 = arr.unshift("lang"); console.log(arr1); // 返回的數(shù)組的長度: 5 console.log(arr); //向數(shù)組開頭添加元素返回的結(jié)果:["lang", "xiao", "ming", "qiqi", "aiming"] reverse() 顛倒數(shù)組中元素的順序。 var arr = [2,3,4,5]; arr.reverse(); console.log(arr); // [5, 4, 3, 2] slice() 從某個(gè)已有的數(shù)組返回選定的元素 var arr = [2,3,4,5]; var arr2 = arr.slice(1,3); console.log(arr2); // 截取區(qū)間返回的數(shù)組為:[3, 4] console.log(arr); // [2, 3, 4, 5] sort() 對數(shù)組的元素進(jìn)行排序 借助排序函數(shù),實(shí)現(xiàn)數(shù)值由小到大排序 function sortNumber(a,b){ return a - b } var arr = [23,30,42,5]; var arr2 = arr.sort(sortNumber); console.log(arr2); // [5, 23, 30, 42] console.log(arr); // [5, 23, 30, 42] 借助排序函數(shù),實(shí)現(xiàn)數(shù)值由大到小排序 function sortNumber(a,b){ return b - a } var arr = [23,30,42,5]; var arr2 = arr.sort(sortNumber); console.log(arr2); // [42, 30, 23, 5] console.log(arr); // [42, 30, 23, 5] splice() 刪除元素,并向數(shù)組添加新元素。 語法:arrayObject.splice(index,howmany,item1,.....,itemX) index:必需。整數(shù),規(guī)定添加/刪除項(xiàng)目的位置,使用負(fù)數(shù)可從數(shù)組結(jié)尾處規(guī)定位置。 howmany:必需。要?jiǎng)h除的項(xiàng)目數(shù)量。如果設(shè)置為 0,則不會(huì)刪除項(xiàng)目。 item1, ..., itemX:可選。向數(shù)組添加的新項(xiàng)目。 // 創(chuàng)建一個(gè)新數(shù)組,并向其添加一個(gè)元素 var arr = [1,2,3,4]; arr.splice(2,0,5); console.log(arr); // [1, 2, 5, 3, 4] // 刪除位于 index 2 的元素,并添加一個(gè)新元素來替代被刪除的元素: var arr = [1,2,3,4]; arr.splice(2,1,5); console.log(arr); // [1, 2, 5, 4] toString() 把數(shù)組轉(zhuǎn)換為字符串,并返回結(jié)果。 var arr = ["xiao","ming","qiqi","aiming"]; arr.toString(); console.log(arr); // ["xiao", "ming", "qiqi", "aiming"]2、編寫一個(gè)方法 去掉一個(gè)數(shù)組的重復(fù)元素方法一 var arr = [0,2,3,4,4,0,2]; var obj = {}; var tmp = []; for(var i = 0 ;i< arr.length;i++){ if( !obj[arr[i]] ){ obj[arr[i]] = 1; tmp.push(arr[i]); } } console.log(tmp); //結(jié)果如下: [0, 2, 3, 4] 方法二 var arr = [2,3,4,4,5,2,3,6]; var arr2 = []; for(var i = 0;i< arr.length;i++){ if(arr2.indexOf(arr[i]) < 0){ arr2.push(arr[i]); } } console.log(arr2); //結(jié)果為:[2, 3, 4, 5, 6] 方法三 var arr = [2,3,4,4,5,2,3,6]; var arr2 = arr.filter(function(element,index,self){ return self.indexOf(element) === index; }); console.log(arr2); //結(jié)果為:[2, 3, 4, 5, 6] 方法四:(ES6提供了新的數(shù)據(jù)結(jié)構(gòu) Set) let unique= [...new Set(array)]; let unique= [...new Set([2,3,4,4,5,2,3,6])]; console.log(unique)3、求數(shù)組的最值?求數(shù)組最大值:Math.max.apply(null,arr); var arr = [3,43,23,45,65,90]; var max = Math.max.apply(null,arr); console.log(max); // 90 求數(shù)組最小值:Math.min.apply(null,arr); var arr = [3,43,23,45,65,90]; var min = Math.min.apply(null,arr); console.log(min); // 34、數(shù)組排序相關(guān)選擇排序 /** *以一個(gè)角標(biāo)的元素和其他元素進(jìn)行比較。 *在內(nèi)循環(huán)第一次結(jié)束,最值出現(xiàn)的頭角標(biāo)位置上。 */ function selectSort(array) { if (Object.prototype.toString.call(array).slice(8, -1) === "Array") { var len = array.length, temp; for (var i = 0; i < len - 1; i++) { //輪數(shù) var min = array[i]; for (var j = i + 1; j < len; j++) { //第一個(gè)與第二個(gè)比較 if (array[j] < array[i]) { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } return array; } else { return "array is not an Array!"; } } 冒泡排序 /** *比較方式:相鄰兩個(gè)元素進(jìn)行比較,如果后一個(gè)比前一個(gè)小,換位置。 *原理:內(nèi)循環(huán)結(jié)束一次,最值出現(xiàn)在尾角標(biāo)位置。 */ function bubbleSort(array) { if (Object.prototype.toString.call(array).slice(8, -1) === "Array") { var len = array.length, temp; for(var j=0;j5、數(shù)組的翻轉(zhuǎn)(非reverse())arr[i+1]){ var temp = arr[i]; arr[i] = arr[i+1]; arr[i+1] = temp; } } } return array; } else { return "array is not an Array!"; } } 二分插入排序 /** *為了提高查找效率,可使用折半查找的方式,注意:這種查找只對有序的數(shù)組有效。這種方式也叫二分查找法。 */ function binaryInsertionSort(array) { if (Object.prototype.toString.call(array).slice(8, -1) === "Array") { for (var i = 1; i < array.length; i++) { var key = array[i], left = 0, right = i - 1; while (left <= right) { var middle = parseInt((left + right) / 2); if (key < array[middle]) { right = middle - 1; } else { left = middle + 1; } } for (var j = i - 1; j >= left; j--) { array[j + 1] = array[j]; } array[left] = key; } return array; } else { return "array is not an Array!"; } } 方法一: var arr = [1,2,3,4]; var arr2 = []; while(arr.length) { var num = arr.pop(); //刪除數(shù)組最后一個(gè)元素并返回被刪除的元素 arr2.push(num); } console.log(arr2); // [4, 3, 2, 1] 方法二: var arr = [1,2,3,4]; var arr2 = []; while(arr.length){ var num = arr.shift(); //刪除數(shù)組第一個(gè)元素并返回被刪除的元素 arr2.unshift(num); } console.log(arr2);6、在Javascript中什么是偽數(shù)組?如何將偽數(shù)組轉(zhuǎn)化為標(biāo)準(zhǔn)數(shù)組?偽數(shù)組(類數(shù)組):無法直接調(diào)用數(shù)組方法或期望length屬性有什么特殊的行為,但仍可以用真正數(shù)組遍歷方法來遍歷它們。
典型的是函數(shù)的argument參數(shù),還有像調(diào)用getElementsByTagName,document.childNodes之類的,它們都返回NodeList對象都屬于偽數(shù)組。
a.使用Array.prototype.slice.call(); Array.prototype.slice.call({ 0:"likeke", 1:12, 2:true, length:3 }); //["likeke", 12, true] b.使用[].slice.call(),了解js原型鏈的都知道,實(shí)際上這種方法和第一中方法是一樣的,但上面第一種方式相對效率更高。 [].slice.call({ 0:"likeke", 1:12, 2:true, length:3 }); //["likeke", 12, true] c. 使用ES6中Array.from方法; Array.from({ 0:"lk", 1:12, 2:2013, 3:"長安大學(xué)", length:4 }); //["lk", 12, 2013, "長安大學(xué)"]對象相關(guān) 1、獲取JavaScript對象鍵名var obj = {name: "wan",age: 20, sex: "male"}; var objKey = []; for(var item in obj){ if(obj.hasOwnProperty(item)){ objKey.push(item); } } //for(var item in obj){ // objKey.push(item); //} console.log(objKey);//["name", "age", "sex"]2、call和apply的區(qū)別語法一:func.call(thisObj,a,b,c...) || func.apply(thisObj,array)
定義:將函數(shù)(方法) func 綁定到對象 thisObj 上去運(yùn)行,改變了函數(shù)func 原有的 this 的指向,this指向了對象thisObj(js中的函數(shù)是對象,函數(shù)名是對 Function 對象的引用)語法二:obj.call(thisObj,a,b,c...) || obj.apply(thisObj,array)
定義:將對象 obj 的屬性和方法添加到對象 thisObj 上,即 thisObj 繼承了 obj區(qū)別:call的參數(shù)個(gè)數(shù),從第二個(gè)開始 大于等于 0個(gè),為單個(gè)變量;apply的參數(shù)只有兩個(gè),第二個(gè)參數(shù)為一個(gè)數(shù)組,即array = [a,b,c...];
實(shí)例一:借調(diào)方法,對象sub借調(diào)對象add的方法add(函數(shù)也是對象) function add(a,b){return a+b} function sub(a,b){return a-b} add.call(sub,3,1)//4 sub.call(add,3,1)//2 add.call(sub,3,1) === add(3,1) 實(shí)例二:改變this指向 function a(){console.log(this)} var obj = {} a()//window a.call()//window a.call(obj)//obj 實(shí)例三:實(shí)現(xiàn)繼承 function Animal(name){this.name=name;this.showName=function(){alert(this.name)}} function Cat(name){ Animal.call(this,name); //將Animal對象的屬性和方法應(yīng)用到Cat上,因此Cat繼承了Animal的所有屬性和方法 } var cat = new Cat(“Black Cat”); cat.showName(); //Black Cat 實(shí)例四:多重繼承 function add(a,b){return a+b} function sub(a,b){return a-b} function calc(a,b){ add.call(this) sub.call(this) }3、js中改變this指向的方法call、apply、bind,this總是指向調(diào)用它的對象4、為下面的類增加一個(gè)方法method1var A = function(){} A.prototype.method1 = function(a,b){return a+b}5、實(shí)現(xiàn)Parent類和Child類,并建立Parent和Child的繼承關(guān)系面向?qū)ο蟮幕咎卣饔校悍忾]、繼承、多態(tài)。
function Parent(){ this.surname = "wan"; this.work = function(){console.log("i like work")} } function Child(){} 原型鏈繼承:Child.prototype = new Parent() 實(shí)例化:let person = new Child(); console.log(person.surname);//wan person.work();//i like work 構(gòu)造函數(shù)繼承:function Child(){Parent.call(this)} 組合繼承: function Child(){ Parent.call(this);//繼承屬性 } Child.prototype = new Parent();//繼承方法 原型式繼承: function object(obj){ function Func(){}; Func.prototype = obj; return new Func(); } var Child = object(Parent); 寄生式繼承: 寄生組合式繼承:6、解釋原型和原型鏈原型:即原型對象,原型對象上定義方法和屬性的目的是為了被子類繼承和使用。原型鏈的形成真正是靠__proto__ 而非prototype
原型鏈:每個(gè)對象都有原型,對象的原型指向原型對象,即子對象的原型指向父對象,父對象的原型指向爺爺對象,這種原型層層連接起來的就構(gòu)成了原型鏈。
7、定義一個(gè)類的私有屬性和公有屬性function Person(){ var sex = "man";//var 私有 this.surnname = "wan";//this 公有 }8、實(shí)現(xiàn)一個(gè)函數(shù)clone,可以對JavaScript中的5種主要的數(shù)據(jù)類型(包括Number、String、Object、Array、Boolean)進(jìn)行值復(fù)制。(Object.prototype.toString.call()方法及應(yīng)用) /** * 對象克隆 * 支持基本數(shù)據(jù)類型及對象 * 遞歸方法 */ function clone(obj) { var o; switch (typeof obj) { case "undefined": break; case "string": o = obj + ""; break; case "number": o = obj - 0; break; case "boolean": o = obj; break; case "object": // object 分為兩種情況 對象(Object)或數(shù)組(Array) if (obj === null) { o = null; } else { if (Object.prototype.toString.call(obj).slice(8, -1) === "Array") { o = []; for (var i = 0; i < obj.length; i++) { o.push(clone(obj[i])); } } else { o = {}; for (var k in obj) { o[k] = clone(obj[k]); } } } break; default: o = obj; break; } return o; } //測試 var a=[12,34,"123"]; console.log(clone(a)); var b=null; console.log(clone(b)); var c={1:"a",2:"b",3:"c"}; console.log(clone(c)); var d=1; console.log(clone(d));9、創(chuàng)建對象使用Object構(gòu)造函數(shù)或?qū)ο笞置媪慷伎梢詣?chuàng)建對象,但缺點(diǎn)是創(chuàng)建多個(gè)對象時(shí),會(huì)產(chǎn)生大量的重復(fù)代碼,因此下面介紹可解決這個(gè)問題的創(chuàng)建對象的方法
1、工廠模式 function createPerson(name, age, job) { var o = new Object(); o.name = name; o.age = age; o.job = job; o.getName = function () { return this.name; } return o;//使用return返回生成的對象實(shí)例 } var person = createPerson("Jack", 19, "SoftWare Engineer"); 創(chuàng)建對象交給一個(gè)工廠方法來實(shí)現(xiàn),可以傳遞參數(shù),但主要缺點(diǎn)是無法識(shí)別對象類型,因?yàn)閯?chuàng)建對象都是使用Object的原生構(gòu)造函數(shù)來完成的。 2、構(gòu)造函數(shù)模式 function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.getName = function () { return this.name; } } var person1 = new Person("Jack", 19, "SoftWare Engineer"); var person2 = new Person("Liye", 23, "Mechanical Engineer"); 使用自定義的構(gòu)造函數(shù)(與普通函數(shù)一樣,只是用它來創(chuàng)建對象),定義對象類型(如:Person)的屬性和方法。它與工廠方法區(qū)別在于: 沒有顯式地創(chuàng)建對象,直接將屬性和方法賦值給this對象;沒有return語句; 此外,要?jiǎng)?chuàng)建Person的實(shí)例,必須使用new關(guān)鍵字,以Person函數(shù)為構(gòu)造函數(shù),傳遞參數(shù)完成對象創(chuàng)建;實(shí)際創(chuàng)建經(jīng)過以下4個(gè)過程: 創(chuàng)建一個(gè)對象 將函數(shù)的作用域賦給新對象(因此this指向這個(gè)新對象,如:person1) 執(zhí)行構(gòu)造函數(shù)的代碼 返回該對象 上述由Person構(gòu)造函數(shù)生成的兩個(gè)對象person1與person2都是Person的實(shí)例,因此可以使用instanceof判斷,并且因?yàn)樗袑ο蠖祭^承Object,因此person1 instanceof Object也返回真: alert(person1 instanceof Person);//true; alert(person2 instanceof Person);//true; alert(person1 instanceof Object);//true; alert(person1.constructor === person2.constructor);//ture; 雖然構(gòu)造函數(shù)方式比較不錯(cuò),但也存在缺點(diǎn),那就是在創(chuàng)建對象時(shí),特別針對對象的屬性指向函數(shù)時(shí),會(huì)重復(fù)的創(chuàng)建函數(shù)實(shí)例,以上述代碼為基礎(chǔ),可以改寫為: function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.getName = new Function () {//改寫后效果與原代碼相同,不過是為了方便理解 return this.name; } } 上述代碼,創(chuàng)建多個(gè)實(shí)例時(shí),會(huì)重復(fù)調(diào)用new Function();創(chuàng)建多個(gè)函數(shù)實(shí)例,這些函數(shù)實(shí)例還不是一個(gè)作用域中,當(dāng)然這一般不會(huì)有錯(cuò),但這會(huì)造成內(nèi)存浪費(fèi)。 當(dāng)然,可以在函數(shù)中定義一個(gè)getName = getName的引用,而getName函數(shù)在Person外定義,這樣可以解決重復(fù)創(chuàng)建函數(shù)實(shí)例問題,但在效果上并沒有起到封裝的效果,如下所示: function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.getName = getName; } function getName() {//到處是代碼,看著亂??! return this.name; } 3、原型模式 JS每個(gè)函數(shù)都有一個(gè)prototype(原型)屬性,這個(gè)屬性是一個(gè)指針,指向一個(gè)對象,它是所有通過new操作符使用函數(shù)創(chuàng)建的實(shí)例的原型對象。 原型對象最大特點(diǎn)是,所有對象實(shí)例共享它所包含的屬性和方法,也就是說,所有在原型對象中創(chuàng)建的屬性或方法都直接被所有對象實(shí)例共享。 function Person(){} Person.prototype.name = "Jack";//使用原型來添加屬性 Person.prototype.age = 29; Person.prototype.getName = function(){ return this.name; } var person1 = new Person(); alert(person1.getName());//Jack var person2 = new Person(); alert(person1.getName === person2.getName);//true;共享一個(gè)原型對象的方法 原型是指向原型對象的,這個(gè)原型對象與構(gòu)造函數(shù)沒有太大關(guān)系,唯一的關(guān)系是函數(shù)的prototype是指向這個(gè)原型對象!而基于構(gòu)造函數(shù)創(chuàng)建的對象實(shí)例也包含一個(gè)內(nèi)部指針為:[[prototype]]指向原型對象。 實(shí)例屬性或方法的訪問過程是一次搜索過程: 首先從對象實(shí)例本身開始,如果找到屬性就直接返回該屬性值; 如果實(shí)例本身不存在要查找屬性,就繼續(xù)搜索指針指向的原型對象,在其中查找給定名字的屬性,如果有就返回; 基于以上分析,原型模式創(chuàng)建的對象實(shí)例,其屬性是共享原型對象的;但也可以自己實(shí)例中再進(jìn)行定義,在查找時(shí),就不從原型對象獲取,而是根據(jù)搜索原則,得到本實(shí)例的返回;簡單來說,就是實(shí)例中屬性會(huì)屏蔽原型對象中的屬性; 原型與in操作符 一句話:無論原型中屬性,還是對象實(shí)例的屬性,都可以使用in操作符訪問到;要想判斷是否是實(shí)例本身的屬性可以使用object.hasOwnProperty(‘a(chǎn)ttr’)來判斷; 原生對象中原型 原生對象中原型與普通對象的原型一樣,可以添加/修改屬性或方法,如以下代碼為所有字符串對象添加去左右空白原型方法: String.prototype.trim = function(){ return this.replace(/^s+/,"").replace(/s+$/,""); } var str = " word space "; alert("!"+str.trim()+"!");//!word space! 原型模式的缺點(diǎn),它省略了為構(gòu)造函數(shù)傳遞初始化參數(shù),這在一定程序帶來不便;另外,最主要是當(dāng)對象的屬性是引用類型時(shí),它的值是不變的,總是引用同一個(gè)外部對象,所有實(shí)例對該對象的操作都會(huì)其它實(shí)例: function Person() { } Person.prototype.name = "Jack"; Person.prototype.lessons = ["Math","Physics"]; var person1 = new Person(); person1.lessons.push("Biology"); var person2 = new Person(); alert(person2.lessons);//Math,Physics,Biology,person1修改影響了person2 4、組合構(gòu)造函數(shù)及原型模式 目前最為常用的定義類型方式,是組合構(gòu)造函數(shù)模式與原型模式。構(gòu)造函數(shù)模式用于定義實(shí)例的屬性,而原型模式用于定義方法和共享的屬性。結(jié)果,每個(gè)實(shí)例都會(huì)有自己的一份實(shí)例屬性的副本,但同時(shí)又共享著對方方法的引用,最大限度的節(jié)約內(nèi)存。此外,組合模式還支持向構(gòu)造函數(shù)傳遞參數(shù),可謂是集兩家之所長。 function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.lessons = ["Math", "Physics"]; } Person.prototype = { constructor: Person,//原型字面量方式會(huì)將對象的constructor變?yōu)镺bject,此外強(qiáng)制指回Person getName: function () { return this.name; } } var person1 = new Person("Jack", 19, "SoftWare Engneer"); person1.lessons.push("Biology"); var person2 = new Person("Lily", 39, "Mechanical Engneer"); alert(person1.lessons);//Math,Physics,Biology alert(person2.lessons);//Math,Physics alert(person1.getName === person2.getName);//true,//共享原型中定義方法 在所接觸的JS庫中,jQuery類型的封裝就是使用組合模式來實(shí)例的?。?! 5、動(dòng)態(tài)原型模式 組合模式中實(shí)例屬性與共享方法(由原型定義)是分離的,這與純面向?qū)ο笳Z言不太一致;動(dòng)態(tài)原型模式將所有構(gòu)造信息都封裝在構(gòu)造函數(shù)中,又保持了組合的優(yōu)點(diǎn)。 其原理就是通過判斷構(gòu)造函數(shù)的原型中是否已經(jīng)定義了共享的方法或?qū)傩裕绻麤]有則定義,否則不再執(zhí)行定義過程。該方式只原型上方法或?qū)傩灾欢x一次,且將所有構(gòu)造過程都封裝在構(gòu)造函數(shù)中,對原型所做的修改能立即體現(xiàn)所有實(shí)例中: function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.lessons = ["Math", "Physics"]; } if (typeof this.getName != "function") {//通過判斷實(shí)例封裝 Person.prototype = { constructor: Person,//原型字面量方式會(huì)將對象的constructor變?yōu)镺bject,此外強(qiáng)制指回Person getName: function () { return this.name; } } } var person1 = new Person("Jack", 19, "SoftWare Engneer"); person1.lessons.push("Biology"); var person2 = new Person("Lily", 39, "Mechanical Engneer"); alert(person1.lessons);//Math,Physics,Biology alert(person2.lessons);//Math,Physics alert(person1.getName === person2.getName);//true,//共享原型中定義方法jQuery相關(guān) 1、jQuery為DOM元素綁定點(diǎn)擊事件的方法和區(qū)別.click(function(){}) .bind({"click mouseleave",function(){}},{"click mouseleave",function(){}}) //在.bind()綁定事件的時(shí)候,這些元素必須已經(jīng)存在。 .on() //為動(dòng)態(tài)綁定事件 .one("click", function() {alert("This will be displayed only once.");});//綁定一個(gè)事件,并且只運(yùn)行一次,然后刪除自己,2、jQuery 庫中的 $() 是什么?$() 函數(shù)是 jQuery() 函數(shù)的別稱。$() 函數(shù)用于將任何對象包裹成 jQuery 對象,接著你就被允許調(diào)用定義在 jQuery 對象上的多個(gè)不同方法。
可以將一個(gè)選擇器字符串傳入` $()` 函數(shù),它會(huì)返回一個(gè)包含所有匹配的 DOM 元素?cái)?shù)組的 jQuery 對象。3、如何找到所有 HTML select 標(biāo)簽的選中項(xiàng)?$("[name=selectname] :selected")4、$(this) 和 this 關(guān)鍵字在 jQuery 中有何不同?$(this) 返回一個(gè) jQuery 對象,你可以對它調(diào)用多個(gè) jQuery 方法,比如用 text() 獲取文本,用val() 獲取值等等。
而 this 代表當(dāng)前元素,它是 JavaScript 關(guān)鍵詞中的一個(gè),表示上下文中的當(dāng)前 DOM 元素。你不能對它調(diào)用 jQuery 方法,直到它被 $() 函數(shù)包裹,例如 $(this)。
5、jquery怎么移除標(biāo)簽onclick屬性?獲得a標(biāo)簽的onclick屬性: $("a").attr("onclick") 刪除onclick屬性:$("a").removeAttr("onclick"); 設(shè)置onclick屬性:$("a").attr("onclick","test();");6、jquery中addClass,removeClass,toggleClass的使用。$(selector).addClass(class):為每個(gè)匹配的元素添加指定的類名 $(selector).removeClass(class):從所有匹配的元素中刪除全部或者指定的類,刪除class中某個(gè)值; $(selector).toggleClass(class):如果存在(不存在)就刪除(添加)一個(gè)類 $(selector).removeAttr(class);刪除class這個(gè)屬性;7、JQuery有幾種選擇器?(1)、基本選擇器:#id,class,element,*; (2)、層次選擇器:parent > child,prev + next ,prev ~ siblings (3)、基本過濾器選擇器::first,:last ,:not ,:even ,:odd ,:eq ,:gt ,:lt (4)、內(nèi)容過濾器選擇器: :contains ,:empty ,:has ,:parent (5)、可見性過濾器選擇器::hidden ,:visible (6)、屬性過濾器選擇器:[attribute] ,[attribute=value] ,[attribute!=value] ,[attribute^=value] ,[attribute$=value] ,[attribute*=value] (7)、子元素過濾器選擇器::nth-child ,:first-child ,:last-child ,:only-child (8)、表單選擇器: :input ,:text ,:password ,:radio ,:checkbox ,:submit 等; (9)、表單過濾器選擇器::enabled ,:disabled ,:checked ,:selected8、jQuery中的Delegate()函數(shù)有什么作用?
delegate()會(huì)在以下兩個(gè)情況下使用到:
1、如果你有一個(gè)父元素,需要給其下的子元素添加事件,這時(shí)你可以使用delegate()了,代碼如下:
`$("ul").delegate("li", "click", function(){ $(this).hide(); });`2、當(dāng)元素在當(dāng)前頁面中不可用時(shí),可以使用delegate()
9、$(document).ready()方法和window.onload有什么區(qū)別?(1)、window.onload 方法是在網(wǎng)頁中所有的元素(包括元素的所有關(guān)聯(lián)文件)完全加載到瀏覽器后才執(zhí)行的。 (2)、$(document).ready() 方法可以在DOM載入就緒時(shí)就對其進(jìn)行操縱,并調(diào)用執(zhí)行綁定的函數(shù)。10、如何用jQuery禁用瀏覽器的前進(jìn)后退按鈕?$(document).ready(function() { window.history.forward(1); //OR window.history.forward(-1); });11、 jquery中$.get()提交和$.post()提交有區(qū)別嗎?相同點(diǎn):都是異步請求的方式來獲取服務(wù)端的數(shù)據(jù);
異同點(diǎn):
1、請求方式不同:$.get() 方法使用GET方法來進(jìn)行異步請求的。$.post() 方法使用POST方法來進(jìn)行異步請求的。
2、參數(shù)傳遞方式不同:get請求會(huì)將參數(shù)跟在URL后進(jìn)行傳遞,而POST請求則是作為HTTP消息的實(shí)體內(nèi)容發(fā)送給Web服務(wù)器的,這種傳遞是對用戶不可見的。
3、數(shù)據(jù)傳輸大小不同:get方式傳輸?shù)臄?shù)據(jù)大小不能超過2KB 而POST要大的多
4、安全問題: GET 方式請求的數(shù)據(jù)會(huì)被瀏覽器緩存起來,因此有安全問題。
12、寫出一個(gè)簡單的$.ajax()的請求方式?$.ajax({ url:"http://www.baidu.com", type:"POST", data:data, cache:true, headers:{}, beforeSend:function(){}, success:function(){}, error:function(){}, complete:function(){} });13、jQuery的事件委托方法bind 、live、delegate、on之間有什么區(qū)別?
(1)、bind 【jQuery 1.3之前】
定義和用法:主要用于給選擇到的元素上綁定特定事件類型的監(jiān)聽函數(shù); 語法:bind(type,[data],function(eventObject)); 特點(diǎn): (1)、適用于頁面元素靜態(tài)綁定。只能給調(diào)用它的時(shí)候已經(jīng)存在的元素綁定事件,不能給未來新增的元素綁定事件。 (2)、當(dāng)頁面加載完的時(shí)候,你才可以進(jìn)行bind(),所以可能產(chǎn)生效率問題。 實(shí)例如下:$( "#members li a" ).bind( "click", function( e ) {} );
(2)、live 【jQuery 1.3之后】
定義和用法:主要用于給選擇到的元素上綁定特定事件類型的監(jiān)聽函數(shù); 語法:live(type, [data], fn); 特點(diǎn): (1)、live方法并沒有將監(jiān)聽器綁定到自己(this)身上,而是綁定到了this.context上了。 (2)、live正是利用了事件委托機(jī)制來完成事件的監(jiān)聽處理,把節(jié)點(diǎn)的處理委托給了document,新添加的元素不必再綁定一次監(jiān)聽器。 (3)、使用live()方法但卻只能放在直接選擇的元素后面,不能在層級比較深,連綴的DOM遍歷方法后面使用,即$(“ul”").live...可以,但$("body").find("ul").live...不行; 實(shí)例如下:$( document ).live( "click", "#members li a", function( e ) {} );
(3)、delegate 【jQuery 1.4.2中引入】
定義和用法:將監(jiān)聽事件綁定在就近的父級元素上 語法:delegate(selector,type,[data],fn) 特點(diǎn): (1)、選擇就近的父級元素,因?yàn)槭录梢愿斓拿芭萆先?,能夠在第一時(shí)間進(jìn)行處理。 (2)、更精確的小范圍使用事件代理,性能優(yōu)于.live()??梢杂迷趧?dòng)態(tài)添加的元素上。 實(shí)例如下: $("#info_table").delegate("td","click",function(){/*顯示更多信息*/}); $("table").find("#info").delegate("td","click",function(){/*顯示更多信息*/});
(4)、on 【1.7版本整合了之前的三種方式的新事件綁定機(jī)制】
定義和用法:將監(jiān)聽事件綁定到指定元素上。 語法:on(type,[selector],[data],fn) 實(shí)例如下:$("#info_table").on("click","td",function(){/*顯示更多信息*/});參數(shù)的位置寫法與delegate不一樣。 說明:on方法是當(dāng)前JQuery推薦使用的事件綁定方法,附加只運(yùn)行一次就刪除函數(shù)的方法是one()。 總結(jié):.bind(), .live(), .delegate(),.on()分別對應(yīng)的相反事件為:.unbind(),.die(), .undelegate(),.off()開發(fā)及性能優(yōu)化 1、規(guī)避javascript多人開發(fā)函數(shù)重名問題命名空間 封閉空間 js模塊化mvc(數(shù)據(jù)層、表現(xiàn)層、控制層) seajs 變量轉(zhuǎn)換成對象的屬性 對象化2、請說出三種減低頁面加載時(shí)間的方法壓縮css、js文件 合并js、css文件,減少http請求 外部js、css文件放在最底下 減少dom操作,盡可能用變量替代不必要的dom操作3、你所了解到的Web攻擊技術(shù)(1)XSS(Cross-Site Scripting,跨站腳本攻擊):指通過存在安全漏洞的Web網(wǎng)站注冊用戶的瀏覽器內(nèi)運(yùn)行非法的HTML標(biāo)簽或者JavaScript進(jìn)行的一種攻擊。
(2)SQL注入攻擊
(3)CSRF(Cross-Site Request Forgeries,跨站點(diǎn)請求偽造):指攻擊者通過設(shè)置好的陷阱,強(qiáng)制對已完成的認(rèn)證用戶進(jìn)行非預(yù)期的個(gè)人信息或設(shè)定信息等某些狀態(tài)更新。
4、web前端開發(fā),如何提高頁面性能優(yōu)化?
內(nèi)容方面:
1.減少 HTTP 請求 (Make Fewer HTTP Requests) 2.減少 DOM 元素?cái)?shù)量 (Reduce the Number of DOM Elements) 3.使得 Ajax 可緩存 (Make Ajax Cacheable)
針對CSS:
1.把 CSS 放到代碼頁上端 (Put Stylesheets at the Top) 2.從頁面中剝離 JavaScript 與 CSS (Make JavaScript and CSS External) 3.精簡 JavaScript 與 CSS (Minify JavaScript and CSS) 4.避免 CSS 表達(dá)式 (Avoid CSS Expressions)
針對JavaScript :
1. 腳本放到 HTML 代碼頁底部 (Put Scripts at the Bottom) 2. 從頁面中剝離 JavaScript 與 CSS (Make JavaScript and CSS External) 3. 精簡 JavaScript 與 CSS (Minify JavaScript and CSS) 4. 移除重復(fù)腳本 (Remove Duplicate Scripts)
面向圖片(Image):
1.優(yōu)化圖片 2 不要在 HTML 中使用縮放圖片 3 使用恰當(dāng)?shù)膱D片格式 4 使用 CSS Sprites 技巧對圖片優(yōu)化5、前端開發(fā)中,如何優(yōu)化圖像?圖像格式的區(qū)別?
優(yōu)化圖像:
1、不用圖片,盡量用css3代替。 比如說要實(shí)現(xiàn)修飾效果,如半透明、邊框、圓角、陰影、漸變等,在當(dāng)前主流瀏覽器中都可以用CSS達(dá)成。 2、 使用矢量圖SVG替代位圖。對于絕大多數(shù)圖案、圖標(biāo)等,矢量圖更小,且可縮放而無需生成多套圖。現(xiàn)在主流瀏覽器都支持SVG了,所以可放心使用! 3.、使用恰當(dāng)?shù)膱D片格式。我們常見的圖片格式有JPEG、GIF、PNG。 基本上,內(nèi)容圖片多為照片之類的,適用于JPEG。 而修飾圖片通常更適合用無損壓縮的PNG。 GIF基本上除了GIF動(dòng)畫外不要使用。且動(dòng)畫的話,也更建議用video元素和視頻格式,或用SVG動(dòng)畫取代。 4、按照HTTP協(xié)議設(shè)置合理的緩存。 5、使用字體圖標(biāo)webfont、CSS Sprites等。 6、用CSS或JavaScript實(shí)現(xiàn)預(yù)加載。 7、WebP圖片格式能給前端帶來的優(yōu)化。WebP支持無損、有損壓縮,動(dòng)態(tài)、靜態(tài)圖片,壓縮比率優(yōu)于GIF、JPEG、JPEG2000、PG等格式,非常適合用于網(wǎng)絡(luò)等圖片傳輸。
圖像格式的區(qū)別:
矢量圖:圖標(biāo)字體,如 font-awesome;svg 位圖:gif,jpg(jpeg),png
區(qū)別:
1 、gif:是是一種無損,8位圖片格式。具有支持動(dòng)畫,索引透明,壓縮等特性。適用于做色彩簡單(色調(diào)少)的圖片,如logo,各種小圖標(biāo)icons等。 2、JPEG格式是一種大小與質(zhì)量相平衡的壓縮圖片格式。適用于允許輕微失真的色彩豐富的照片,不適合做色彩簡單(色調(diào)少)的圖片,如logo,各種小圖標(biāo)icons等。 3、png:PNG可以細(xì)分為三種格式:PNG8,PNG24,PNG32。后面的數(shù)字代表這種PNG格式最多可以索引和存儲(chǔ)的顏色值。 關(guān)于透明:PNG8支持索引透明和alpha透明;PNG24不支持透明;而PNG32在24位的PNG基礎(chǔ)上增加了8位(256階)的alpha通道透明;
優(yōu)缺點(diǎn):
1、能在保證最不失真的情況下盡可能壓縮圖像文件的大小。 2、對于需要高保真的較復(fù)雜的圖像,PNG雖然能無損壓縮,但圖片文件較大,不適合應(yīng)用在Web頁面上。ES5和ES6 1、ES5和ES6的類ES5的類 function Person(name) { this.name = name; } Person.prototype.sayHello = function(){ return "Hi, I am " + this.name; } ES6的類 class Person { constructor(name){ this.name = name; } sayHello(){ return "Hi, I am " + this.name; } } typeof Person; //"function" 調(diào)用的方式都是一致的: var me = new Person("Yecao");2、ES5的繼承和ES6的繼承有什么區(qū)別?ES5的繼承時(shí)通過prototype或構(gòu)造函數(shù)機(jī)制來實(shí)現(xiàn)。ES5的繼承實(shí)質(zhì)上是先創(chuàng)建子類的實(shí)例對象,然后再將父類的方法添加到this上(Parent.apply(this))。
ES6的繼承機(jī)制完全不同,實(shí)質(zhì)上是先創(chuàng)建父類的實(shí)例對象this(所以必須先調(diào)用父類的super()方法),然后再用子類的構(gòu)造函數(shù)修改this。
ES6繼承 class Father{ constructor(name){ this.name = name; } getName(){ console.log(this.name); } // 這里是父類的f方法 f(){ console.log("fffffffffffffffffffffff"); } } class Son extends Father{ constructor(name,age){ super(name); // HACK: 這里super()要在第一行 this.age = age; } getAge(){ console.log(this.age); } // 子類的f方法 f(){ console.log("sssssssssssssssssssssss"); } } var s1 = new Son("張一",12); s1.getName(); s1.getAge(); console.log(s1.__proto__); // 為Son,不用修正 s1.f(); // 打印ssssssssssssss s1.__proto__ = new Father(); // 改變s1的原型指向,改為Father s1.f(); // 打印ffffffffffffff console.log(s1.__proto__); // 為Father ES5繼承 function Father(name){ this.name = name; } function Son(name,age){ Father.call(this,name); this.age = age; } Father.prototype.getName = function(){ console.log(this.name); } // 這里注意原型繼承要在,實(shí)例化s1變量之前,如果要使用原型鏈上的方法的話,子類的原型是父類的一個(gè)實(shí)例 Son.prototype = new Father; // 修正構(gòu)造器,這里注意要將Son的構(gòu)造器指向賦值為Son,否則,打印出來的s1是Father對象 Son.prototype.constructor = Son; Son.prototype.getAge = function(){ console.log(this.age); } var s1 = new Son("李四",22); console.log(s1); // Son {name:"李四",age:22} s1.getName(); // 李四 console.log(Son.prototype.constructor); // Son console.log(s1.constructor); // Son,如果不糾正,則為Father s1.getAge(); // 22 //HACK:這里通過__proto__這個(gè)s1實(shí)例的屬性找到了Son的prototype,并為其添加了say的方法 s1.__proto__.say = function(){ console.log("hhhhhhhhhhhhhhhhhhhhhhhh"); } s1.say() // 打印 hhhhhhhhhhhhhhh // NOTE: __proto__這個(gè)屬性是具體到某個(gè)實(shí)例化后的對象才有的屬性,指向他所屬的類的原型 console.log(new Son().__proto__); // 為Son對象2、ES6 Set和MapMap和Set都叫做集合,但是他們也有所不同。Set常被用來檢查對象中是否存在某個(gè)鍵名,Map集合常被用來獲取已存的信息。
1、set類似于數(shù)組,但是成員的值都是唯一的,沒有重復(fù)的值。
Set 實(shí)例的方法分為兩大類:操作方法(用于操作數(shù)據(jù))和遍歷方法(用于遍歷成員)。四個(gè)操作方法。 add(value):添加某個(gè)值,返回Set結(jié)構(gòu)本身。 delete(value):刪除某個(gè)值,返回一個(gè)布爾值,表示刪除是否成功。 has(value):返回一個(gè)布爾值,表示該值是否為Set的成員。 clear():清除所有成員,沒有返回值。 Set 結(jié)構(gòu)的實(shí)例有四個(gè)遍歷方法,可以用于遍歷成員。 keys():返回鍵名的遍歷器 values():返回鍵值的遍歷器 entries():返回鍵值對的遍歷器 forEach():使用回調(diào)函數(shù)遍歷每個(gè)成員2、Set類似于數(shù)組,而Map就類似于鍵值對(Key, Value);
它類似于對象,也是鍵值對的集合,但是“鍵”的范圍不限于字符串,各種類型的值(包括對象)都可以當(dāng)作鍵。
Map有size()屬性,查看Map對象大小,set(key , value) , get(Key), delete(key) , has(key) ,clear()方法。Map 結(jié)構(gòu)原生提供三個(gè)遍歷器生成函數(shù)和一個(gè)遍歷方法。 keys():返回鍵名的遍歷器。 values():返回鍵值的遍歷器。 entries():返回所有成員的遍歷器。 forEach():遍歷 Map 的所有成員。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/96584.html
摘要:確定離開和操作的用法實(shí)例操作符判斷基本數(shù)據(jù)類型檢測對象的繼承關(guān)系,左操作數(shù)是對象,右操作數(shù)是構(gòu)造函數(shù)可以準(zhǔn)確判斷左對象是右對象的實(shí)例頁面的三種彈窗警告框確認(rèn)框提示框請指出和的區(qū)別共同點(diǎn)這兩種事件都代表的是頁面文檔加載時(shí)觸發(fā)。 js&jq涉及內(nèi)容眾多,分為上下兩部分進(jìn)行整理,該部分為上部分。 1、對前端工程師這個(gè)職位你是怎么樣理解的? 前端是最貼近用戶的程序員,前端的能力就是能讓產(chǎn)品...
摘要:站在這個(gè)時(shí)間點(diǎn)上,我對自己之前三次失敗的面試經(jīng)歷做了一次深度回顧。關(guān)于我第三次面試失敗的經(jīng)歷,依然是與輪播圖有關(guān)。當(dāng)然,這次思特奇面試之旅,最后也是以失敗告終,這也是我離進(jìn)大廠最近的一次。 showImg(https://segmentfault.com/img/bVYQuP?w=528&h=513); 前言 時(shí)間的齒輪已經(jīng)來到了2017年的11月份,距離2018年僅僅還剩下不到兩...
摘要:站在這個(gè)時(shí)間點(diǎn)上,我對自己之前三次失敗的面試經(jīng)歷做了一次深度回顧。關(guān)于我第三次面試失敗的經(jīng)歷,依然是與輪播圖有關(guān)。當(dāng)然,這次思特奇面試之旅,最后也是以失敗告終,這也是我離進(jìn)大廠最近的一次。 showImg(https://segmentfault.com/img/bVYQuP?w=528&h=513); 前言 時(shí)間的齒輪已經(jīng)來到了2017年的11月份,距離2018年僅僅還剩下不到兩...
摘要:今天同學(xué)去面試,做了兩道面試題全部做錯(cuò)了,發(fā)過來給道典型的面試題前端掘金在界中,開發(fā)人員的需求量一直居高不下。 排序算法 -- JavaScript 標(biāo)準(zhǔn)參考教程(alpha) - 前端 - 掘金來自《JavaScript 標(biāo)準(zhǔn)參考教程(alpha)》,by 阮一峰 目錄 冒泡排序 簡介 算法實(shí)現(xiàn) 選擇排序 簡介 算法實(shí)現(xiàn) ... 圖例詳解那道 setTimeout 與循環(huán)閉包的經(jīng)典面...
閱讀 3315·2021-09-23 11:55
閱讀 2674·2021-09-13 10:33
閱讀 1693·2019-08-30 15:54
閱讀 3118·2019-08-30 15:54
閱讀 2384·2019-08-30 10:59
閱讀 2393·2019-08-29 17:08
閱讀 1823·2019-08-29 13:16
閱讀 3611·2019-08-26 12:25