前端javascript知識(三)
阿新 • • 發佈:2017-11-17
當前 call method reduce n) obj bin mat prime
- 函數記憶,判斷是不是質數.
方法一: function isPrime1(n){ if(n<=3){return true} else{ for(var i=2;i<Math.sqrt(n);i++){ if(n%i==0){return false;} } return true; } }; 方法二:hash var isPrime2=(function(){//hash var hash={}; return function(n){ if(n<=3){return true} else if(hash[n]!==undefined){ return hash[n]; }else{ for(var i=2;i<Math.sqrt(n);i++){ if(n%i==0){return hash[n]=false} } return hash[n]=true; } } })();
- 數組去重
方法一: var arr1=[1,2,3,2,1,2]; function repeat1(arr){ for(var i=0,arr2=[];i<arr.length;i++){ if(arr2.indexOf(arr[i])==-1){ arr2.push(arr[i]); } }//(遍歷結束) return arr2; } 方法二:hash function repeat2(arr){ //遍歷arr中每個元素,同時聲明hash for(var i=0,hash={};i<arr.length;i++){ //hash中是否包含當前元素值的建 //如果不包含,就hash添加一個新元素,以當前元素值為key,value默認為1 if(hash[arr[i]]===undefined){ hash[arr[i]]=1; } }//(遍歷結束) //將hash轉為索引: var i=0; var arr2=[]; for(arr2[i++] in hash); return arr2; } 方法三: function repeat3(arr){ return arr.sort() .join(",,") .replace( /(^|,,)([^,]+)(,,\2)*/g, "$1$2") .split(",,"); } console.log(repeat3(arr1));
- 插入排序
var arr=[2,4,1,5,3]; function insertSort(arr){ //遍歷arr中每個元素(i從1開始) for(var i=1;i<arr.length;i++){ //將當前元素臨時保存在變量t中 var t=arr[i]; var p=i-1;//聲明變量p=i-1 //循環:(arr[p]>t&&p>=0){ while(arr[p]>t&&p>=0){ //將p位置的值,賦值給p+1位置 arr[p+1]=arr[p]; p--;//p-- }//(循環結束) arr[p+1]=t;//將t放在p+1的位置上 }//(循環結束) } insertSort(arr); console.log(String(arr));
- 快速排序:
function quickSort(arr){ //如果arr的length<=1 if(arr.length<=1){ return arr;//就直接返回arr } //計算參照位p var p=Math.floor(arr.length/2); var left=[]; var right=[]; //刪除p位置的元素 var center=arr.splice(p,1)[0]; //遍歷arr中每個元素 for(var i=0;i<arr.length;i++){ if(arr[i]>=center){ right.push(arr[i]); }else{ left.push(arr[i]); } } return quickSort(left) .concat(center,quickSort(right)) } var sortedArr=quickSort(arr); console.log(String(sortedArr));
- 正則表達式
(1) "ryan5 is6 not7 a8 good9 man10" var n=5; var str="ryan is not a good man"; str=str.replace(/\b[a-z]+\b/g,function(kw){ return kw+n++;}); console.log(str);
- 統計字符串中每種字符出現的次數,出現次數最多的是? 出現?次
var str="helloworld"; 方法一:用hash for(var i=0,hash={};i<str.length;i++){ if(hash[str[i]]){ hash[str[i]]++ }else{ hash[str[i]]=1; } } console.dir(hash); 方法二:用正則 var arr=str.split("") .sort() .join("") .match(/([a-z])\1*/g) .sort(function(a,b){ return b.length-a.length; }) console.log("出現最多的是: "+arr[0][0] +"共"+arr[0].length+"次"); var hash={}; arr.forEach(function(val){ hash[val[0]]=val.length; }); console.dir(hash);
- 數組降維
var arr=[ [0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0], ]; //method 1: for(var r=0,arr1=[];r<arr.length;r++){ for(var c=0;c<arr[r].length;c++){ arr1.push(arr[r][c]); } } console.dir(arr1); //method 2: for(var r=0,arr2=[];r<arr.length;r++){ arr2=arr2.concat(arr[r]); } console.dir(arr2); //method 3: var arr2=[].concat.apply([],arr); console.dir(arr2);
- Function賦值
var f=function(){var a=b=1;} f(); console.log(b);//1 console.log(a);//報錯 var f=function(){var a=b=1;} setTimeout(f,0); console.log(b);//報錯 f(); var a,b=0, fn=function(){var a=b=2;} fn(); console.log(a);//undefined console.log(b);//2
- 函數currying(柯裏華)
var getN; function add(n){ getN=function(){console.log(n);} return function(m){ n+=m; arguments.callee.toString=function(){ return n; } return arguments.callee; } } add(1)(2)(3); getN();//6 add(1)(2)(3)(4); getN();//10 alert(add(1)(2)(3));//6 alert(add(1)(2)(3)(4));//10
- 遞歸
var emp={ work:function(){//3,2,1 var sum=0;//+3+2+1 +2+1 +1 for(vari=0; i<arguments.length&&arguments[0]>0; i++){ sum+=arguments[i] +arguments.callee( --arguments[i] ); } return sum; } } console.log(emp.work(3,2,1));//10
- 閉包
(1)function fun(n,o){//外層函數 console.log(o); return { fun:function(m){//內層函數 n return fun(m,n); } } } var a=fun(0);a.fun(1); a.fun(2); a.fun(3); //undefined 0 0 0 var a=fun(0).fun(1).fun(2).fun(3); //undefined 0 1 2 var a=fun(0).fun(1); a.fun(2); a.fun(3); //undefined 0 1 1 (2)var a=0,b=0; function A(a){ A=function(b){alert(a+b++)}; alert(a); } A(1);//1 A(12);//13
- OOP
(1) window.a=300; function fn1(){ this.a=100; this.b=200; return function(){ alert(this.a) }.call(arguments[0]) } function fn2(){ this.a=new fn1(); } var a=new fn1().b;//300 var v=new fn1(fn2());//[object Object] (2) var number=2;//4 8 var obj={ number:4,//8 fn1:(function(){ //var number; this.number*=2; number*=2; //聲明提前 undefined var number=3; return function(){ this.number*=2; number*=3; alert(number); } })() } var fn1=obj.fn1; alert(number); fn1(); obj.fn1(); //4 9 27 alert(window.number);//8 alert(obj.number);//8 (3) function Foo(){ getName=function(){alert(1);}; return this; } Foo.getName=function(){alert(2);}; Foo.prototype.getName=function(){ alert(3); }; var getName=function(){alert(4);}; function getName(){ alert(5); }; Foo.getName();//2 getName();//4 Foo().getName();//1 getName();//1 new Foo.getName();//2 new Foo().getName();//3 new new Foo().getName();//3 (4) var a=1; var b={ a:2, b:function(){ console.log(this.a);//1 }(), f:this.f=function(){ console.log(this.a); } }; function f(){ console.log(3); } f();//1 b.f();//2 (b.f)();//2 (0,b.f)();//1 (5) var foo=function(){ console.log(this.a); } var obj={a:2,foo:foo}; var a=10; var bar=obj.foo; var bar2=foo.bind(obj); bar();//10 bar2();//2 foo();//10 obj.foo();//2 setTimeout(bar,0);//10 (6) function MyObj(){ this.p.pid++; } MyObj.prototype.p={"pid":0}//2 MyObj.prototype.getNum=function(num){ return this.p.pid+num; } var _obj1=new MyObj(); //創建新對象,繼承原型pid+1 var _obj2=new MyObj(); //創建新對象,繼承原型pid+2 console.log( _obj1.getNum(1)+_obj2.getNum(2) );//7 2+1 + 2+2
- 判斷一個對象是不是數組類型,有五種方法:
(1) typeof 無法判斷 只能判斷原始類型的值和函數 (2)isPrototypeOf 判斷父及對象 可檢查整個原型鏈 //可能繼承自數組 console.log(Array.prototype.isPrototypeOf([])?"是數組":"不是數組"); console.log(Array.prototype.isPrototypeOf({})?"是數組":"不是數組"); console.log(Array.prototype.isPrototypeOf(function(){})?"是數組":"不是數組"); (3)constructor 檢查指定對象的構造函數 可檢查整個原型鏈 //可能繼承自數組 var father={}; var son={}; father.__proto__=Array.prototype; son.__proto__=father; console.log(son.contructor==Array?"是數組":"不是數組") console.log({}.contructor==Array?"是數組":"不是數組"); console.log(function(){}.contructor==Array?"是數組":"不是數組"); (4)instanceof 檢查一個對象是否是制定構造函數的實例 可檢查整個原型鏈 //可能繼承自數組 var father={}; var son={}; father.__proto__=Array.prototype; son.__proto__=father; console.log(son instanceof Array?"是數組":"不是數組"); console.log({} instanceof Array?"是數組":"不是數組"); console.log(function(){} instanceof Array?"是數組":"不是數組"); (5)強行用要檢查的對象,調用原始的toString方法 不檢查整個原型鏈 //[object class]: class-Array Date Object //只能檢查最初就是數組創建的對象。 console.log(Object.prototype.toString.call([])=="[object Array]"?"是數組":"不是數組"); console.log(Object.prototype.toString.call({})); console.log(Object.prototype.toString.call(function(){})); console.log(Object.prototype.toString.call(/\d/)); var father={}; var son={}; father.__proto__=Array.prototype; son.__proto__=father; console.log(Object.prototype.toString.call(son)=="[object Array]"?"是數組":"不是數組");//不是 //結論: 對象一旦創建,class屬性就無法修改 //修改繼承關系,也無法修改class屬性 (6) Array.isArray(obj) 不檢查整個原型鏈 console.log(Array.isArray([])); console.log(Array.isArray({})); //如果瀏覽器不支持isArray if(Array.prototype.isArray===undefined){//if(!Array.isArray) //給?添加isArray方法 Array.prototype.isArray=function(arg){ //強行調用原始toString方法,和"[object Array]"比較 return Object.prototype.toString.call(arg) =="[object Array]"?"是數組":"不是數組"; } }
- 自定義Object.create()——手寫
Object.create=function(father,props){ console.log("我的create"); /*使用setPrototypeOf方法 var o=Object();//1. 創建空對象 Object.setPrototypeOf(o,father);//2. 繼承father */ /*不使用setPrototypeOf方法 function Constructor(){} Constructor.prototype=father; var o=new Constructor(); */ Object.defineProperties(o,props);//3. 定義新屬性 return o; }
- 深克隆原理
Object.clone=function(obj){//深克隆 if(typeof(obj)=="object"){//如果obj是對象 var o=//有必要區分數組和普通對象 Object.prototype.toString.call(obj)=="[object Array]"?[]:{}; for(var key in obj){//遍歷obj的自有屬性 //如果key是obj的自有屬性 if(obj.hasOwnProperty(key)){ o[key]=arguments.callee(obj[key]);//arguments.callee調的是當前的Object.clone函數 } } return o; }else{//如果obj是原始類型的值,就直接返回副本 return obj; } }
- 如果瀏覽器不支持every屬性,every的實現原理
if(Array.prototype.every===undefined){ Array.prototype.every=function(fun){ //遍歷當前數組中每個元素 for(var i=0;i<this.length;i++){ if(this[i]!==undefined){ //調用fun,依次傳入當前元素值,位置i,當前數組作為參數 ,將返回值,保存在變量r中 var r=fun(this[i],i,this); if(r==false){//如果r為false return false;//返回false } } }//(遍歷結束) return true;//返回true } }
- 如果瀏覽器不支持some屬性,some的實現原理
if(Array.prototype.some===undefined){ Array.prototype.some=function(fun){ for(var i=0;i<this.length;i++){ if(this[i]!==unefined){ var r=fun(this[i],i,this); if(r==true){ return true; } } } return false; } }
- 瀏覽器不支持map屬性,map的實現原理
if(Array.prototype.map===undefined){ Array.prototype.map=function(fun){ //創建空數組: newArr var newArr=[]; //遍歷當前數組中每個元素 for(var i=0;i<this.length;i++){ //如果當前元素不是undefined if(this[i]!==undefined){//判斷稀疏數組 //調用fun傳入當前元素值,位置i,當前數組,將結果保存在r中 //將newArr的i位置賦值為r var r=fun(this[i],i,this); newArr[i]=r; } }//(遍歷結束) return newArr;//返回newArr } }
- 如果瀏覽器不支持reduce屬性,reduce的實現原理
if(Array.prototype.reduce===undefined){ Array.prototype.reduce=function(fun,base){ base===undefined&&(base=0); for(var i=0;i<this.length;i++){ if(this[i]!==undefined){ base=fun(base,this[i],i,this); } } return base; } }
- 如果瀏覽器不支持bind屬性, bind函數的實現原理
if(Function.prototype.bind===undefined){ Function.prototype.bind=function(obj/*,參數列表*/){ var fun=this;//留住this //*****將類數組對象,轉化為普通數組 var args=Array.prototype.slice.call(arguments,1); //args保存的就是提前綁定的參數列表 /*function slice(1){ var sub=[]; for(var i=0;i<length;i++){ sub.push(arguments[i]); } return sub; }*/ return function(){ //將後傳入的參數值,轉為普通數組 var innerArgs=Array.prototype.slice.call(arguments);//將之前綁定的參數值和新傳入的參數值,拼接為完整參數之列表 var allArgs=args.concat(innerArgs) //調用原始函數fun,替換this為obj,傳入所有參數 fun.apply(obj,allArgs); } } }
前端javascript知識(三)