javascript編程筆記

1. 快速排序算法

  1. 方法一
function quicksort(n,left,right){
  var p;
  if(left<right){
    p = position(n,left,right);
    quicksort(n,left,p-1);
    quicksort(n,p+1,right);
  }
}

function position(n,left,right){
  var temp = n[left];
  while(left<right){
    while(left<right&&n[right]>temp)
      right--;
    if(left<right)
      n[left++]=n[right];
    while(left<right&&n[left]<temp)
      left++;
    if(left<right)
      n[right--]=n[left];
  }
  n[left]=temp;
  return left;
}

var a =[50, 32, 11, 16, 32, 24, 99, 57, 100];
quicksort(a,0,a.length-1)
console.log(a);
  1. 方法二
function quickSort(arr,left,right){
  var p;
  if(left<right){
    p=position(arr,left,right);
    quicksort(arr,left,p-1);
    quicksort(arr,p+1,right);
  }
  function position(arr,left,right){
    var temp=arr[left];
    while(left<right){
      while(left<right&&arr[right]>temp) right--;
      if(left<right) arr[left++]=arr[right];
      while(left<right&&arr[left]<temp) left++;
      if(left<right) arr[right--]=arr[left];
    }
    arr[left] =temp;
    return left;
  }
}

2. 深度克隆clone(繼承)

var cloneObj = function(obj){
    var str, newobj = obj.constructor === Array ? [] : {};
    if(typeof obj !== 'object'){
        return;
    } else if(window.JSON){
        str = JSON.stringify(obj), //系列化對象
        newobj = JSON.parse(str); //還原
    } else {
        for(var i in obj){
            newobj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i]; 
        }
    }
    return newobj;
};

//測試
var obj = {a: 0, b: 1, c: 2};
var arr = [0, 1, 2];
//執行深度克隆
var newobj = cloneObj(obj);
var newarr = cloneObj(arr);

//對克隆後的新對象進行成員刪除
delete newobj.a;
newarr.splice(0,1);
console.log(obj);
console.log(arr);
console.log(newobj);
console.log(newarr);
/*
結果: 
{a: 0, b: 1, c: 2}
[0, 1, 2]
{b: 1, c: 2}
[1, 2]
*/

3. 找出字符串或者數組中出現相同字符, 而且打印出次數最多的次數和字符

var str = "abcdefgaddda";  
var obj = {};  
for (var i = 0, l = str.length; i < l; i++) {  
  var key = str[i];  
  if (!obj[key]) {  
    obj[key] = 1;  
  } else {  
    obj[key]++;  
  }  
}  

var max = -1;  
var max_key = "";  
var key;  
for (key in obj) {  
  if (max < obj[key]) {  
    max = obj[key];  
    max_key = key;  
  }  
}  
alert("max:" + max + " max_key:" + max_key);

4. 解析url爲json數據格式 也叫將url的查詢參數解析成字典對象同類型

function getUrl(url){
  //var arr=url.split('?')[1].split('&'); 
  var arr = [];
  var a3= [];
  arr = url.split("?");
  a1 = arr[1];
  a2 = a1.split("&");
  obj = {};
  for(var i=0;i<a2.length;i++){
    a3[i] = a2[i].split("=");
    obj[a3[i][0]] = a3[i][1];
  }
return obj;

}
var url= "URL:http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e";
//console.log(getUrl(url));



var getjson = function(url) {
  var a = [];
  var obj = {};
  var a = url.split('?')[1].split('&');
  for (var i = 0; i < a.length; i++) {
    var b[i] = a[i].split('=');
    obj[b[i][0]] = b[i][1];
  }
  return obj;
}

getjson(url);
//正則方法
function getQueryObject(url) {
url = url == null ? window.location.href : url;
    var search = url.substring(url.lastIndexOf("?") + 1);
    var obj = {};
    var reg = /([^?&=]+)=([^?&=]*)/g;
    search.replace(reg, function (rs, $1, $2) {
        var name = decodeURIComponent($1);
        var val = decodeURIComponent($2);                
        val = String(val);
        obj[name] = val;
        return rs;
    });
    return obj;
}

