Js流水账知识点

2019-03-15  本文已影响0人  许骁Charles

在学js的过程中,记录一些零碎的小知识,以便以后翻看。持续更新……
学习资料:JavaScript教程 以及 《你不知道的JavaScript》系列丛书

  1. localstorage:保存用户更改,可用于覆盖当前页面已修改的hash,避免浏览器刷新后更改信息丢失。(以后补充和cookie的区别)
  2. example.com/favicon.ico,favicon.ico用于获取当前网站的title图标
  3. 变量提升:JavaScript 引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting)。
console.log(a)      // undefined
var a = 1
  1. JavaScript 使用大括号,将多个相关的语句组合在一起,称为“区块”(block),对于var命令来说,JavaScript 的区块不构成单独的作用域(scope)。
{
  var a = 1;
}

a // 1

在区块外部,变量a依然有效,ES6为了改变这种现状,引入了let:

{
  let a = 1;
}

a // undefined
  1. 关于是否添加分号:尤雨溪的回答
    总结下来就是一句话:一行开头是括号或者方括号的时候加上分号就可以了,其他时候全部不需要。
  2. 如果存在多重循环,不带参数的break语句和continue语句都只针对最内层循环。
  3. 语句的前面有标签(label),用于跳转到程序的任意位置,通常与break语句和continue语句配合使用,跳出特定的循环或者代码块。
  4. 七大数据类型:
  1. 三种类型准换的方法:typeof,instanceof,Object.prototype.toString
var obj = { }, arr = [ ] 
typeof obj        // object
typeof arr        // object
arr instanceof Array        // true
obj instanceof Array        // false
typeof NaN        // number
typeof Ifinity        // number
typeof null        // object
function f(){}
typeof f        // function
  1. 隐式转换

数组或对象会先调用valueOf()获取原始值,然后调用toString()转化成字符串,然后调用Number()转成数字,Boolean类型也是调用Number()转化成数字。
参考:js面试题大坑——隐式类型转换

Number(null) // 0
5 + null // 5
Number(undefined) // NaN
5 + undefined // NaN

神代码:

(!(~+[])+{})[--[~+""][+[]]*[~+[]]+~~!+[]]+({}+[])[[~!+[]*~+[]]] = sb
  1. 如果 JavaScript 预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。转换规则是除了下面六个值被转为false,其他值都视为true。
  1. event.target 和 event.currentTaget的区别,以后整理为博客,先参考这篇

  2. typeof valueOf instanceof的用法,区别,输出结果博客总结

  3. js现阶段主要掌握用法:改变元素的class,比如添加和取消"active",具体的样式交给CSS

  4. 尽量不要用浏览器提供的API,容易出bug

  5. nextSibling找兄弟的时候:记住nodeType的1,3状态。1是元素,3是文字以及各种空格回车制表符。不过更常用nextElementSibling

  6. 记住常用DOM操作的API,出博客

  7. setInterval() clearInterval() setTimeout()

  8. 如果忘了使用new命令,直接调用构造函数会发生什么事?

这种情况下,构造函数就变成了普通函数,并不会生成实例对象。而且由于后面会说到的原因,this这时代表全局对象,将造成一些意想不到的结果。

  1. 运算符:見博客

  2. 当需要迅速先hide()再show()的时候,浏览器会自动合并这个操作,也就是忽略掉hide(),此时可以在hide()之后调用offset()来打断浏览器这一行为。因为offset()会计算当前CSS中涉及变量的偏移。

  3. 轮播图时,宽高在HTML写死的原因:作为图片站位符,防止图片加载不均匀发生重排(re-layout),重排时图片倒退,会降低效率,很耗内存。

这个手段常用于页面性能优化。

  1. 状态机的编程思想:

  2. 指导思想:HTML、CSS和JS:内容、样式和行为分离:

  1. .one():为元素添加一个事件处理,只执行一次。

  2. transitionend事件会在CSS transition结束后触发,无缝轮播中有用到。

  3. “点击别处消失”的实现方法:(遮蔽罩?)

(1)点击元素自身处理

(2)用jq封装好的

  1. dispatchEvent & fireEvent

  2. 如果是被点击的节点同时拥有捕获和冒泡,那么执行顺序和添加顺序一致;其他情况都是优先捕获。

mouseenter:鼠标进入一个节点时触发,进入子节点不会触发这个事件
mouseover:鼠标进入一个节点时触发,进入子节点会再一次触发这个事件
mouseout:鼠标离开一个节点时触发,离开父节点也会触发这个事件
mouseleave:鼠标离开一个节点时触发,离开父节点不会触发这个事件

  1. click事件指的是,用户在同一个位置先完成mousedown动作,再完成mouseup动作。因此,触发顺序是,mousedown首先触发,mouseup接着触发,click最后触发。

dblclick事件则会在mousedown、mouseup、click之后触发。

