首页 > 代码库 > js 面试的坑
js 面试的坑
判断页面滚动方向(上下)
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title></title> <style> body{ height:1000px; } </style> <script src=http://www.mamicode.com/"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://www.mamicode.com/"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://www.mamicode.com/"http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> </head> <body> <div id="link"> <p> <a href=http://www.mamicode.com/"#" class="tooltip" title="这是我的超链接提示1">提示1</a> </p> <p> <a href=http://www.mamicode.com/"#" class="tooltip" title="这是我的超链接提示2">提示2</a> </p> <p> <a href=http://www.mamicode.com/"#" title="这是我的超链接提示1">自带提示1</a> </p> <p> <a href=http://www.mamicode.com/"#" 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); //objectconsole.log(typeof []); //objectconsole.log(typeof {}); //objectconsole.log(typeof new Date()); //objectconsole.log(typeof new Object); //objectconsole.log(typeof function(){}); //functionconsole.log(typeof alert); //functionconsole.log(typeof 1); //numberconsole.log(typeof "abc"); //stringconsole.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)); //nullconsole.log($.type([])); //arrayconsole.log($.type({})); //objectconsole.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://www.mamicode.com/"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 = http://www.mamicode.com/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://www.mamicode.com/"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.mamicode.com/"http://www.baidu.com"; } else { window.location.href = http://www.mamicode.com/"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 = http://www.mamicode.com/{"hljs-attribute">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) //返回truevar b = {};console.log(b instanceof Object) //返回true
这么基础的东西实在不应该再记录了,不过嘛,温故知新~就先从数据类型开始吧js六大数据类型:number、string、object、Boolean、null、undefinedstring: 由单引号或双引号来说明,如"string"number:什么整数啊浮点数啊都叫数字,你懂的~Boolean: 就是true和false啦undefined:未定义,就是你创建一个变量后却没给它赋值~null: 故名思久,null就是没有,什么也不表示object: 这个我也很难解释的说。就是除了上面五种之外的类型--------------------上面的都是浮云,下面的才是神马------------------------------数据类型判断之 typeoftypeof可以解决大部分的数据类型判断,是一个一元运算,放在一个运算值之前,其返回值为一个字符串,该字符串说明运算数的类型,所以判断某个是否为String类型,可以直接 if(typeof(你的值) == "string"){}以下是各种数据类型返回结果:复制代码var a="string"; console.log(a); //stringvar a=1; console.log(a); //numbervar a=false; console.log(a); //booleanvar a; console.log(typeof a); //undfinedvar a = null; console.log(typeof a); //objectvar a = document; console.log(typeof a); //objectvar a = []; console.log(a); //objectvar a = function(){}; console.log(typeof a) //function 除了可以判断数据类型还可以判断function类型复制代码这样一来就很明显了,除了前四个类型外,null、对象、数组返回的都是object类型;对于函数类型返回的则是function,再比如typeof(Date),typeof(eval)等。然后这里就可以再引申出另一个灰常热门并且解决方法已普遍存在的问题,如何判断数据是个数组类型?---------------------------------------其实这才是我的目的,咩~----------------------------------------------js判断数组类型的方法 方法一之 instanceofinstance,故名思义,实例,例子,所以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/4171630http://my.oschina.net/sfm/blog/33197http://openxtiger.iteye.com/blog/1893378function 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=http://www.mamicode.com/"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代码:1234/* 检测小屏幕- */@media only screen and (max-width: 760px) { #some-element { display: none; }} js代码:123456789$( document ).ready(function() { var isMobile = false;//默认是pc端 if( $(‘#some-element‘).css(‘display‘)==‘none‘) { is_mobile = true; } if (isMobile == true) { //对移动端进行处理 }});方法二、通过navigator.userAgent字符串检测思路:Navigator对象包含有关浏览器的信息,通过检测userAgent字符串,然后使用正则表达式进行匹配,我们自然就能知道用户是否在使用移动端的浏览器啦先上个简化版的,意思意思下12345678var isMobile = false;// 检测userAgentif( /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发现一哥们检测得更加全面牛逼:12345678var isMobile = false;//默认PC端// 检测userAgentif(/(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代码实现如下:12345var 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代码实现:1234567891011var 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=http://www.mamicode.com/"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=http://www.mamicode.com/"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 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。先来一个栗子:1234567891011function 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 方法:12345banana = { color: "yellow"}apple.say.call(banana); //My color is yellowapple.say.apply(banana); //My color is yellow所以,可以看出 call 和 apply 是为了动态改变 this 而出现的,当一个 object 没有某个方法(本栗子中banana没有say方法),但是其他的有(本栗子中apple有say方法),我们可以借助call或apply用其它对象的方法来操作。 apply、call 的区别 对于 apply、call 二者而言,作用完全一样,只是接受参数的方式不太一样。例如,有一个函数定义如下:123var func = function(arg1, arg2) {};就可以通过如下方式来调用:12func.call(this, arg1, arg2);func.apply(this, [arg1, arg2])其中 this 是你想指定的上下文,他可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。 JavaScript 中,某个函数的参数数量是不固定的,因此要说适用条件的话,当你的参数是明确知道数量时用 call 。而不确定的时候用 apply,然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments 这个数组来遍历所有的参数。为了巩固加深记忆,下面列举一些常用用法:1、数组之间追加1234var 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、获取数组中的最大值和最小值123var numbers = [5, 458 , 120 , -215 ]; var maxInNumbers = Math.max.apply(Math, numbers), //458 maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458number 本身没有 max 方法,但是 Math 有,我们就可以借助 call 或者 apply 使用其方法。3、验证是否是数组(前提是toString()方法没有被重写过)123functionisArray(obj){ return Object.prototype.toString.call(obj) === ‘[object Array]‘ ;}4、类(伪)数组使用数组方法1var 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 方法,常见的解决方法是:12345function log(msg) { console.log(msg);}log(1); //1log(1,2); //1上面方法可以解决最基本的需求,但是当传入参数的个数是不确定的时候,上面的方法就失效了,这个时候就可以考虑使用 apply 或者 call,注意这里传入多少个参数是不确定的,所以使用apply是最好的,方法如下:12345function log(){ console.log.apply(console, arguments);};log(1); //1log(1,2); //1 2接下来的要求是给每一个 log 消息添加一个"(app)"的前辍,比如:1log("hello world"); //(app)hello world该怎么做比较优雅呢?这个时候需要想到arguments参数是个伪数组,通过 Array.prototype.slice.call 转化为标准数组,再使用数组方法unshift,像这样:123456function 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 ,这样我们可以在改变了上下文之后继续引用到它。 像这样:12345678910var 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() 可以更加优雅的解决这个问题:123456789var 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 对象。再来一个简单的栗子:123456789var bar = function(){console.log(this.x);}var foo = {x:3}bar(); // undefinedvar func = bar.bind(foo);func(); // 3这里我们创建了一个新的函数 func,当使用 bind() 创建一个绑定函数之后,它被执行的时候,它的 this 会被设置成 foo , 而不是像我们调用 bar() 时的全局作用域。有个有趣的问题,如果连续 bind() 两次,亦或者是连续 bind() 三次那么输出的值是什么呢?像这样:12345678910111213141516