5. 通用事件註冊函數

var obj = document.getElementById("p");
var type = click;
function fun() {}

function addEvent(obj, type, fun) {
  if (obj.addEventListener) {
    obj.addEventListener(type, fun, false);
  } else if (obj.attachEvent) {
    obj.attachEvent("on" + type, fun);
  } else {
    obj["on" + type] = fun;
  }
}

6. 寫一個獲取url中參數的值的函數

function getRequest() {
  var url = window.location.search;
  var oRequest = new Object();
  if (url.indexOf('?') !== -1) {
    url = url.substr(1); // 取得?之後的字符串
    var reqArr = url.split('&');
    for (var i = 0; i < reqArr.length; i++) {
      oRequest[(reqArr[i].split('='))[0]] = unescape((reqArr[i].split('='))[1]);
    }
  }
  return oRequest;
}

7. JS中的數據類型? 如何判定一個變量是不是String類型

var str = new String("abcd");
console.log(typeof str); // object
console.log(str instanceof String); //true
console.log(str.constructor == String); //true
console.log(Object.prototype.toString.call(str) === "[object String]"); // true

var str1 = "abcd";
console.log(typeof str1); // string
console.log(str1 instanceof String); //fasle
console.log(str1.constructor == String); //true
console.log(Object.prototype.toString.call(str1) === "[object String]"); // true*/

8. 請實現, 鼠標點擊頁面中的任意標籤, alert該標籤的名稱.( 注意兼容性)

document.onclick = function(e) {
  var e = e || window.event;
  var obj = e.target || e.srcElement;
  alert(obj.tagName.toLowerCase());
}

9. js異步加載的三種解決方案

(1) defer,只支持IE 
<script type="text/javascript" defer="defer"> 
alert(document.getElementById("p1").firstChild.nodeValue); 
</script> 
(2) async:
<script type="text/javascript" src="demo_async.js" async="async"></script> 
(3) 建立script,插入到DOM中,加載完畢後callBack,見代碼:
function loadScript(url, callback){
    var script = document.createElement("script");
    script.type = "text/javascript";
    if(script.readyState){//IE
        script.onreadystatechange = function(){
            if(script.readyState == "loaded" ||
                script.readyState == "complete"){
                script.onreadystatechange = null;
                callback();
            }
        };
    }else{//firefox,safari,chrome,opera
        script.onload = function(){
            callback();
        };
    }
    script.src = url;
    document.body.appendChild(script);
}

10. 二分搜索,從數組中找到findvalue

function binarySearch(arr,start,end,findvalue){
  var arr = arr.sort(function(a,b){return a-b});
  var mid=Math.floor((start+end)/2);
  var midvalue = arr[mid];
  if(midvalue==findvalue){
    return mid;
  }else if(findvalue<midvalue){
    binarySearch(arr,start,mid-1,findvalue);
  }else if(findvalue>midvalue){
    binarySearch(arr,mid+1,end,findvalue);
  }else{
    return -1;
  } 
}

11. javascript保留兩位小數

num.toFixed(2);

function toDecimal(x) {    
  var f = parseFloat(x)
  if(isNaN(f)){
    return false;
  }
  var f = Math.round(x*100)/100;
  var s = f.toString();
  var rs = s.indexOf('.');
  if(rs<0){
    rs=s.length;
    s+='.';
  }
  while(s.length<=rs+2){
    s+='0';
  }
  return s;          
}

12. 編寫一個方法 求一個字符串的字節長度;英文佔一個, 中文佔兩個