x, clientX, offsetX, pageX, screenX

(1)clientX、clientY
点击位置距离当前body可视区域的x,y坐标
(2)pageX、pageY
对于整个页面来说,包括了被卷去的body部分的长度
(3)screenX、screenY
点击位置距离当前电脑屏幕的x,y坐标
(4)offsetX、offsetY
相对于带有定位的父盒子的x,y坐标
MouseEvent.offsetX属性返回鼠标位置与目标节点左侧的padding边缘的水平距离(单位像素)
(5)x、y
和screenX、screenY一样

  1. 键盘事件由用户击打键盘触发,主要有keydown、keypress、keyup三个事件,它们都继承了KeyboardEvent接口。

鼠标的事件属性。
onclick
ondblclick
onmousedown
onmouseenter
onmouseleave
onmousemove
onmouseout
onmouseover
onmouseup
onwheel

键盘的事件属性。
onkeydown
onkeypress
onkeyup

焦点的事件属性。
onblur
onfocus

表单的事件属性。
oninput
onchange
onsubmit
onreset
oninvalid
onselect

触摸的事件属性。
ontouchcancel
ontouchend
ontouchmove
ontouchstart

拖动的事件属性分成两类:一类与被拖动元素相关,另一类与接收被拖动元素的容器元素相关。
被拖动元素的事件属性。
ondragstart:拖动开始
ondrag:拖动过程中,每隔几百毫秒触发一次
ondragend:拖动结束

接收被拖动元素的容器元素的事件属性。
ondragenter:被拖动元素进入容器元素。
ondragleave:被拖动元素离开容器元素。
ondragover:被拖动元素在容器元素上方,每隔几百毫秒触发一次。
ondrop:松开鼠标后,被拖动元素放入容器元素。

<dialog>对话框元素的事件属性。
oncancel
onclose

  1. 当需要响应式布局时,不要用img标签,用 div 的 background 来设置图片,而且还可以加个懒加载什么的
background: transparent url(...) no-repeat center;
background-size: cover;
  1. 固定比例div技巧:https://www.w3cplus.com/css/aspect-ratio.html

  2. display: flow-root; // 只有一个作用,触发BFC

  3. 为什么 let 和 const 不存在变量提升呢?

这是因为在编译阶段, 当遇到变量声明时, 编译器要么将它提升至作用域顶部(var 声明), 要么将它放到 临时死区(temporal dead zone, TDZ), 也就是用 let 或 const 声明的变量. 访问 TDZ 中的变量会触发运行时的错误, 只有执行过变量声明语句后, 变量才会从 TDZ 中移出, 这时才可访问.

下面这个例子你能不能全部答对.

typeof null; // 'object'
typeof []; // 'object'
typeof someStr; // 'undefined'
typeof str; // Uncaught ReferenceError: str is not defined
const str = 'Yancey';

第一个, 因为 null 根本上是一个指针, 所以会返回 'object'. 深层次一点, 不同的对象在底层都表示为二进制, 在 Javascript 中二进制前三位都为 0 的会被判断为 Object 类型, null 的二进制全为 0, 自然前三位也是 0, 所以执行 typeof 时会返回 'object'.

第二个想强调的是, typeof 判断一个引用类型的变量, 拿到的都是 'object', 因此该操作符无法正确辨别具体的类型, 如 Array 还是 RegExp.

第三个, 当 typeof 一个 未声明 的变量, 不会报错, 而是返回 'undefined'

第四个, str 先是存在于 TDZ, 上面说到访问 TDZ 中的变量会触发运行时的错误, 所以这段代码直接报错.

  1. javascript:void($={}) 使不能复制的页面可以复制(原理??)

  2. 浏览器渲染机制(reflow && repaint)

  3. flex布局中,对需要右对齐的元素设置margin-left: auto即可

  4. 图片居中HTML5:

  1. defer和async的区别

  2. Object.assign 方法可以很方便地一次向类添加多个方法。

  3. 类的内部所有定义的方法,都是不可枚举的(non-enumerable)。

class Point {
  constructor(x, y) {
    // ...
  }

  toString() {
    // ...
  }
}

Object.keys(Point.prototype)
// []
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]

上面代码中,toString 方法是 Point 类内部定义的方法,它是不可枚举的。这一点与 ES5 的行为不一致。

ES6 规定,在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例。

class A {
  constructor() {
    this.x = 1;
  }
  print() {
    console.log(this.x);
  }
}

class B extends A {
  constructor() {
    super();
    this.x = 2;
  }
  m() {
    super.print();
  }
}

let b = new B();
b.m() // 2

上面代码中,super.print()虽然调用的是A.prototype.print(),但是A.prototype.print()内部的this指向子类B的实例,导致输出的是2,而不是1。也就是说,实际上执行的是super.print.call(this)。

上一篇 下一篇

猜你喜欢

热点阅读