引伸:
用setTimeout()方法来模拟setInterval()与setInterval()之间的什么区别?node
精确度问题?数组
微任务和宏任务问题?promise
macro-task(宏任务):包括总体代码script,setTimeout,setInterval浏览器
micro-task(微任务):Promise,process.nextTick,相似node.js版的"setTimeout",在事件循环的下一次循环中调用 callback 回调函数。dom
同步>异步异步
主任务>微任务>宏任务函数
console.log('script start'); setTimeout(function() { console.log('setTimeout'); }, 0); Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); }); console.log('script end');
结果:script start, script end, promise1, promise2, setTimeoutcode
console.log('1'); setTimeout(function() { console.log('2'); process.nextTick(function() { console.log('3'); }) new Promise(function(resolve) { console.log('4'); resolve(); }).then(function() { console.log('5') }) }) process.nextTick(function() { console.log('6'); }) new Promise(function(resolve) { console.log('7'); resolve(); }).then(function() { console.log('8') }) setTimeout(function() { console.log('9'); process.nextTick(function() { console.log('10'); }) new Promise(function(resolve) { console.log('11'); resolve(); }).then(function() { console.log('12') }) })
结果:同步任务1,7,微任务nextTick和promise.then()6,8,宏任务setTimeout,里面做为一个新的内容2,4,3,5,9,11,10,12对象
// 使用直接量 var obj = { name: 'zzz', age: 24, }; var arr = ["nicholas", 50, true]; // 不使用直接量 var obj = new Object(); obj.name = 'zzz'; obj.age = 24; var arr = new Array(); arr[0] = "nicholas"; arr[1] = 50; arr[2] = true;
最多见的重复工做就是浏览器探测,基于浏览器的功能做分支判断致使产生大量代码。生命周期
一个页面假若有屡次调用 addHandler 函数添加事件,那么每次浏览器都会作判断,来执行哪个方法。事实上每次的判断结果都是同样的。有几种方法能够避免。
function addHandler(target, eventType, handler) { if (target.addEventListener) { // DOM2 Events target.addEventListener(eventType, handler, false); } else { // IE target.attachEvent('on' + eventType, handler); } } addHandler(document, 'click', function() { console.log('hello world'); });
方法一:延迟加载
延迟加载,也称惰性加载,惰性载入等。延迟加载意味着在信息被使用前不会作任何操做:
function addHandler(target, eventType, handler) { if (target.addEventListener) { // DOM2 Events addHandler = function(target, eventType, handler) { target.addEventListener(eventType, handler, false); }; } else { // IE addHandler = function(target, eventType, handler) { target.attachEvent('on' + eventType, handler); }; } addHandler(target, eventType, handler); } addHandler(document, 'click', function() { console.log('hello world'); }); addHandler(window, 'keydown', function() { console.log('key down'); }); //方法在第一个调用的时候,会作一次判断决定使用哪一种方法去绑定时间处理器,而后原始addHandler会被新的addHandler函数覆盖,最后一步调用新的函数,并传入原始参数。随后每次调用addHandler()都不会再作检测,由于检测代码已经被新的函数覆盖。 //第一次总会消耗较长的时间,由于需先检测再调用完成任务。以后会变快。
方法二:条件预加载
条件预加载会在脚本加载期间提早检测,而不会等到函数被调用:
var addHandler = document.addEventListener ? function(target, eventType, handler) { target.addEventListener(eventType, handler, false); }: function(target, eventType, handler) { target.attachEvent('on' + eventType, handler); }; addHandler(document, 'click', function() { console.log('hello world'); }); //这个例子就是先检查 addEventListener()是否存在,而后根据结果指定函数。 //条件预加载确保全部函数调用消耗的时间相同,代价是须要在脚本加载时就检测。适用于一个函数立刻就要被用到,而且在整个页面的生命周期中频繁出现的场景。
特别是数学运算。内置Math对象的方法。dom运算,querySelector()和querySelectorAll()
Math 对象用于执行数学任务。
使用 Math 的属性和方法的语法:
var pi_value=Math.PI; var sqrt_value=Math.sqrt(15);
Math 对象并不像 Date 和 String 那样是对象的类,所以没有构造函数 Math(),像 Math.sin() 这样的函数只是函数,不是某个对象的方法。您无需建立它,经过把 Math 做为对象使用就能够调用其全部属性和方法。
https://www.w3school.com.cn/j...