方法一:
function getStrlen(str) {
  var len = str.length;
  var re = /[\u4e00-\u9fa5]/;
  for(var i=0;i<str.length;i++){
    if(re.test(str.charAt(i)))
      len++;
  }
  return len;
}
方法二:
function getStrlen(str){
  var len= str.length;
  for(var i=0;i<str.length;i++){
    if(str.charCodeAt(i)>255)
      len++;
  }
  return len;
}

13. 編寫一個方法 去掉一個數組的重複元素

方法一:該方法數組內順序不變javascript

function delRepeat(arr){
  var a = [];
  for(var i=0,l=arr.length;i<l;i++){
    if(arr.indexOf(arr[i])==i){
      a.push(arr[i])
    }
  }
  return a;
}

方法二:該方法因爲排序緣由,致使去重後數組內元素排序不一樣java

function unique(arr){
    arr.sort();
    var re=[arr[0]];
    for(var i=1,len=arr.length;i<len;i++){
        if(arr[i]!==arr[i-1]){
            re.push(arr[i]);
        }
    }
    return re;
}

13 輸入兩個數字,輸出這兩個數字的最大公約數。如16,4輸出4。

最大公約數就是<=最小的那個數,那就從最小的那個數開始一個一個試node

function maxDivisor(num1,num2){
   var max=num1>num2?num1:num2,
       min=num1>num2?num2:num1;
   for(var i=min;i>=1;i--){
      if(max%i==0&&min%i==0){
         return i;
      }
   }
}

順帶也寫下最小公倍數就是>=最大的那個數,那就從最大的那個數開始一個一個試git

function minDivisor(num1,num2){
   var max=num1>num2?num1:num2,
       min=num1>num2?num2:num1;
   for(var i=max;i>=max;i++){
      if(i%max==0&&i%min==0){
         return i;
      }
   }

}

方法挺多,還有展轉相除法,用遞歸作。es6

function maxDivisor(num1,num2){
   if(num2==0){
      return num1;
   }else{
      return maxDivisor(num2,num1%num2);
   }
}

14. JavaScript中如何檢測一個變量是一個String類型? 請寫出函數實現

//判斷是不是String
function isString(str){
    return ((str instanceof String) || (typeof str).toLowerCase() == 'string');
}
//測試案例
var s1 = "abc",
var s2 = new String("abc");
console.log(isString(s1)+'\n');
console.log(isString(s2));
//JS裏面String的初始化有兩種方式:直接賦值和String對象的實例化
var str = "abc";
var str = new String("abc");
//一般來講判斷一個對象的類型使用typeof,可是在new String的狀況下的結果會是object
//此時須要經過instanceof來判斷

obj.constructor == String;
obj instanceof String;

15. 鼠標點擊頁面中的任意標籤, alert該標籤的名稱.( 注意兼容性)

方法一: DOM0級事件
document.onclick = function(e){
  var e = e||window.event;
  var target = e.target || e.srcElement;
  console.log(target.tagName.toLowerCase());
}
方法二: DOM2級事件
事件代理
function callback(e) {
  var e = e || window.event;
  var target = e.target || e.srcElement;
  console.log(target.tagName);
}

if (document.addEventListener) {
  document.addEventListener('click', callback, false)
} else if (document.attachEvent) {
  document.attachEvent('onclick', callback)
} else {
  document['onclick'] = callback;
}

手寫Function.bind函數

bind()方法會建立一個新函數,當這個新函數被調用時,它的this值是傳遞給bind()的第一個參數, 它的參數是bind()的其餘參數和其本來的參數.github

bind() 最簡單的用法是建立一個函數,使這個函數不論怎麼調用都有一樣的 this 值。JavaScript新手常常犯的一個錯誤是將一個方法從對象中拿出來,而後再調用,但願方法中的 this 是原來的對象。(好比在回調中傳入這個方法。)若是不作特殊處理的話,通常會丟失原來的對象。從原來的函數和原來的對象建立一個綁定函數,則能很漂亮地解決這個問題:
this.x = 9; 
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 81

