js 面试的坑
JavaScript事件屬性event.target
<!DOCTYPE html> <html><head><meta charset="UTF-8"><title></title><style type="text/css">#main {width: 200px;height: 100px;background: red;}</style><script type="text/javascript">window.onload = function() {document.getElementById("main").onclick = function(e) {console.log(e.target);console.log(e.target.id);console.log(e.target.tagName);console.log(e.target.nodeName);console.log(e.target.classList);console.log(e.target.className);console.log(e.target.innerHTML);console.log(e.target.innerText);}}</script></head><body><div id="main" class="sb js node"><span>我愛JavaScript</span></div></body></html>
?
jquery檢查元素存在性
javascript檢查元素存在性:
即使這個元素被刪除了,也不擔心javascript代碼報錯;
jquery檢查元素存在性:
代碼如下:
if(!document.getElementById("preview")) return false; ?
?
jquery $(“#preview”)獲取的永遠是對象,即使網頁上沒有此元素。
不能使用以下代碼:
if($("#preview"){
//do something
} 因此要用jquery檢查某個元素在網頁上是否存在時,應該根據獲取到元素的長度來判斷。
代碼如下:
if($("#preview").length>0){
//do something
} ?
判斷頁面滾動方向(上下)
<!DOCTYPE html>
<html><head> <meta charset="UTF-8"> <title></title> <style> body{ height:1000px; } </style> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> </head> <body> <script type="text/javascript"> $(function() { function scroll(fn) { var beforeScrollTop = document.body.scrollTop, fn = fn || function() {}; window.addEventListener("scroll", function() { var afterScrollTop = document.body.scrollTop, delta = afterScrollTop - beforeScrollTop; if(delta === 0) return false; fn(delta > 0 ? "down" : "up"); beforeScrollTop = afterScrollTop; }, false); } scroll(function(direction) { if(direction == "down") { console.log("向下滾"); } else { console.log("向上滾"); } }); }); </script> </body> </html> 深入理解javascript 回調指針
<!doctype html>
<html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> <script type="text/javascript"> window.onload = function() { var i=0; function test() { document.getElementById('main').innerHTML=i++; } setInterval(test, 1000);//注意此處是test,不是test(); } </script> </head> <body> <p id="main"></p> </body> </html> 去掉字符串中所有空格
1、 去掉字符串前后所有空格:
代碼如下:function Trim(str) { return str.replace(/(^\s*)|(\s*$)/g, ""); } 說明: 如果使用jQuery直接使用$.trim(str)方法即可,str表示要去掉前后所有空格的字符串。 2、 去掉字符串中所有空格(包括中間空格,需要設置第2個參數為:g) 代碼如下: function Trim(str,is_global) { var result; result = str.replace(/(^\s+)|(\s+$)/g,""); if(is_global.toLowerCase()=="g") { result = result.replace(/\s/g,""); } return result; } JS獲取div距離瀏覽器窗口的高度(重要)
?
制作圖片懶加載:http://www.cnblogs.com/libin-1/p/5851872.html
http://www.cnblogs.com/vajoy/p/4263291.html
<!DOCTYPE html>
<html><head> <meta charset="UTF-8"> <title></title> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <style type="text/css"> * { padding: 0px; margin: 0px; } #main { height: 2000px; background: red; } #java { height: 300px; background: blue; } #js{ height: 300px; background: green; } #haha{ height: 300px; background: yellow; } </style> <script type="text/javascript"> $(function() { console.log('$("#java").offset().top : '+$("#java").offset().top); $("#java").offset({ top: 200 }); console.log('document.getElementById("js").getBoundingClientRect().top : '+document.getElementById('js').getBoundingClientRect().top); console.log('document.getElementById("js").getBoundingClientRect().bottom : '+document.getElementById('js').getBoundingClientRect().bottom); }) </script> </head> <body> <div id="main"> </div> <div id="java"> </div> <div id="js"> </div> <div id="haha"> </div> </body> </html> 點擊div外面該div消失
http://www.cnblogs.com/libin-1/p/5746167.html
自定義a標簽懸浮title樣式
<!doctype html>
<html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> <style> #tooltip { border: 1px solid red; background: #FF6; position: absolute; padding: 1px; color: #333; display: none; } </style> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> </head> <body> <div id="link"> <p> <a href="#" class="tooltip" title="這是我的超鏈接提示1">提示1</a> </p> <p> <a href="#" class="tooltip" title="這是我的超鏈接提示2">提示2</a> </p> <p> <a href="#" title="這是我的超鏈接提示1">自帶提示1</a> </p> <p> <a href="#" title="這是我的超鏈接提示2">自帶提示2</a> </p> </div> <script type="text/javascript"> $(function() { var x = 10; var y = 20; $("a.tooltip").mouseover(function(e) { this.myTitle = this.title; this.title = ""; var tooltip = "<div id='tooltip'>" + this.myTitle + "</div>"; //創建DIV元素 $("#link").append(tooltip); //追加到文檔中 $("#tooltip").css({ "top": (e.pageY + y) + "px", "left": (e.pageX + x) + "px" }).show(); //設置X Y坐標, 并且顯示 }).mouseout(function() { this.title = this.myTitle; $("#tooltip").remove(); //移除 }).mousemove(function(e) { $("#tooltip").css({ "top": (e.pageY + y) + "px", "left": (e.pageX + x) + "px" }); }) }) </script> </body> </html> 回調函數是什么鬼?
<!DOCTYPE html>
<html><head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> function test(a, b, c) { setInterval(function() { b(a); }, c) } test(10, function(i) { console.log(i); }, 2000); </script> </head> <body> </body> </html> js如何實現繼承
http://blog.csdn.net/james521314/article/details/8645815
JS原型鏈簡單圖解
http://www.cnblogs.com/libin-1/p/5820550.html
http://blog.csdn.net/libin_1/article/details/52366524
http://www.cnblogs.com/myqianlan/p/4421950.html
http://www.cnblogs.com/shuiyi/p/5343399.html
http://www.cnblogs.com/shuiyi/p/5305435.html
this,都快忘了你了
?
參考:http://blog.csdn.net/libin_1/article/details/52337576?
http://www.cnblogs.com/libin-1/p/5814792.html?
http://www.cnblogs.com/beyond-succeed/p/5808290.html
<!DOCTYPE html>
<html><head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> var name = "window1", lzh = { name: "lzh", sayName: function() { function innerFunction() { console.log(_this.name); } var _this=this; innerFunction(); return function() { console.log(_this.name); } } } lzh.sayName()(); </script> <script type="text/javascript"> var name1 = "window2", lzh1 = { name: "lzh", sayName: function() { function innerFunction() { console.log(this.name); } innerFunction(); return function() { console.log(this.name); } } } lzh1.sayName()(); </script> </head> <body> </body> </html> prototype,都快忘了你了
<!DOCTYPE html>
<html><head> <meta charset="utf-8" /> <title></title> <script type="text/javascript"> function LIBIN(a, b) { this.a = a; this.b = b; this.fun = function() { alert('真是日了dog了'); sb(); } sb = function() { alert("臥槽!"); } } LIBIN.prototype = { dianzan: function() { alert("點贊"); }, budianzan: function() { alert("拒絕點贊"); } } var libin = new LIBIN('小明', 18); libin.dianzan(); alert(libin.a + ":" + libin.b); libin.fun(); </script> </head> <body> </body> </html> <!DOCTYPE html>
<html><head> <meta charset="utf-8" /> <title></title> <script type="text/javascript"> function LIBIN(a, b) { this.a = a; this.b = b; this.fun = function() { alert('真是日了dog了'); sb(); } sb = function() { alert("臥槽!"); } }; LIBIN.prototype = { sb:"是你", dianzan: function() { alert("點贊"); }, budianzan: function() { alert("拒絕點贊"); } }; LIBIN.prototype.x="zhangsan"; LIBIN.prototype.saycao=function(){ alert("臥槽"); } var libin = new LIBIN('小明', 18); libin.dianzan(); alert(libin.a + ":" + libin.b+":"+libin.x+":"+libin.sb); libin.fun(); libin.saycao(); </script> </head> <body> </body> </html> JavaScript和jQuery的類型判斷
參考:http://www.cnblogs.com/likeFlyingFish/p/5840496.html
對于類型的判斷,JavaScript用typeof來進行。栗子:復制代碼
console.log(typeof null); //object
console.log(typeof []); //object console.log(typeof {}); //object console.log(typeof new Date()); //object console.log(typeof new Object); //object console.log(typeof function(){}); //function console.log(typeof alert); //function console.log(typeof 1); //number console.log(typeof "abc"); //string console.log(typeof true); //boolean 復制代碼 可以看到,typeof并不能夠準確的判斷出每一種數據類型,比如null和數組等都是object類型。因此,JavaScript判斷數據類型不推薦使用typeof。 那么要如何具體判斷呢??看一下語法<( ̄3 ̄)> ! {}.toString.call(obj); 栗子: 復制代碼 console.log({}.toString.call(null)); //[object Null] console.log({}.toString.call([])); //[object Array] console.log({}.toString.call({})); //[object Object] console.log({}.toString.call(new Date())); //[object Date] console.log({}.toString.call(function(){})); //[object Function] console.log({}.toString.call(new Object)); //[object Object] console.log({}.toString.call(alert)); //[object Function] console.log({}.toString.call(1)); //[object Number] console.log({}.toString.call('abc')); //[object String] console.log({}.toString.call(true)); //[object Boolean] 復制代碼 哈哈,是不是一目了然呀!! 那如果你用的是jQuery,就不用這么麻煩嘍,可以直接用工具方法$.type(),進行判斷 栗子: console.log($.type(null)); //null console.log($.type([])); //array console.log($.type({})); //object console.log($.type(1)); //number ......不全寫完了,結果和{}.toString.call(obj);是一樣的 實際上{}.toString.call(obj);就是jQuery中$.type()這個工具方法的實現最重要的一段代碼(⊙o⊙)哦,神奇吧!趕快去jQuery源碼中找找看吧~~ 如果哪里寫的有問題,歡迎各路大神指正! <!DOCTYPE html>
<html><head> <meta charset="UTF-8"> <title></title> <style type="text/css"> div { width: 200px; height: 200px; border: 3px solid red; padding: 17px; margin: 16px; color: blue; } </style> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <script type="text/javascript"> $(function() { console.log("width:" + $("div").width()); console.log("width+padding:" + $("div").innerWidth()); console.log("width+padding+border:" + $("div").outerWidth()); console.log("width+padding+border+margin:" + $("div").outerWidth(true)); }) </script> </head> <body> <div> <p>width: 200px;</p> <p> height: 200px;</p> <p> border: 3px solid red;</p> <p> padding: 17px;</p> <p> margin: 16px;</p> </div> </body> </html> 像素轉為整數
禁止用戶輸入非數字
<input type="text" placeholder="只能輸入數字" onkeyup="this.value = this.value.replace(/\D/,'')" > window.onload的jQuery寫法
window.onload=function(){} === 或者$(window).load(function(){}); js判斷終端是PC還是移動端
function IsPC() { var userAgentInfo = navigator.userAgent; var Agents = new Array("Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"); var flag = true; for (var v = 0; v < Agents.length; v++) { if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break; } } return flag; } 最簡單的排序
<script type="text/javascript"> var a = [1, 18, 23, 9, 16, 10, 29, 17]; var t = 0; for(var i = 0; i < a.length; i++) { for(var j = i + 1; j < a.length; j++) { if(a[i] > a[j]) { t = a[i]; a[i] = a[j]; a[j] = t; } } } console.log(a); //[1, 9, 10, 16, 17, 18, 23, 29] </script> 判斷終端類型跳轉
<!doctype html>
<html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <script type="text/javascript"> if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { window.location.href = "http://www.baidu.com"; } else { window.location.href = "https://wx.qq.com/"; } </script> </head> <body> </body> </html> 深入理解JavaScript中 fn() 和 return fn() 的區別
在js中,經常會遇到在函數里調用其它函數的情況,這時候會有 fn() 這種調用方式,還有一種是 return fn() 這種調用方式,一些初學者經常會一臉萌逼地被這兩種方式給繞暈了。這里用一個優雅的面試題來分析一下兩種方式的不同之處。
var i = 0;
function fn(){ i++; if(i < 10){ fn(); }else{ return i; } } var result = fn(); console.log(result); 這是一道隱藏了坑的面試題,看似很簡單,大部分人可能想都不想就答出了10。而實際上運行可知打印出來的是 undefined。這道陷阱題很直觀的體現出了前面所說的問題,當我們將執行fn的那一行修改為:
var i = 0;
function fn(){i++;if(i < 10){ return fn(); }else{ return i; } } var result = fn(); console.log(result); 這時,會發現打印出來的結果終于不負眾望的是 10 了。
為什么這里加不加return區別會這么大?
這里的主要原因很簡單,JavaScript的函數都是有默認返回值的,如果函數結尾不寫return,會默認返回undefined,這就是為什么在chrome的console控制臺里,寫代碼經常下面會出現一行undefined的原因。
再仔細看看這個例子,當i自增到9的時候,也就是倒數第二次遞歸調用fn的那一次,如果沒有return,這一次執行完fn,會默認return undefined,而不會繼續下一次遞歸了。當加上了 return,在這里則會繼續最后一次遞歸,即i=10的時候,跳入else里面返回得到正確的10。
說到這里,可以引申出一個更為經典的例子,著名的二分查
var midMath.floor((arr.length - 1) / 2);function search(n, mid) {if (n > arr[mid]) { mid = Math.floor((mid + arr.length) / 2); return search(n, mid); } else if (n < arr[mid]) { mid = Math.floor((mid - 1) / 2); return search(n, mid); } else { return mid; } } var index = search(n, mid); console.log(index); 也是需要多次遞歸調用,很多新手在第一次實現這個算法的時候經常會犯的一個錯誤就是忘記在遞歸的函數前加上return,最后導致返回結果是undefined,這里的道理也和前面是類似的,不加return,會導致遞歸后,直接返回undefined,不會繼續下一次遞歸。
localStorage使用很簡單
?
<!doctype html>
<html lang="en"><head><meta charset="UTF-8" /><title>Document</title><script type="text/javascript">window.onload = function() { window.localStorage.clear(); //清除所有的變量和值 window.localStorage.a = 100; window.localStorage["b"] = 200; window.localStorage.setItem("c", 300);; console.log("window.localStorage.a=" + window.localStorage.a); console.log("window.localStorage['b']=" + window.localStorage["b"]); console.log("window.localStorage.getItem('c')=" + window.localStorage.getItem("c")); console.log(window.localStorage); console.log(typeof window.localStorage); for (var i = 0; i < window.localStorage.length; i++) { var key1 = window.localStorage.key(i); var key2 = window.localStorage.getItem(key1); console.log("字段名:" + key1 + " 值:" + key2); } console.log(typeof window.localStorage.a); console.log(typeof window.localStorage['b']); console.log(typeof window.localStorage.getItem('c')); console.log("空了:" + window.localStorage); window.localStorage.SB = "我是你大爺!"; window.localStorage.aaa = "this is test!"; window.localStorage.removeItem("aaa"); console.log("-------------------------------------------------"); var storage = window.localStorage; var data = { name: 'xiecanyong', sex: 'man', hobby: 'program' }; var d = JSON.stringify(data); console.log(typeof d); storage.setItem("data", d); console.log(storage.data); var json = storage.getItem("data"); var jsonObj = JSON.parse(json); console.log(typeof jsonObj); console.log(storage.data); } </script> </head> <body> </body> </html> 注意
<!DOCTYPE html>
<html><head> <meta charset="UTF-8"> <title></title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <script type="text/javascript"> "use strict"; var B = { "name": "SBSBSBS", "age": "32", say: function() { console.log("不加this可能會報錯:"+this.name+":"+this.age); } } B.say(); var name="我是你大爺"; function USR(name) { this.name = name; this.say = function() { console.log("window下的: " + window.name); console.log("USR 里面的:" + this.name); } }; var a = new USR("我是誰?"); a.say(); </script> <style type="text/css"> * { margin: 0px; padding: 0px; } div { width: 50%; height: 200px; } .demo { float: left; background: red; } .main { float: right; background: green; } </style> </head> <div class="demo"> </div> <div class="main"> </div> <body> </body> </html> 深入理解變量提升和函數提升
<!doctype html>
<html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> <script type="text/javascript"> console.log(x()); console.log(x); var x = 10; console.log(x); x = 20; function x() { var a = new Array(); } console.log(x); if (true) { var a = 1; } else { var b = true; } console.log(a); console.log(b); </script> </head> <body> </body> </html> constructor 和 instanceof
instanceof 用于判斷一個變量是否某個對象的實例,或用于判斷一個變量是否某個對象的實例; constructor 用于判斷一個變量的原型,constructor 屬性返回對創建此對象的數組函數的引用。 Javascript中對象的prototype屬性的解釋是:返回對象類型原型的引用。 <!DOCTYPE html>
<html><head> <meta charset="utf-8" /> <title></title> <script type="text/javascript"> console.log("----------------Number---------------"); var A = 123; console.log(A instanceof Number); //false console.log(A.constructor == Number); //true console.log(A.constructor); console.log("----------------String---------------"); var B = "javascript"; console.log(B instanceof String); //false console.log(B.constructor == String); //true console.log(B.constructor); console.log("----------------Boolean---------------"); var C = true; console.log(C instanceof Boolean); //false console.log(C.constructor == Boolean); //true console.log(C.constructor); console.log("----------------null---------------"); var D = null; console.log(D instanceof Object); //false //console.log(D.constructor == null); //報錯 //console.log(D.constructor); //報錯 console.log("----------------undefined---------------"); var E = undefined; //console.log(E instanceof undefined); // //報錯 //console.log(E.constructor == undefined); //報錯 //console.log(E.constructor); //報錯 console.log("----------------function---------------"); var F = function() {}; console.log(F instanceof Function); console.log(F.constructor == Function); console.log(F.constructor); console.log("----------------new function---------------"); function SB() {}; var G = new SB(); console.log(G instanceof SB); console.log(G.constructor == SB); console.log(G.constructor); console.log("----------------new Object---------------"); var H = new Object; console.log(H instanceof Object); console.log(H.constructor == Object); console.log(H.constructor); console.log("-----------------Array--------------"); var I = []; console.log(I instanceof Array); console.log(I.constructor == Array); console.log(I.constructor); console.log("-----------------JSON--------------"); var J = { "sb": "javascript", "node": "very SB" }; console.log(J instanceof Object); console.log(J.constructor == Object); console.log(J.constructor); </script> </head> <body> </body> </html> <!DOCTYPE html>
<html><head> <meta charset="utf-8" /> <title></title> <script type="text/javascript"> var A = new Array(); var B = new Boolean(); console.log(A instanceof Array); // true console.log(A instanceof Boolean); // false console.log(B.constructor == Array); // false console.log(B.constructor == Boolean); // true </script> </head> <body> </body> </html> <!DOCTYPE html>
<html><head> <meta charset="utf-8" /> <title></title> <script type="text/javascript"> function sb(name, age) { this.name = name; this.age = age; this.sbs = function() { console.log(this.name + "," + this.age); } } var A = new Array(); var B = new Boolean(); var C=new sb("libin",28); document.writeln(A.constructor + "<br />"); //function Array() { [native code] } document.writeln(B.constructor + "<br />"); //function Boolean() { [native code] } document.writeln(C.constructor + "<br />"); //function sb(name, age) { this.name = name; this.age = age; this.sbs = function() { console.log(this.name + "," + this.age); } } C.name="李斌"; C.sbs(); //李斌,28 </script> </head> <body> </body> </html> 注意
<!DOCTYPE html>
<html><head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> function aaa(){ alert(a); //報錯:a is not defined } function bbb(){ var a=10; aaa(); } bbb(); </script> </head> <body> </body> </html> <!DOCTYPE html>
<html><head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> var a=100; function aaa(){ alert(a); //100 } function bbb(){ var a=10; aaa(); } bbb(); </script> </head> <body> </body> </html> 數組去重
<!doctype html>
<html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> <script type="text/javascript"> var a = [1, 2, 5, 5, 7, 9]; Array.prototype.unique = function() { var b = []; for (var i = 0; i < this.length; i++) { if (b.indexOf(this[i]) == -1) { b.push(this[i]); } } return b; } document.writeln(a.unique()); </script> </head> <body> </body> </html> 可惡的forEach
<!doctype html>
<html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> <script type="text/javascript"> var a = ["a", "b", "c", "d", "e"]; a.forEach(function(i, j) { //注意參數i,j對應關系相反 console.log(i + ":" + j); //媽的個巴子,j居然是索引 }) </script> </head> <body> </body> </html> call 和 apply 是為了動態改變 this 而出現的
<!doctype html>
<html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> <script type="text/javascript"> //apply 、 call 、bind 三者都是用來改變函數的this對象的指向的; //apply 、 call 、bind 三者第一個參數都是this要指向的對象,也就是想指定的上下文; //apply 、 call 、bind 三者都可以利用后續參數傳參; //bind 是返回對應函數,便于稍后調用;apply 、call 則是立即調用 。 var xw = { name: "小王", gender: "男", age: 24, say: function(school, grade) { console.log(this.name + " , " + this.gender + " ,今年" + this.age + " ,在" + school + "上" + grade); } } var xh = { name: "小紅", gender: "女", age: 18 } xw.say("清華大學","本科"); xw.say.call(xh,"北京大學","研究僧"); //call后面的參數與say方法中是一一對應的 xw.say.apply(xh,["新東方","電氣焊"]); //而apply的第二個參數是一個數組,數組中的元素是和say方法中一一對應的 xw.say.bind(xh)("藍翔技校","挖掘機"); //bind返回的仍然是一個函數,所以我們還可以在調用的時候再進行傳參 </script> </head> <body> </body> </html> js計算div 寬高等(面試常問)
<!doctype html>
<html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> <style type="text/css"> * { padding: 0px; margin: 0px; } #main { width: 200px; height: 300px; padding: 3px; margin: 7px; background: green; border: 5px solid red; position: absolute; top: 100px; left: 200px; } span{ color: red; } </style> <script type="text/javascript"> function G(a) { return document.getElementById(a); } window.onload = function() { document.onmousemove = function(e) { document.getElementsByTagName('span')[0].innerText = e.clientX + "," + e.clientY; }; G("main").onmousemove = function(e) { document.getElementsByTagName('span')[1].innerText = e.offsetX + "," + e.offsetY; } console.log("屏幕寬高:" + window.screen.width+","+window.screen.height); console.log("body寬高:" +document.body.clientWidth +","+ document.body.clientHeight); console.log("offsetWidth包含width,padding,border:" + G('main').offsetWidth); console.log("offsetHeight包含height,padding,border:" + G('main').offsetHeight); console.log("offsetTop包含top,margin:" + G('main').offsetTop); console.log("offsetLeft包含left,margin:" + G('main').offsetLeft); } </script> </head> <body> <div id="main"> </div> <p>相對窗口的座標:e.clientX,e.clientY:(<span>0,0</span>)</p> <p>相對容器的坐標:e.offsetX,e.offsetY:(<span>0,0</span>)</p> </body> </html> 回到頂部回到底部
$("#dwn").click(function() {$('html,body').animate({ scrollTop: $(document).height() }, 600) }); $(".logo2").click(function() { $('html,body').animate({ scrollTop: 0 }, 600) }); js數據類型判斷和數組判斷
var a = [];
console.log(a instanceof Array) //返回true
var b = {}; console.log(b instanceof Object) //返回true 這么基礎的東西實在不應該再記錄了,不過嘛,溫故知新~就先從數據類型開始吧js六大數據類型:number、string、object、Boolean、null、undefinedstring: 由單引號或雙引號來說明,如"string"number:什么整數啊浮點數啊都叫數字,你懂的~Boolean: 就是true和false啦 undefined:未定義,就是你創建一個變量后卻沒給它賦值~ null: 故名思久,null就是沒有,什么也不表示 object: 這個我也很難解釋的說。就是除了上面五種之外的類型 --------------------上面的都是浮云,下面的才是神馬------------------------------ 數據類型判斷之 typeof typeof可以解決大部分的數據類型判斷,是一個一元運算,放在一個運算值之前,其返回值為一個字符串,該字符串說明運算數的類型,所以判斷某個是否為String類型,可以直接 if(typeof(你的值) == "string"){} 以下是各種數據類型返回結果: 復制代碼 var a="string"; console.log(a); //string var a=1; console.log(a); //number var a=false; console.log(a); //boolean var a; console.log(typeof a); //undfined var a = null; console.log(typeof a); //object var a = document; console.log(typeof a); //object var a = []; console.log(a); //object var a = function(){}; console.log(typeof a) //function 除了可以判斷數據類型還可以判斷function類型 復制代碼 這樣一來就很明顯了,除了前四個類型外,null、對象、數組返回的都是object類型; 對于函數類型返回的則是function,再比如typeof(Date),typeof(eval)等。 然后這里就可以再引申出另一個灰常熱門并且解決方法已普遍存在的問題,如何判斷數據是個數組類型? ---------------------------------------其實這才是我的目的,咩~---------------------------------------------- js判斷數組類型的方法 方法一之 instanceof instance,故名思義,實例,例子,所以instanceof 用于判斷一個變量是否某個對象的實例,是一個三目運算式---和typeof最實質上的區別 a instanceof b?alert("true"):alert("false") //注意b值是你想要判斷的那種數據類型,不是一個字符串,比如Array 舉個栗子: var a=[]; console.log(a instanceof Array) //返回true 方法二之 constructor 在W3C定義中的定義:constructor 屬性返回對創建此對象的數組函數的引用 就是返回對象相對應的構造函數。從定義上來說跟instanceof不太一致,但效果都是一樣的 如: (a instanceof Array) //a是否Array的實例?true or false (a.constructor == Array) // a實例所對應的構造函數是否為Array? true or false 舉個栗子: 復制代碼 function employee(name,job,born){ this.name=name; this.job=job; this.born=born; } var bill=new employee("Bill Gates","Engineer",1985); console.log(bill.constructor); //輸出function employee(name, jobtitle, born){this.name = name; this.jobtitle = job; this.born = born;} 復制代碼 那么判斷各種類型的方法就是: console.log([].constructor == Array); console.log({}.constructor == Object); console.log("string".constructor == String); console.log((123).constructor == Number); console.log(true.constructor == Boolean); -------------------------------------以下不是原創-------------------------------------- 較為嚴謹并且通用的方法: function isArray(object){ return object && typeof object==='object' && Array == object.constructor; } !!注意: 使用instaceof和construcor,被判斷的array必須是在當前頁面聲明的!比如,一個頁面(父頁面)有一個框架,框架中引用了一個頁面(子頁面),在子頁面中聲明了一個array,并將其賦值給父頁面的一個變量,這時判斷該變量,Array == object.constructor;會返回false; 原因: 1、array屬于引用型數據,在傳遞過程中,僅僅是引用地址的傳遞。 2、每個頁面的Array原生對象所引用的地址是不一樣的,在子頁面聲明的array,所對應的構造函數,是子頁面的Array對象;父頁面來進行判斷,使用的Array并不等于子頁面的Array;切記,不然很難跟蹤問題! 方法三之 特性判斷法 以上方法均有一定的缺陷,但要相信人民大眾的智慧是無所不能及的,我們可根據數組的一些特性來判斷其類型 復制代碼 function isArray(object){ return object && typeof object==='object' && typeof object.length==='number' && typeof object.splice==='function' && //判斷length屬性是否是可枚舉的 對于數組 將得到false !(object.propertyIsEnumerable('length')); } 復制代碼 有length和splice并不一定是數組,因為可以為對象添加屬性,而不能枚舉length屬性,才是最重要的判斷因子。 ps: 在這里普及下 propertyIsEnumerable 方法: object. propertyIsEnumerable(proName) 判斷指定的屬性是否可列舉 備注:如果 proName 存在于 object 中且可以使用一個 For…In 循環窮舉出來,那么 propertyIsEnumerable 屬性返回 true。如果 object 不具有所指定的屬性或者所指定的屬性不是可列舉的,那么 propertyIsEnumerable 屬性返回 false。 propertyIsEnumerable 屬性不考慮原型鏈中的對象。 示例: var a = new Array("apple", "banana", "cactus"); document.write(a.propertyIsEnumerable(1)); 方法四之 最簡單的方法 對于這種方法,以下有幾個鏈接可供參考解釋: http://blog.csdn.net/zhangw428/article/details/4171630 http://my.oschina.net/sfm/blog/33197 http://openxtiger.iteye.com/blog/1893378 function isArray(o) { return Object.prototype.toString.call(o) === ‘[object Array]‘; } 當然,你知道啦,這篇東西不完全是出自我手的啦, 全局和局部變量
這里寫代碼片 <!DOCTYPE HTML>
<html><head> <script type="text/javascript"> //只要函數里不管什么時候只要定義var ,變量就是局部變量 var a = 100; function test() { console.log("a=" + a); //100 a = 10; console.log("a=" + a); //10 } test(); console.log("a=" + a); //10 console.log("---------------------------------------"); var b = 100; function test1() { console.log("b=" + b); //undefined var b = 10; console.log("b=" + b); //10 } test1(); console.log("b=" + b); //100 console.log("---------------------------------------"); var c = 10; function test2() { c = 100; console.log("c=" + c); //100 console.log("this.c=" + this.c); //10 var c; //c 就是局部變量 console.log("c=" + c); //100 } test2(); console.log("c=" + c); //10 </script> </head> <body> <div id="sse"> </div> </body> </html> 反轉字符串
<script type="text/javascript"> var a = "hello" document.writeln(a.split("").reverse().join("")); //olleh </script> js倒計時
<!Doctype html>
<html><head> <meta charset="utf-8"> <title>下班倒計時</title> <style> * { margin: 0; padding: 0; } body { font-size: 16px; text-align: center; font-family: arial; } .time { margin-top: 10px; border: 1px solid red; height: 30px; padding: 2px; line-height: 30px; } </style> </head> <body> <div class="time"> <span id="t_d">00天</span> <span id="t_h">00時</span> <span id="t_m">00分</span> <span id="t_s">00秒</span> </div> <script> setInterval(function() { var EndTime = new Date('2016/06/13 00:00:00'); var NowTime = new Date(); var t = EndTime.getTime() - NowTime.getTime(); var d = 0; var h = 0; var m = 0; var s = 0; if (t >= 0) { d = Math.floor(t / 1000 / 60 / 60 / 24); h = Math.floor(t / 1000 / 60 / 60 % 24); m = Math.floor(t / 1000 / 60 % 60); s = Math.floor(t / 1000 % 60); } document.getElementById("t_d").innerHTML = d + "天"; document.getElementById("t_h").innerHTML = h + "時"; document.getElementById("t_m").innerHTML = m + "分"; document.getElementById("t_s").innerHTML = s + "秒"; }, 10); </script> </body> </html> 檢測PC端和移動端的方法總結
<!doctype html>
<html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <script type="text/javascript" src="js/jquery-2.1.4.min.js"></script> <title>Document</title> <script type="text/javascript"> $(function() { if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { console.log(1); } }) </script> </head> <body> <div></div> </body> </html> ## 其他辦法: ##
正在苦逼的實習中,昨天公司讓做一個頁面,涉及到檢測終端的問題,如果是手機設備,就跳轉到指定的網頁上,以前寫響應式布局的時候都是用的同一套代碼,然后通過css的@media screen來實現布局的差異化適應,but現在情景不一樣了,所以看了點資料,做個總結方法一、還是用@media screen
思路:css使用媒體查詢,當屏幕小于760px時,使某個元素的樣式發生改變,然后通過js檢測到這個改變,就可以知道現在切換到移動端了css代碼:1
2
3
4 /* 檢測小屏幕- */ @media only screen and (max-width: 760px) { #some-element { display: none; } } js代碼: 1 2 3 4 5 6 7 8 9 $( document ).ready(function() { var isMobile = false;//默認是pc端 if( $('#some-element').css('display')=='none') { is_mobile = true; } if (isMobile == true) { //對移動端進行處理 } }); 方法二、通過navigator.userAgent字符串檢測 思路:Navigator對象包含有關瀏覽器的信息,通過檢測userAgent字符串,然后使用正則表達式進行匹配,我們自然就能知道用戶是否在使用移動端的瀏覽器啦 先上個簡化版的,意思意思下 1 2 3 4 5 6 7 8 var isMobile = false; // 檢測userAgent if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) { isMobile = true; } if(isMobile){ //移動端的處理邏輯 } 其實還可以用jQuery,but jQuery 從 1.9 版開始,移除了 $.browser 和 $.browser.version: 1 $.browser.device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase())); 通過上面那段代碼基本就能檢測到我們能常用的移動終端了,但是后來我在stackoverflow發現一哥們檢測得更加全面牛逼: 1 2 3 4 5 6 7 8 var isMobile = false;//默認PC端 // 檢測userAgent if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,4))) { isMobile = true; } if(isMobile){<br> //移動端的處理邏輯<br>} 方法三、通過Window.matchMedia()檢測 思路:Window.matchMedia()用來檢查mediaquery語句,扔個MDN的傳送門。它返回一個MediaQueryList對象。該對象有兩個屬性 media:查詢語句的內容。 matches:如果查詢結果為真,值為true,否則為false 代碼實現如下: 1 2 3 4 5 var isMobile = false;//默認PC端 var result = window.matchMedia("<code>only screen and</code> (max-width: 760px)"); if (result.matches){ isMobile = true; } 如果在PC端上使用Window.matchMedia()的話IE10以下是不支持的,但是我們只是用來檢測終端哈,IE不支持就算了,移動端上安卓3.0以上都沒有問題,so~~ 方法四、檢測移動端的TouchEvent事件 思路:使用document.createEvent()創建TouchEvent事件,如果成功那就是移動端了,返回true,pc端是沒有TouchEvent事件的,所以會出錯,返回false 代碼實現: 1 2 3 4 5 6 7 8 9 10 11 var isMobile = false;//默認PC端 function mobile() { try{ document.createEvent("TouchEvent"); return true; } catch(e){ return false; } } isMobile=mobile(); 簡潔方便~~ 方法五、使用Device.js庫 這個庫就沒啥好講的了,自己跟著套代碼就OK arguments是對象,不是數組
<!doctype html>
<html lang="en"> <head> <meta charset="utf-8" /> <script type="text/javascript" src="js/jquery-2.1.4.min.js"></script> <title>document</title> <script type="text/javascript"> function fun1() { // if (arguments.length == 0) { // return 0; // }; // if (arguments.length == 1) { // return arguments[0]; // }; // if (arguments.length == 2) { // return arguments[0] + arguments[1]; // } console.log(typeof arguments); console.log(arguments); switch (arguments.length) { case 0: return 0; break; case 1: return arguments[0]; break; case 2: return arguments[0] + arguments[1]; break; default: break; } } console.log(fun1()); console.log(fun1(275)); console.log(fun1(275,25)); </script> </head> <body> </body> </html> JavaScript 函數重載
<!doctype html>
<html lang="en"> <head> <meta charset="utf-8" /> <script type="text/javascript" src="js/jquery-2.1.4.min.js"></script> <title>document</title> <script type="text/javascript"> function fun1() { // if (arguments.length == 0) { // return 0; // }; // if (arguments.length == 1) { // return arguments[0]; // }; // if (arguments.length == 2) { // return arguments[0] + arguments[1]; // } switch (arguments.length) { case 0: return 0; //arguments是對象,不是數組 break; case 1: return arguments[0]; break; case 2: return arguments[0] + arguments[1]; break; default: break; } } console.log(fun1()); console.log(fun1(275)); console.log(fun1(275,25)); </script> </head> <body> </body> </html> apply、call 是什么?
在 javascript 中,call 和 apply 都是為了改變某個函數運行時的上下文(context)而存在的,換句話說,就是為了改變函數體內部 this 的指向。
JavaScript 的一大特點是,函數存在「定義時上下文」和「運行時上下文」以及「上下文是可以改變的」這樣的概念。
先來一個栗子:
1
2
3
4 5 6 7 8 9 10 11 function fruits() {} fruits.prototype = { color: "red", say: function() { console.log("My color is " + this.color); } } var apple = new fruits; apple.say(); //My color is red 但是如果我們有一個對象banana= {color : "yellow"} ,我們不想對它重新定義 say 方法,那么我們可以通過 call 或 apply 用 apple 的 say 方法: 1 2 3 4 5 banana = { color: "yellow" } apple.say.call(banana); //My color is yellow apple.say.apply(banana); //My color is yellow 所以,可以看出 call 和 apply 是為了動態改變 this 而出現的,當一個 object 沒有某個方法(本栗子中banana沒有say方法),但是其他的有(本栗子中apple有say方法),我們可以借助call或apply用其它對象的方法來操作。 apply、call 的區別 對于 apply、call 二者而言,作用完全一樣,只是接受參數的方式不太一樣。例如,有一個函數定義如下: 1 2 3 var func = function(arg1, arg2) { }; 就可以通過如下方式來調用: 1 2 func.call(this, arg1, arg2); func.apply(this, [arg1, arg2]) 其中 this 是你想指定的上下文,他可以是任何一個 JavaScript 對象(JavaScript 中一切皆對象),call 需要把參數按順序傳遞進去,而 apply 則是把參數放在數組里。 JavaScript 中,某個函數的參數數量是不固定的,因此要說適用條件的話,當你的參數是明確知道數量時用 call 。 而不確定的時候用 apply,然后把參數 push 進數組傳遞進去。當參數數量不確定時,函數內部也可以通過 arguments 這個數組來遍歷所有的參數。 為了鞏固加深記憶,下面列舉一些常用用法: 1、數組之間追加 1 2 3 4 var array1 = [12 , "foo" , {name "Joe"} , -2458]; var array2 = ["Doe" , 555 , 100]; Array.prototype.push.apply(array1, array2); /* array1 值為 [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */ 2、獲取數組中的最大值和最小值 1 2 3 var numbers = [5, 458 , 120 , -215 ]; var maxInNumbers = Math.max.apply(Math, numbers), //458 maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458 number 本身沒有 max 方法,但是 Math 有,我們就可以借助 call 或者 apply 使用其方法。 3、驗證是否是數組(前提是toString()方法沒有被重寫過) 1 2 3 functionisArray(obj){ return Object.prototype.toString.call(obj) === '[object Array]' ; } 4、類(偽)數組使用數組方法 1 var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*")); Javascript中存在一種名為偽數組的對象結構。比較特別的是 arguments 對象,還有像調用 getElementsByTagName , document.childNodes 之類的,它們返回NodeList對象都屬于偽數組。不能應用 Array下的 push , pop 等方法。 但是我們能通過 Array.prototype.slice.call 轉換為真正的數組的帶有 length 屬性的對象,這樣 domNodes 就可以應用 Array 下的所有方法了。 深入理解運用apply、call 下面就借用一道面試題,來更深入的去理解下 apply 和 call 。 定義一個 log 方法,讓它可以代理 console.log 方法,常見的解決方法是: 1 2 3 4 5 function log(msg) { console.log(msg); } log(1); //1 log(1,2); //1 上面方法可以解決最基本的需求,但是當傳入參數的個數是不確定的時候,上面的方法就失效了,這個時候就可以考慮使用 apply 或者 call,注意這里傳入多少個參數是不確定的,所以使用apply是最好的,方法如下: 1 2 3 4 5 function log(){ console.log.apply(console, arguments); }; log(1); //1 log(1,2); //1 2 接下來的要求是給每一個 log 消息添加一個"(app)"的前輟,比如: 1 log("hello world"); //(app)hello world 該怎么做比較優雅呢?這個時候需要想到arguments參數是個偽數組,通過 Array.prototype.slice.call 轉化為標準數組,再使用數組方法unshift,像這樣: 1 2 3 4 5 6 function log(){ var args = Array.prototype.slice.call(arguments); args.unshift('(app)'); console.log.apply(console, args); }; bind 說完了 apply 和 call ,再來說說bind。bind() 方法與 apply 和 call 很相似,也是可以改變函數體內 this 的指向。 MDN的解釋是:bind()方法會創建一個新函數,稱為綁定函數,當調用這個綁 定函數時,綁定函數會以創建它時傳入 bind()方法的第一個參數作為 this,傳入 bind() 方法的第二個以及以后的參數加上綁定函數運行時 本身的參數按照順序作為原函數的參數來調用原函數。 直接來看看具體如何使用,在常見的單體模式中,通常我們會使用 _this , that , self 等保存 this ,這樣我們可以在改變了上下文之后繼續引用到它。 像這樣: 1 2 3 4 5 6 7 8 9 10 var foo = { bar : 1, eventBind: function(){ var _this = this; $('.someClass').on('click',function(event) { /* Act on the event */ console.log(_this.bar); //1 }); } } 由于 Javascript 特有的機制,上下文環境在 eventBind:function(){ } 過渡到 $('.someClass').on('click',function(event) { }) 發生了改變,上述使用變量保存 this 這些方式都是有用的,也沒有什么問題。當然使用 bind() 可以更加優雅的解決這個問題: 1 2 3 4 5 6 7 8 9 var foo = { bar : 1, eventBind: function(){ $('.someClass').on('click',function(event) { /* Act on the event */ console.log(this.bar); //1 }.bind(this)); } } 在上述代碼里,bind() 創建了一個函數,當這個click事件綁定在被調用的時候,它的 this 關鍵詞會被設置成被傳入的值(這里指調用bind()時傳入的參數)。因此,這里我們傳入想要的上下文 this(其實就是 foo ),到 bind() 函數中。然后,當回調函數被執行的時候, this 便指向 foo 對象。再來一個簡單的栗子: 1 2 3 4 5 6 7 8 9 var bar = function(){ console.log(this.x); } var foo = { x:3 } bar(); // undefined var func = bar.bind(foo); func(); // 3 這里我們創建了一個新的函數 func,當使用 bind() 創建一個綁定函數之后,它被執行的時候,它的 this 會被設置成 foo , 而不是像我們調用 bar() 時的全局作用域。 有個有趣的問題,如果連續 bind() 兩次,亦或者是連續 bind() 三次那么輸出的值是什么呢?像這樣: 1 2 3 4 5 6 7 8 9 10 11 12
轉載于:https://www.cnblogs.com/libin-1/p/5865616.html
總結
- 上一篇: IOS开发UISearchBar失去第一
- 下一篇: 找出前50个素数,构成素数表