Open WhiteYin opened 6 years ago
eslint-standard规范
这是一个以standard标准规范化js代码的工具,同时可以使用eslint设置该标准。比较方便易用。目前npm等网站都在使用。
JavaScript 中的继承:ES3、ES5 和 ES6 - 天方夜谈
不同阶段JS规范下的对象继承实现方法,前两个问题在于原型链的传递方式。
javascript 连等赋值问题
解析器在接受到 a = a.x = {n:2} 这样的语句后,会这样做:
找到 a 和 a.x 的指针。如果已有指针,那么不改变它。如果没有指针,即那个变量还没被申明,那么就创建它,指向 undefined。
a 是有指针的,指向 {n:1};a.x 是没有指针的,所以创建它,指向 undefined。
然后把上面找到的指针,都指向最右侧赋的那个值,即 {n:2}。
JavaScript 运行机制详解:再谈Event Loop
JS事件处理机制是将同步任务放在事件栈中,异步任务放在事件队列里。当事件栈空,读取事件队列,将事件放入事件栈中,循环处理。定时任务在事件队列中,只有定时时间到才被处理。
setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,也就是说,尽可能早得执行。它在"任务队列"的尾部添加一个事件,因此要等到同步任务和"任务队列"现有的事件都处理完,才会得到执行。
HTML5标准规定了setTimeout()的第二个参数的最小值(最短间隔),不得低于4毫秒,如果低于这个值,就会自动增加。
Pinterest的PWA实践
需求 :Pinterest 发现他们原来旧而慢的网络体验仅能将 1% 的用户转化为注册、登录或下载 app 作为本地应用使用的用户。为了提升转化率,它们开始投资PWA应用。
效果 :与旧移动端网页的体验相比,新移动端网页用户的使用时间增加了 40%,用户生成的广告收益增加了 44%,并且核心业务增长了 60%。
关于let变量是否提升的讨论
getify对变量提升的定义是要同时具有2点:既要在运行前的编译阶段将声明与作用域绑定,又要能够在作用域中的任何位置获得对变量引用。var关键字声明的变量2点都满足,因此有变量提升;而let和const关键字声明的变量只满足第一点,因为临时死区的原因无法在任何位置时获得引用,因此没有变量提升。
JS 判断CSS3 动画结束
监听animationend事件。
margin的百分比值是相对于包含块的宽度来定。
var a = [];
// 方法一
Object.prototype.toString.apply(a)==='[object Array]';
// 方法二
a.constructor === Array;
判断是否为数组。
label的for属性值要与后面对应的input标签id属性值相同
<label for='Name'>Number:</label>
<input type=“ text “ name='Name' id='Name'/>
重构、回流
浏览器的重构指的是改变每个元素外观时所触发的浏览器行为,比如颜色,背景等样式发生了改变而进行的重新构造新外观的过程。重构不会引发页面的重新布局,不一定伴随着回流,回流指的是浏览器为了重新渲染页面的需要而进行的重新计算元素的几何大小和位置的,他的开销是非常大的,回流可以理解为渲染树需要重新进行计算,一般最好触发元素的重构,避免元素的回流。
比如通过通过添加类来添加css样式,而不是直接在DOM上设置,当需要操作某一块元素时候,最好使其脱离文档流,这样就不会引起回流了,比如设置position:absolute或者fixed,或者display:none,等操作结束后在显示。
启动本地服务器:http-server
$ npm i --save-dev http-server
$ http-server
默认8080端口,使用-p 4000可以切换端口。
剖析主流网站实现效果原理
包括知乎内容延时显示、导航栏动态底部、元素进入视口开始动画。
今天遇到个小问题,css中的计算属性calc(100%-200px);语句是无效的,我原本以为是单位不同导致的。结果是因为-减号两边要加空格,写成calc(100% - 200px);
涨姿势了。
JavaScript中,所有数字都是64位的浮点数,在某些运算中会将浮点数强制转换成32位的整数。
parseInt()方法在转换数字为整数时会出现错误情况:
parseInt(10000000000000000.5);//1
parseInt(0.0000000000000003);//3
这是因为位数过多时会自动转成科学计数法相当于:
parseInt(1e+22);
parseInt(3e-16);
好像科学计数法在超过20位后parseInt把它当成字符串,识别到不是数字的e就结束了。
JS原生的两种处理base64方法:
btoa():将一个base64编码过的字符串转换成ascii字符串或二进制数据,
atob():对 base64 编码过的字符串进行解码。
如果要转换的字符串中有中文,需要特殊处理:
function b64Encode(str) {
return btoa(encodeURIComponent(str));
}
function b64Decode(str) {
return decodeURIComponent(atob(str));
}
b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"
JS 事件循环的一些细节 JS事件循环中最小延迟时间为1ms,并不是HTML规范定的4ms,规范受到了浏览器实现的影响。
在安卓和IOS的原生应用中,字体大小往往不会随着设备屏幕大小的改变而改变。因此,现在移动端HTML页面中使用的rem单位并不是完美方案。在设计中应该尽量避免。
rem不是神农草
个人觉得应该多考虑细节,rem方案虽然简单但是细节处理并不好。至少在保持字体大小一致方面做的并不好。
URLSearchParams
URLSearchParams API可以用来处理url中的查询字段,如果不支持可以使用第三方库。
web storage API 在对sessionStorage或localStorage操作时会触发storage事件。当同时打开同一域名下的不同网页,其中一个网页修改storage时,其他网页会触发storage事件,而该页面不会。从某种程度上讲,可以实现多窗口通信。
storage事件的回调函数会有一个event对象,包括4个属性:
根据大漠的博客,手机淘宝在移动端适配中使用的方案从flexible.js到vw再到viewport-units-buggyfill,可以看出适配需要处理的问题在于:
思考为什么在移动端retina屏幕下,1px的边框会看上去是2px?
首先需要知道设备独立像素与屏幕物理像素的概念。
物理像素,指的是屏幕中的像素数。这个是我们前端开发无法控制的。
设备独立像素,有代表性的就是css中的像素单位。拿这个来举例,我们设置样式border:1px solid
,这里的1px就是1独立像素。
从用户的视角来说,只能看到物理像素,并不能看到设备独立像素。在电脑或非retina屏幕下物理像素与独立像素是1:1的关系。但是在retina屏幕下,往往是2:1甚至是3:1的情况。这个比例我们用dpr(device pixel ratio)来表示。公式如下:
dpr = 物理像素 / 设备独立像素
(适用于x或y轴方向)
这个公式,就像电阻的定义式一样,并不能说明dpr是由右侧两个变量决定。
举个例子,当手机的dpr为2时,一个css像素在屏幕上应该是2x2=4个物理像素,也就是宽是两倍,长也是两倍。
设置1px边框时,由于dpr=2,因此高度也就是粗细会显示成2px。这里的2px使用的是物理像素单位。
要解决这个问题,有两种方法:
如何记忆DOM模型的七种节点?
获取元素节点:JS原生和jQuery方法的区别。
首先,使用JS获取所有的h3元素:var byJS = document.getElementsByTagName("h3");
,假设返回由10个h3元素组成的NodeList对象。
然后,jQuery使用var byJquery = $("h3")
获取10个NodeList对象。
如果我们新增一个h3节点,则byJS会动态返回11个,而byJquery仍是10个。
在IOS浏览器中,设置了readonly的input输入框仍会获得焦点,但键盘只会弹出顶部一小块。 这时可以设置让其在获取焦点时失去焦点。这种方法比disabled方法好在仍然可以触发click事件。
DocumentFragment节点可以用来创建独立的DOM树,并且操作它比操作真正的文档DOM要快。因此在插入一堆新的节点时可以先添加在DocumentFragment中。当DocumentFragment节点被当作appendChild或是insertBefore时,只会将其内部的子节点插入进DOM,其本身会变成一个空节点。相当于一桶水向盆里倒吧。
JSON.stringify()方法在处理字符串时会返回带有双引号的字符串:
JSON.stringify("123");//""123""
JSON.stringify('123');//""123"",即使使用单引号,返回结果也会转成双引号
JSON.stringify(123);//"123",转成正常字符串
IE浏览器和现代浏览器添加事件的方法是不一样的,要兼容的话需要修改:
/**
* ele:节点,type:事件类型,fn:回调函数,capture:捕获
*/
function addEvent(ele,type,fn,capture){
if(window.addEventListener){
ele.addEventListener(type,function(e){
fn.call(ele,e);
},capture);
}else if(window.attchEvent){
ele.attchEvent("on"+type,function(e){
fn.call(ele,e);
})
}
};
注意要绑定fn的this到ele节点上。
高阶函数的定义:
箭头函数中的this指向上一层作用域。使用call或apply并不会改变this的值。
JS的堆栈概念与使用的搜索引擎有关。 SG 数据类型存放在堆还是栈?
深拷贝的算法步骤:
function deepClone(source){
if(!source && typeof source !== 'object'){
throw new Error('error arguments', 'shallowClone');
}
var targetObj = source.constructor === Array ? [] : {};
for(var keys in source){
if(source.hasOwnProperty(keys)){
if(source[keys] && typeof source[keys] === 'object'){
targetObj[keys] = source[keys].constructor === Array ? [] : {};
targetObj[keys] = deepClone(source[keys]); //递归
}else{
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}
使用JS修改元素的style属性时,一定要记得加上单位!而且值是字符串。
在ES6中,可以在块级作用域里声明函数。这在ES5中是非法的。
console.log(0,x);
if(true){
function x(){
console.log("123");
}
}
console.log(1,x);
输出:
0 undefined
1 function....
for value of和for key in有什么区别?
createDocumentFragment处理大量数据
使用JS为节点设置浮动时,可以使用NODE.style.float,但是在低版本浏览器中,这个float属性并不存在。可以用一种兼容性代码:
if(IE){
NODE.style.styleFloat = "";
}else{
NODE.style.cssFloat = "";
}
最好一直使用这种方法。
<script src="path/to/myModule.js" defer></script>
<script src="path/to/myModule.js" async></script>
defer与async的区别是:defer要等到整个页面在内存中正常渲染结束(DOM 结构完全生成,以及其他脚本执行完成),才会执行;async一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。一句话,defer是“渲染完再执行”,async是“下载完就执行”。另外,如果有多个defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。
bug分支
工作区和暂存区是一个公开的工作台,任何分支都会用到,并能看到工作台上最新的内容,只要在工作区、暂存区的改动未能够提交到某一个版本库(分支)中,那么在任何一个分支下都可以看得到这个工作区、暂存区的最新实时改动。
使用git stash就可以将暂存区的修改藏匿起来,使整个工作台看起来都是干净的。所以要清理整个工作台,那么前提是必须先将工作区的内容都add到暂存区中去。之后在干净的工作台上可以做另外一件紧急事件与藏匿起来的内容是完全独立的
Node 定时器详解 由于setTimeout在 timers 阶段执行,而setImmediate在 check 阶段执行。所以,setTimeout会早于setImmediate完成。
git图像日志简写:
git config --global alias.glog "log --graph --oneline --abbrev-commit"
github设置二步验证后,需要生成自己的access token,然后设置密码为这个token。这样push时就不用输入密码,并且也不会失败。
setInterval有两个缺点:
使用setInterval时,某些间隔会被跳过; 可能多个定时器会连续执行
呀~难得看到老乡同行,加个友链互相学习喽~~
https://whiteyin.github.io/notes/