var retrieveX = module.getX;
retrieveX(); // 9, because in this case, "this" refers to the global object

// Create a new function with 'this' bound to module
//New programmers (like myself) might confuse the global var getX with module's property getX
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
Polyfill(兼容舊瀏覽器)
if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    var aArgs = Array.prototype.slice.call(arguments, 1), 
        fToBind = this, 
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP
                                 ? this
                                 : oThis || this,
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

寫一個判斷質數的isPrime()函數,當其爲質數時返回true,不然返回false。

function isPrime(number) {
   if (typeof number !== 'number' || !Number.isInteger(number)) {
      // Alternatively you can throw an error.
      return false;
   }
   if (number < 2) {
      return false;
   }
 
   if (number === 2) {
      return true;
   } else if (number % 2 === 0) {
      return false;
   }
   var squareRoot = Math.sqrt(number);
   for(var i = 3; i <= squareRoot; i += 2) {
      if (number % i === 0) {
         return false;
      }
   }
   return true;
}

16通用事件處理函數

// event(事件)工具集,來源:github.com/markyunajax

EventUtil = {
    // 頁面加載完成後
    readyEvent : function(fn) {
        if (fn==null) {
            fn=document;
        }
        var oldonload = window.onload;
        if (typeof window.onload != 'function') {
            window.onload = fn;
        } else {
            window.onload = function() {
                oldonload();
                fn();
            };
        }
    },
    // 視能力分別使用dom0||dom2||IE方式 來綁定事件
    // 參數: 操做的元素,事件名稱 ,事件處理程序
    addEvent : function(element, type, handler) {
        if (element.addEventListener) {
            //事件類型、須要執行的函數、是否捕捉
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent('on' + type, function() {
                handler.call(element);
            });
        } else {
            element['on' + type] = handler;
        }
    },
    // 移除事件
    removeEvent : function(element, type, handler) {
        if (element.removeEnentListener) {
            element.removeEnentListener(type, handler, false);
        } else if (element.datachEvent) {
            element.detachEvent('on' + type, handler);
        } else {
            element['on' + type] = null;
        }
    }, 
    // 阻止事件 (主要是事件冒泡,由於IE不支持事件捕獲)
    stopPropagation : function(ev) {
        if (ev.stopPropagation) {
            ev.stopPropagation();
        } else {
            ev.cancelBubble = true;
        }
    },
    // 取消事件的默認行爲
    preventDefault : function(event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    },
    // 獲取事件目標
    getTarget : function(event) {
        return event.target || event.srcElement;
    },
    // 獲取event對象的引用,取到事件的全部信息,確保隨時能使用event;
    getEvent : function(e) {
        var ev = e || window.event;
        if (!ev) {
            var c = this.getEvent.caller;
            while (c) {
                ev = c.arguments[0];
                if (ev && Event == ev.constructor) {
                    break;
                }
                c = c.caller;
            }
        }
        return ev;
    }
};

//獲取瀏覽器頁面當前座標
EventUtil.addEvent(btn,'click',function(e){
e = EventUtil.getEvent(e);
var pageX = e.pageX,
      pageY = e.pageY;
if(!pageX) {
pageX = e.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft);
}
if(!pageY) {
pageY = e.clientY + (document.body.scrollTop || document.documentElement.scrollTop);
}
console.log("頁面X軸座標爲:"+pageX + " "+ "頁面Y軸座標爲:"+pageY);

});算法

17javascript 事件派發 dispathEvent

單個派發事件chrome

