前端基础知识
- 在js里面,我们在转换其它类型为布尔类型的时候,只有6个情况是false
var res1 = Boolean(0);
console.log(res1); //输出false
var res2 = Boolean('');
console.log(res2); //输出false
var res3 = Boolean(NaN);
console.log(res3); //输出false
var res4 = Boolean(undefined);
console.log(res4); //输出false
var res5 = Boolean(null);
console.log(res5); //输出false
var res6 = Boolean(false);
console.log(res6); //输出false
-
js访问一个变量或者函数先在自己作用域查找,查找不到则不断向父级作用域查找,直到全局作用域,如果全局作用域也查不到,就会报错
var a = 10; function f1(){ console.log(a); } f1();// 变量a在函数外定义,可以在函数内使用 function f2(){ var b = 20; } console.log(b); // 变量b在函数内定义,在函数外无法访问,报错: b is not defined
-
js中,代码执行之前,会先进行一次预解析。就是在执行代码之前,把代码中的通过
var
方式的变量声明和函数声明,提升到当前作用域的最顶端,而变量的赋值和函数的调用还在原来的位置。
fn();// 正常执行
function fn(){
console.log(1);
}
fn(); // 正常执行
f2();// 报错 : f2 is not a function
var f2 = function(){
console.log(2);
}
// function 关键字定义的函数,可以在定义之前使用,函数表达式的不行
-
DOM 是由节点(node)组成的、 常用两种类型的节点是文档节点(document)和 元素节点(element)
-
基本属性操作包括: href title id src className
-
表单属性操作常见:value type 特殊属性操作:disabled checked selected 都是布尔类型
-
自定义属性,约定data-xxx。 可以通过getAttribute获取属性,setAttribute设置属性。也可通过dataSet.xx设置和读取属性。
-
事件处理函数中的
this
指向被添加处理函数的对象,和event.currentTarget等价,和 event.target可能不是一个对象 -
可以通过document.querySelector('css选择器'),获取一个元素
-
创建元素的三种方式:innerHtml, document.write, document.createElement
-
事件常用方法:event.stopPropagation()阻止冒泡;event.preventDefaut()取消默认行为
-
全屏出发的事件源:document
-
事件三个阶段捕获、目标、冒泡
-
DOMContentLoaded
事件在DOM结构构件完触发,load事件要在DOMContentLoaded事件出发后,媒体资源和css资源加载完后触发 -
键盘事件keypress不识别功能键,keyup和keydown不识别字母大小写
-
this一般指向调用他的对象。定时器回调函数中this指向window,构造函数中this指向构造函数实例,事件监听中this指向添加监听的对象
-
js分为同步任务和异步任务,异步任务包括:普通事件、资源加载、定时器、ajax请求。
执行任务的机制:先执行执行栈内的同步代码,异步任务放到任务队列,所有同步任务执行完毕,读取异步任务进入执行栈开始执行
微任务比宏任务优先级高
宏任务
任务名 | 浏览器 | Node |
---|---|---|
I/O |
✅ | ✅ |
setTimeout |
✅ | ✅ |
setInterval |
✅ | ✅ |
setImmediate |
❌ | ✅ |
requestAnimationFrame |
✅ | ❌ |
微任务
任务名 | 浏览器 | Node |
---|---|---|
process.nextTick | ❌ | ✅ |
MutationObserver | ✅ | ❌ |
Promise.then catch finally | ✅ | ✅ |
引自掘金作者:Jiasm
链接:https://juejin.im/post/5b73d7a6518825610072b42b
-
主线程不断重复获取任务执行任务就叫事件循环
-
函数可以这样定义
new Fucntion(参数1,参数2...,函数体字符串)
-
fn.call(this指向的对象, 参数1,参数2...)
-
fn.apply(this指向的对象, [参数1,参数2])
-
fn.bind(this指向的对象), 返回一个新函数接收fn原本的参数
-
高阶函数就是参数或者返回值是函数的函数
-
闭包就是有权访问另外一个函数作用域中变量的函数
function fn() {
let a = 'outter'
function fnInner() { // fnInner 就是个闭包
return a
}
return fnInner
}
- 查找一个对象的属性时,现在对象自身上查找,如未找到,就在自己的
__proto__
对象属性上找,如果还未找到就在__proto__
对象的__proto__
对象属性上找,知道找到或者__proto__
属性为null停止。这个过程叫顺着原型链一层层往上找。 - 每个对象都有一个
__proto__
属性
函数比普通对象多一个prototype
属性
(__proto__
属性) === (它的构造函数的prototype
属性)
prototype
属性也是个对象所以也满足上面的等式
Object.prototype.__proto__ === null
- 通过call实现继承,不能继承父类原型链上的属性
function Super(name) {
this.name = name
}
function Child(name) {
Super.call(this, name)
this.car = '婴儿车'
}
- 通过原型链和call继承,需要把资料原型链上的constructor属性指向子类构造函数
function Super(name) {
this.name = name
}
Super.prototype.type = 'big'
function Child(name) {
Super.call(this, name)
}
Child.prototype = new Super()
Child.prototype.constructor = Child
var c = new Child('baby');
console.log('name', c.name);
console.log('type', c.type);
- es6 通过class定义类,通过extends继承,constructor作为构造函数, super调用父类构造函数
let Foo = class {
constructor(name) {
this.name = name;
}
say() {
console.log('i am foo')
}
};
class Bar extends Foo {
constructor(name, type) {
super(name); // 调用父类的constructor(name)
this.type = type;
}
}
- es6类中没有变量提升
- js new 执行过程
- 开辟内存创建一个空的新对象
- 将this指向这个空对象
- 执行构造函数, 给对象添加属性和方法
- 返回这个对象(构造函数里可以不写return)
- let和const声明的变量都拥有块级作用域,且都没有变量提升
- 暂时性死区:只要块级作用域内有let或const声明的变量,这个变量就“绑定”到这个块级作用域上,不受外部影响
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError, 这个块级作用域被tmp占领了,不会再关心外面的tmp,在声明之前使用报错
let tmp;
}
- 对象解构
let {a, b} = {a: 1, b: 2}