2021-05-16

Javascript 底层知识

Javascript 重点知识篇;

此文主旨:javascript中常见'重点'易错'知识'以及一些算法(去重~排序).....持续更新中···

window.onload和$(document).ready()的区别

window.onload: 用0级事件绑定·只能绑定一个函数-是在页面中包含图片在内的所有元素全部加载完成后再执行

$(document).ready()用2级事件绑定的 监听DOMContentLoaded事件实现的,可以绑定多个函数:页面DOM结构渲染完成后执行

因此$(document).ready()执行快于window.onload执行;

数组去重

let ary=[35,"aa",56,"aa","35","56","23"]复制代码

1.es6数据结构Set

let unique = new Set(ary);  console.log(Array.from(unique));复制代码

2.使用push()

let ary1=[];for(let i=0;i

3.使用splice()

let len = ary.length;for (let i = 0; i < len; i++) {  for (let j = i + 1; j < len; j++) {    if (ary[i] == ary[j]) {      ary.splice(i, 1);      len--;      j--;    }  }}console.log(ary);复制代码

JS同步和异步【微任务,宏任务】

单线程异步操作

Js是一个单线程的。它一次只能做一件事情,当我们把异步放在webAPI中去监听的时候,如果达到可执行状态,就把他放到微任务或宏任务 此时主线程继续渲染同步的js代码

同步和异步执行的优先级

在同步代码还没执行完前,执行完之前[主线程还没有闲下来] 就算某个异步任务可以执行了,也不会立即执行,而是把它放在 EventQueue 中排队等待执行,只有同步代码执行完后才会执行异步任务;

EventQueue事件循环机制··重点

同步任务完成后,主线程空闲下来后,会去 EventQueue 中,查找能够执行的异步任务,会把放在栈内存中,让主线程去执行[此时主线程又开始执行];等到这个异步执行完,再去EventQueue中找其余的异步任务,拿过来执行

微任务 宏任务

如果有可执行的异步微任务,永远都是先执行微任务。可执行的微任务没有了,再去找异步的宏任务; 相同等级的谁先放进来的,就先执行谁;

call,apply,bind 你真的理解了吗?

语法

fun.call(box,"xxx","xxx")fun.apply(box,["xxx","xxx")fun.bind(box,"xxx","xxx")

new 具体做了什么事

创建了一个实例对象box

让this指向这个实力对象

foo__proto__=box、prototype

我们可以通过box.prototype给foo增加属性

function box(name, age){    this.name = name;    this.age = age;}box.prototype.baby = function (){ // 切记不要用箭头函数 否则this指向全局作用域    console.log(this.name);}const foo = new box('哈哈',123);console.log(foo);=> box {name: "哈哈", age: 123}foo.baby(); =>哈哈console.log(foo.name); =>哈哈

this的指向谁 apply、call、bind如何改变this

普通函数执行this指向

看你所调用的方法执行前面有没有 点(.)如果有· 点前面是谁this就指向谁 如果没有· 就是指向window 特殊情况:如果是在严格模式下就是undefined;箭头函数没有this和prototype

构造函数指向this指向

this指向new出来的那个实例对象

apply、call、bind共同点

apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;

apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文

apply 、 call 、bind 三者都可以利用后续参数传参

apply、call、bind不同点

call改变this指向并执行 func.call(this, arg1, arg2)当传参的参数量不确定时,函数内部也可以通过 arguments 这个数组来遍历所有的参数。

apply改变this指向 把参数放在数组里。例如:func.apply(this, [arg1, arg2])。

bind改变this指向 但是不执行返回对应函数,便于稍后调用

数据类型的检测

typeof 检测

typeof[value]=>首先它是个字符串,字符串中包含着对应的数据类型;

局限性:typeof检测对象类型值,除了可执行{函数}可以检测出来时“function”其余都是“object”

typeof检测一个未被声明的变量,结果是undefined而不会报错,[基于let在后面声明的则会报错]暂时性死区

null的特殊性:typeof检测数据类型是按照计算机底层存储的二进制值来检测的,他认为以·000·开头的都是对象 而碰巧null全是0 所以检测null是对象 其实它是个基本数据类型

instanceof 检测

[value]instanceof[Ctor]=>true/false

instanceof 是临时用来检测据类型,它的本意是用来检测当前实力属不属于这个类;

好处:细分对象类型值 但是不能因为结果是true 就说他是标准普通对象

弊端:不能检测原始类型值,只能检测原始值对应的对象格式实例 原型链在ES6语法中可以肆意改动的

function Fn(){}Fn.prototype=Array.prototype;let f=new Fn;console.log(f instanceof Array );  =>true

let ary=[34,34]class Fn{    static [Symbol.hasInstance](obj){        if(Array.isArray(obj)) return true;    }}console.log(ary instanceof Fn); =>true

原理:通过__proto__找原型链上的prototype,如果[Ctor]出现在原型链上,就返回true,如果一直到Object.prototype都没有出现,就返回false

Object.prototype.toString.call([value]);

它是js检测中唯一一个检测数据类型没有任何瑕疵的;

返回值:[object Number/Boolen/BigInt/String/Array/Math...]

大部分内置类上都有toString属性一般都是转成字字符串,但是 Object.prototype.toString是检测数据类型的,返回值包含自己所属的构造函数信息[这里边的String是调用Object原型上String]所以这里的String是检测数据类型的

([]).toString是调用数组里边的String;这里的String是转化成字符串

Object.prototype.toString.call()改变this指向

结束语:

如有错误,欢迎指正 谢谢

你可能感兴趣的:(2021-05-16)