文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JS之如何处理new的情况

2023-07-02 17:17

关注

这篇文章主要介绍“JS之如何处理new的情况”,在日常操作中,相信很多人在JS之如何处理new的情况问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JS之如何处理new的情况”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

JS 中 bind 方法实现:
Function.prototype.myBind = function(thisArg, ...prefixArgs) {  const fn = this;  return function(...args) {    return fn.call(thisArg, ...prefixArgs, ...args);  }}

但没有处理 通过 new 创建实例 的情况。

因为很少会遇到给 bind 返回的函数做 new 操作的场景。

new

我们先学习一下 new 操作符。

new 用于通过函数来创建一个对象实例,在很多语言中都能看到。

JS 的函数,除了可以是普通函数,比如:

function sum(a, b) {  return a + b;}

还可以是构造函数,只需要在构造时在它前面加一个 new:

function Person(name, age) { this.name = name; this.age = age;}const person = new Person('前端西瓜哥', 100)// Person {name: '前端西瓜哥', age: 100}

new 创建一个新对象,做了下面几件事:

判断函数是否通过 new 被调用

怎么判断一个函数正在被 new 操作符调用?

答案是 使用 instanceof 判断 this 是否为当前函数的实例,即 this instanceof Fn 为 true,表示在通过 new 构建实例。

我们看一个例子:

function Person() {  if (this instanceof Person) {    console.log('通过 new 构建实例');  } else {    console.log('普通调用')  }}Person()     // 输出:普通调用new Person() // 输出:通过 new 构建实例

在 Vuejs 的源码,你会看到下面代码,这里也用到了这个技巧。

function Vue(options) {  if (__DEV__ && !(this instanceof Vue)) {    warn('Vue is a constructor and should be called with the `new` keyword')  }  this._init(options)}

你在开发环境如果不通过 new 来使用 Vue 对象,会在控制台提示你要通过 new 来调用 Vue。

new 和 bind

如果我们 new 的是 Function.prototype.bind 返回的新函数,会发生什么事情?

function Person(name, age) { this.name = name; this.age = age;}const BoundPerson = Person.bind(null, '前端西瓜哥');const boundPerson = new BoundPerson(100);// Person {name: '前端西瓜哥', age: 100}boundPerson.__proto__ === Person.prototype// true

结果等价于直接去 new 原始函数。

不同的是,仍旧可以进行参数的预置。可以看到,构造函数的第一个参数,在调用 bind 的时候就提前设置为 '前端西瓜哥'。

实现完整的 bind

完整实现如下:

Function.prototype.myBind = function(thisArg, ...prefixArgs) {  const fn = this;  const boundFn = function(...args) {    // 通过 new 使用当前函数    if (this instanceof boundFn) {      return new fn(...prefixArgs, ...args);    }    // 普通的方法调用当前函数    return fn.call(thisArg, ...prefixArgs, ...args);  }  boundFn.prototype = fn.prototype;  return boundFn;}

这里我通过 this instanceof boundFn 来判断是否用了 new,如果是,就直接 new 原始函数然后返回,记得带上 bind 预置好的参数。

其他保持原样。

boundFn.prototype = fn.prototype;  这个可写可不写,只是让 bind 返回的新函数的 prototype 指向原函数的 prototype。

如果是原生 bind 返回的函数,它是没有 protoype 属性的,可以认为它是一种特别的函数,而我们实现的 bind 返回的却是一个普通函数,所以并不能完全模拟的。

如果你 追求完美的实现,可以研读一下  Function.prototype.bind 的标准:

然后再看看知名的 core.js 库中对 bind 的实现:

其中核心实现为:

// `Function.prototype.bind` method implementation// https://tc39.es/ecma262/#sec-function.prototype.bindmodule.exports = Function.bind || function bind(that ) {  var F = aCallable(this);  var Prototype = F.prototype;  var partArgs = arraySlice(arguments, 1);  var boundFunction = function bound() {    var args = concat(partArgs, arraySlice(arguments));    return this instanceof boundFunction ? construct(F, args.length, args) : F.apply(that, args);  };  if (isObject(Prototype)) boundFunction.prototype = Prototype;  return boundFunction;};

这里有更多的细节:

到此,关于“JS之如何处理new的情况”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