JS关键词 new call apply bind的原理和手写实现

文章详细阐述了JavaScript中new关键字创建对象的过程以及call、apply、bind方法如何改变函数的this指向。同时,通过示例展示了如何利用这些方法判断数据类型、处理类数组对象以及获取数组的最大值和最小值。此外,还提供了myCall和myApply的手写实现。
摘要由CSDN通过智能技术生成

new 关键字生成一个实例对象的步骤:

  1. 创建一个对象
  2. 将构造函数的作用域赋值给新对象(this 指向新对象)
  3. 执行构造函数中的代码(为新对象添加属性)
  4. 返回新对象

当 构造函数返回一个和 this 无关的对象时,new 命令会直接返回这个对象而不是通过 new 执行步骤而生成的 this 对象。

所以 new 关键词执行之后总会返回一个对象,要么是实例对象,要么是 return 语句返回的指定对象。

call & apply & bind
三个方法都是 Function 下的方法

func.call(thisArg, param1, param2, …)

func.apply(thisArg, [param1,param2,…])

func.bind(thisArg, param1, param2, …)

三者的作用都是改变函数 func 的this 指向。
call 和 apply 的区别在于传参的写法不同,call 的第二个至第 N 个都是给 func 的传参,而 apply 的第二个参数是一个数组。
bind 和 这二者的区别又在于 bind 虽然改变了 func 的 this 指向,但是并不会立即执行,而 call 和 apply 是在改变了函数的 this指向后立即执行。

方法的应用场景:

判断数据类型:

Object.prototype.toString 是可以用来判断数据类型的

console.log(Object.prototype.toString({}) );  // [object Object]
console.log(Object.prototype.toString.call({})); // 同上结果,加上call也ok
console.log(Object.prototype.toString.call(1)); // [object Number]
console.log(Object.prototype.toString.call('1') ); // [object String]
console.log(Object.prototype.toString.call(true) ); // [object Boolean]
console.log(Object.prototype.toString.call(function(){}) ); // [object Function]
console.log(Object.prototype.toString.call(null) ); //[object Null]
console.log(Object.prototype.toString.call(undefined)); // [object Undefined]
console.log(Object.prototype.toString.call(/123/g) ); // [object RegExp]
console.log(Object.prototype.toString.call(new Date())); // [object Date]
console.log(Object.prototype.toString.call([])  ); // [object Array]
console.log(Object.prototype.toString.call(document)); // [object HTMLDocument]
console.log(Object.prototype.toString.call(window)); // [object Window]

其中 prototype.toString 是 Object 的方法所以可以直接使用,而 Number、String、BOOlean、Function 等就需要“借用” Object 的方法,就可以使用 call、apply 等方法将 this 指向进行改变后进行使用。

类数组借用方法

类数组不是真正的数组所以没有数组的方法,但是可以通过这三个方法进行借用。

let arrayLike = { 
  0: 'java',
  1: 'script',
  length: 2
} 

Array.prototype.push.call(arrayLike, 'C', 'python'); 
console.log(arrayLike); // { '0': 'java', '1': 'script', '2': 'C', '3': 'python', length: 4 }
获取数组最大/最小值

通常使用 Math.max()、Math.min() 来获取最大最小值
对于数组就是:

let arr = [1, 6, 9, 19, 10];
const max = Math.max(...arr); 
const min = Math.min(...arr);
console.log(max); // 19
console.log(min); // 11

而使用 apply ,就可以不需要使用扩展运算符进行对数组的展开,直接借用 Math 的方法进行使用:

let arr = [1, 6, 9, 19, 10];
const max = Math.max.apply(Math, arr); 
const min = Math.min.apply(Math, arr);
console.log(max); // 19
console.log(min); // 11

在这里插入图片描述

手写 call & apply
Function.prototype.myCall = function (context, ...args) {
  // 如果 context 为空就指向window对象
  let context = context || window
  context.fn = this
  let res = context.fn(...args)
  // 删除 context 身上的 fn 方法
  delete context.fn
  return res
}

Function.prototype.myApply = function (context, ...args) {
  // 如果 context 为空就指向window对象
  let context = context || window
  context.fn = this
  let res = context.fn(args)
  // 删除 context 身上的 fn 方法
  delete context.fn
  return res
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值