//document上綁定自定義事件onDataRes
document.addEventListener('onDataRes', function (event) {
        alert(event.eventType);
    }, false
);
var obj = document.getElementById("obj");
//obj元素上綁定click事件
obj.addEventListener('click', function (event) {
        alert(event.eventType);
    }, false
);
//調用document對象的 createEvent 方法獲得一個event的對象實例。
var event = document.createEvent('HTMLEvents');
// initEvent接受3個參數:
// 事件類型,是否冒泡,是否阻止瀏覽器的默認行爲
event.initEvent("onDataRes", true, true);
event.eventType = 'message';
//觸發document上綁定的自定義事件onDataRes
document.dispatchEvent(event);*/
/*var event1 = document.createEvent('HTMLEvents');

event1.initEvent("click", true, true);
event1.eventType = 'message';
//觸發obj元素上綁定click事件
document.getElementById("test").onclick = function () {
    obj.dispatchEvent(event1);
};

支持ie瀏覽器通用派發事件觸發json

var dispatch = function(ele, evt) {
    if(document.addEventListener){
        var event = document.createEvent('HTMLEvents');
        event.initEvent(evt, true, true);
        document.dispatchEvent(event);
    }else {
        var event = document.createEventObject();
        document.fireEvent('on'+evt, event)
    }
}

var li = document.getElementById('li');

document.addEventListener('onDataRes', function (event) {
        alert(event.eventType);
    }, false
);

dispatch(li, 'onDataRes')

18,事件代理對比

1.方法一:循環綁定
<ul id="list"></ul>
<script>
    function bindEvent(el, n) {
        addEvent(lis[i], 'click', function() { console.log(i); });
    }
    // 用 setTimeout 模擬 Ajax 僞代碼
    setTimeout(function() {
        var ajaxData = '<li id="item-1">item1</li> <li id="item-2">item2</li> 
        <li id="item-3">item3</li> ;
        var ul = document.getElementById('list')
        ul.innerHTML(ajaxData);
        var lis = ul.getElementsByTagName('li');

        for (var i = 0; i < lis.length; i++) {
            bindEvent(lis[i], i);
        }
    }, 1000);
</script>

2.方法2 ,事件代理,綁定到ul元素上

<ul id="list"></ul>
<script>
function delegateEvent(el, eventType, fn) {
    addEvent(el, eventType, function(event) {
        event = event || window.event;
        var target = event.target || event.srcElement;
        fn(target);
    });
}

var el = document.getElementById('list');
// 用 setTimeout 模擬 Ajax 僞代碼
setTimeout(function() {
    var ajaxData = '<li id="item-1">item1</li> <li id="item-2">item2</li>
     <li id="item-3">item3</li> <li id="item-4">item4</li>
     <li id="item-5">item5</li>';
    el.innerHTML(ajaxData)
}, 1000);

delegateEvent(el, 'click', function(target) {
    console.log(target.id);
});
</script>

19,對象深拷貝

1.遞歸解決

let obj = {name:'fiona-SUN'};
let copyFunc = (originObj) => {
    let copyObj = {};
    for(let key in originObj){
        copyObj[key] = originObj[key];
    }
    return copyObj;
};

let copyObj = copyFunc(obj);
copyObj.name = 'fiona';
console.log(copyObj.name); // 'fiona'
console.log(obj.name); // 'fiona-SUN'

方法二:經過JSON去解析

let obj = {name:'fiona-SUN'};

let copyObj = JSON.parse(JSON.stringify(obj));

copyObj.name = 'fiona';
console.log(copyObj.name); // 'fiona'
console.log(obj.name); // 'fiona-SUN'

方法三:es6之展開Object.assign(拷貝obj的內容到一個新的堆內存,copyObj存儲新內存的引用)

let obj = {name:'fiona-SUN'};

let copyObj = Object.assign({}, obj);

copyObj.name = 'fiona';
console.log(copyObj.name); // 'fiona'
console.log(obj.name); // 'fiona-SUN'

方法四:es6之展開運算符(僅用於數組)

let arr = [1,2,3];
let copyArr = [...obj];
copyArr[2] = 0;
console.log(copyArr[2]); // 0
console.log(arr[2]); // 2
相關文章
相關標籤/搜索