js必备知识点

108 阅读4分钟

js的this

this 的规则,但是可能会发生多个规则同时出现的情况, 这时 候不同的规则之间会根据优先级最高的来决定 this 最终指向哪里。

  • 首先, new 的方式优先级最高,

  • 接下来是 bind 这些函数,

  • 然后是

  • obj.foo () 这种调用方式,

  • 最后是 foo 这种调用方式,

  • 同时, 箭头函数的 this ⼀旦被绑定,就不会再被任何方式所改变

js运算符instaneof

instanceof 用于检测一个对象是否是某个构造函数的实例。它的工作原理是检查对象的原型链中是否包含构造函数的 prototype 属性。

具体来说,instanceof 的内部逻辑如下:

  1. 获取构造函数的 prototype 属性。
  2. 检查对象的原型链中是否包含该 prototype 对象。
  3. 如果包含,返回 true;否则返回 false。

注意:基本数据类型(undefined、boolean、number、string、symbol、bigint)在 JavaScript 中是值类型,而不是对象类型。它们没有原型链,因此无法通过 instanceof 来检测

构建函数构建属性

首先先来讲下 class , 其实在 JS 中并不存在类, class 只是语法糖,本质还是函数。

class Person {}
 Person instanceof Function // true
function Parent(value) {
 this.val = value;
}

Parent.prototype.getValue = function() {
 console.log(this.val);
};

const p = new Parent(42);
console.log(p.val); // 输出:42
p.getValue();

构造函数的 constructor 属性 每个对象的原型上都有一个 constructor 属性,它指向创建该对象的构造函数。

  • p.constructor 指向 Parent,表示 p 是通过 Parent 构造函数创建的。
  • p.proto.constructor 也指向 Parent,因为 p.proto 是 Parent.prototype,而 Parent.prototype.constructor 指向 Parent。
  • 注意:Function 是 Object 的子类型,不是构造函数关系,Function.proto==Object.proto

getValue

getValue 方法的作用是为所有通过 Parent 构造函数创建的实例提供一个共享的方法,用于访问或操作实例的属性。它通过原型链机制实现代码复用,节省内存,并封装逻辑。这种机制是 JavaScript 原型继承的核心特性之一。

getValue 方法可以访问实例的属性。在方法内部,this 指向调用该方法的实例,因此可以通过 this 访问实例的属。

js中 call、apply、bind方法

Parent.call(this, value) 是 JavaScript 中实现继承的一种常用方法。它用于在子类的构造函数中调用父类的构造函数,从而将父类的属性和方法传递给子类的实例。这种方法允许子类继承父类的属性和行为

  • call 方法用于在特定的上下文中调用一个函数,并传递参数
  • apply 方法与 call 类似,但它接受一个参数数组,而不是多个参数
  • bind 方法用于创建一个新函数,该函数的 this 值被永久绑定到指定的对象上。bind 不会立即调用函数,而是返回一个新的函数。
    • (场景:构造函数里面已经声明了this,但是在构造的实例函数的外部环境中用此this则会丢失指向,所以需要用bind(this)绑定this的指向)
手写call方法
Function.prototype.myCall = function(context) {
 if (typeof this !== 'function') {
 throw new TypeError( 'Error')
 }
 context = context || window
 context.fn = this
 const args = [...arguments].slice(1)
 const result = context.fn(...args)
 delete context.fn
 return result
 }
手写apply方法
Function.prototype.myApply = function(context) {
 if (typeof this !== 'function') {
 throw new TypeError( 'Error')
 }
 context = context || window
 context.fn = this
 let result
 // 处理参数和 call 有区别
if (arguments [1]) {
 result = context.fn(...arguments [1])
 } else {
 result = context.fn()
 }
 delete context.fn
 return result
 }
手写bind方法
Function.prototype.myBind = function (context) {
 if (typeof this !== 'function') {
 throw new TypeError( 'Error')
 }
 const _this = this
 const args = [...arguments].slice(1)
 // 返回⼀个函数
return function F() {
 // 因为返回了⼀个函数,我们可以 new F(),所以需要判断
if (this instanceof F) {
 26/166
 return new _this(...args, ...arguments)
 }
 return _this.apply(context, args.concat(...arguments))
     }
 }

ES Mmodule

ES Module 是原生实现的模块化方案,与 CommonJS 有以下⼏个区别

  1. CommonJS 支持动态导⼊,也就是 require(${path}/xx.js) ,后者目前不支持,但是 已有提案
  2. CommonJS 是同步导⼊, 因为用于服务端,文件都在本地, 同步导⼊即使卡住主线程影响 也不大。而后者是异步导⼊, 因为用于浏览器, 需要下载文件, 如果也采用同步导⼊会对 渲染有很大影响
  3. CommonJS 在导出时都是值拷贝,就算导出的值变了, 导入的值也不会改变,所以如果想 更新值,必须重新导入⼀次。但是 ES Module 采用实时绑定的方式, 导入导出的值都指 向同⼀个内存地址,所以导入值会跟随导出值变化
  4. ES Module 会编译成 require/exports 来执行的

Node Eventloop

Node 中的Eventloop Node 中的 Event loop 和浏览器中的不相同。 Node 的 Event loop 分为 6 个阶段, 它们会按照顺序反复运行

冒泡排序

image.png

自定义属性

  • html5中推出专门的data-自定义属性
  • 在标签上一律以data-开头
  • 在DOM对象上一律以dataset对象方式获取

手写防抖函数核心要点 _.debounce

image.png

手写节流函数 _.throttle

image.png