JS知识点搜集
一 语法糖
简易
$()
querySelector函数接受一个合法的css选择器来选择元素,与jQ几乎无差别;
当然有一些选择器,比如:head伪类是不支持的.//ES6版 //单个元素选择 var $ =(query,con)=> (con || document).querySelector(query) //选择一组元素 var $$=(query,con)=> (con || document).querySelectorAll(query) //兼容写法 //单个元素选择 function $ (query,con) {return (con || document).querySelector(query);} //选择一组元素 function $$(query,con) {return (con || document).querySelectorAll(query);}
我的
ready()
有时我们需要等DOM加载完后才执行function。jQuery有ready方法,我们同样可以通过
DOMContentLoaded
事件来拥有自己的ready方法。// 定义 function ready (fn) { document.addEventListener('DOMContentLoaded', fn, false) } // 使用 ready(function (){/*......*/});
函数将在DOM元素加载完毕后立刻执行,但不包括image|audio|video的加载。
最佳实践: 把
<script>
放在body的最后也是简单可行的方法.简写事件绑定
Element.prototype.on = Element.prototype.addEventListener; Element.prototype.off = Element.prototype.removeEventListener;
重复字符串(如abc=>abcabcabc)
// ES6 "abc".repeat(3) //"abcabcabc" // 兼容 String.prototype.repeat = function(n){ return Array.prototype.join.call({length:n+1},this) }
之所以要创建带length属性的对象,
是因为调用数组原型方法时,必须是一个类数组对象,
而类数组对象的条件就是length为非负整数,
不新建数组,而是用拥有length属性的对象替代,
然后调用数组的join方法,当n较大时性能提升很大再改进(n大,且多次调用的时候用)
String.prototype.repeat = (function(){ join=Array.prototype.join,obj={}; return function(target,n){ obj.length=n+1; return join.call(obj,target); } })();
利用闭包将对象和join方法缓存起来,
不用每次调用该方法都新建对象和寻找方法,
可以减少多次调用的内存开销和一点时间.类数组转数组
//ES6 Array.from(arr) //兼容写法 Array.prototype.slice.call(arr)
二 技巧
- 倒序遍历数组可提高一点效率, 因为i只需要与0比较
用对象属性匹配模拟switch语句
var key = 1,cases = {1: todoA,2: todoB,3: todoC} console.log(cases[key]) //输出为todoA
遍历一个obj的属性到数组
var a=[]; for(a[a.length] in obj); return a;
按照Object的属性排序
//把3个对象按照score排序。 var test= [ {id:1,name:"a",score:22}, {id:2,name:"b",score:33}, {id:3,name:"c",score:44} ] result = test.sort(function(a,b){ return a.score> b.score?1:-1; });
批量获取随机数
// 获取五个无符号8位整数 var uInt8Arr = new Uint8Array(5); console.log(window.crypto.getRandomValues(uInt8Arr));
随机字符串
Math.random().toString(16).substring(2); //0~f 14位 Math.random().toString(36).substring(2); //0~z 11位
获取元素最终样式
function attrStyle(elem,attr){ //如果在style下有属性则优先获取,否则用getComputedStyle //用getComputedStyle获取属性,是采用原格式(text-align)获取的,故要转换一下 return elem.style[attr] || getComputedStyle(elem,null)[attr.replace(/([A-Z])/g,'-$1').toLowerCase()]; }
获取CSS样式表文档
document.styleSheets[0].rules[0].style.width = "1024px"
原生AJAX
function loadXMLDoc() { var ajax = new XMLHttpRequest; ajax.onreadystatechange = function { if (ajax.readyState == 4){ switch(ajax.status){ case 200: alert("success"); break; case 400: alert("error 400"); break; default: alert("something broke") }}} ajax.open("GET", "test.html", true); ajax.send; }
匿名函数调用自身
function(){ // doSomething... arguments.callee() }
可用于匿名函数递归
访问剪贴板
// dataTransfer event.dataTransfer.setData("URL", oImage.src); sImageURL = event.dataTransfer.getData("URL") // 普通访问(ie) window.clipboardData.setData("Text",oSource.innerText); window.clipboardData.getData("Text");
判断键值
document.onkeydown = function(e){ var key=event.keyCode; realkey = { 32: '空格', 13: '回车', 27: 'Esc', 16: 'Shift', 17: 'Ctrl', 18: 'Alt' }[key] || String.fromCharCode(key) alert('键值:'+key+'\n'+'实际键为'+realkey); }
判断一个变量是否真的为NaN
NaN是JS中唯一不等于自己的值,因此NaN !== NaN // true function isNaN(n){ return n !== n ? true : false; }
鸭子类型
并不是所有时候都需要继承,继承也不是完美的,有时候会创造比他能解决的更多的问题,特别是当层次关系没那么明显的时候,
这时候应该多用结构类型(又叫鸭子类型),用结构类型设计灵活的对象接口的时候,不需要返回类的实例,而是直接返回对象,对象具备预期的方法和属性,比如:SomeObj.someWidget = function(opts) { return { a: blabla, b: function() { //... }, c: blabla } }
三 事件
捕获全局异常:
window.onerror
, 可用于调试.退出前事件:
onbeforeunload
, 可用于确认退出等.动画结束后事件
// webkit el.addEventListener("webkitTransitionEnd", transitionEnded); // W3C el.addEventListener("transitionend", transitionEnded);
可用于动画后清理变换
屏蔽右键
document.oncontextmenu= function(){return false}
防复制
element.onselectstart = function(){return false}
防粘贴
element.onpaste = function(){return false}
关闭输入法
function disableIME = function(){ this.style.imeMode='disabled' } element.addEventListener("focus",disableIME,false)
四 参量
是否ie
var isIE = /*@cc_on !@*/false;
判断系统
// navigator.platform -> "Win32" | "MacPPC" | "Linuxi586" | ... var isWin = false, isMac = false, isLinux = false, isOtherSystem = false; // 用法 var pt = navigator.platform if (pt.indexOf('Win') === 0) { isWin = true } else if(pt.indexOf('Mac') === 0){ isMac = true } else if(pt.indexOf('Linux') ===0){ isLinux = true } else{ isOtherSystem = true };
在线状态
var isOnline = navigator.onLine
CSS风格媒体查询
mql = window.matchMedia('(min-width: 400px)') if (mql.matches) { /* 宽度大于400px */ } else { /* 宽度小于400px */ }
五 注意
注意行尾分号的省略
JS具备自动插入分号的能力,但有几个情况要注意:
当开头为
(,[,+,-,/
的时候,上一行不会自动插入分号,例如下式会解析为a=b(f())
:a=b (f());
还有一些情况,尽管不会出现解析错误,JS仍然会强制插入分号,这就是所谓的JS语法限制产生式。它不允许在两个字符间出现换行,最危险的就是return语句,如:
return {}; // 会被强制插入而成为 return; {};
类似的还有:
- throw语句
- 带有显示标签的break或者continue语句
- 后置自增或自减运算符
==
与===
的差异
js有两个表示”相等”的运算符:== 和 ===
“==”运算符在比较时会隐式转换变量类型,因此两种符号并不完全一样:0 == ''// true 1 == true // true 2 == true // false 0 == '0' // true false == 'false' // false false == '0' // true " \t\r\n " == 0 // true