返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript中利用new调用函数的原理是什么
  • 542
分享到

JavaScript中利用new调用函数的原理是什么

2024-04-02 19:04:59 542人浏览 安东尼
摘要

javascript中利用new调用函数的原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1.1 无 return 语

javascript中利用new调用函数的原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

1.1 无 return 语句

构造函数***没有 return 语句,这也是使用构造函数时默认情况,***会返回一个新对象,如下:

function Foo(age) {    this.age = age;  }    var o = new Foo(111);  console.log(o);

这是常见的使用构造函数创建对象的过程,打印出来的是 {age: 111}。

1.2 return 对象类型数据

构造函数*** return 对象类型数据:

function Foo(age) {   this.age = age;   return { type: "我是显式返回的" }; }  var o = new Foo(222); console.log(o);

打印出来的是 {type: '我是显式返回的'},也就是说,return 之前的工作都白做了,***返回 return 后面的对象。

1.3 return 基本类型数据

那是不是只要构造函数体内***有 return,返回都是 return 后面的数据呢?

我们看下返回基本类型数据的情况:

function Foo(age) {    this.age = age;     return 1;  }   var o = new Foo(333);  console.log(o);

打印出来的是 {age: 333},和没有 return 时效果一样。跟预期不一样,背后你原理看下面分析。

二、背后原理

2.1 非箭头函数的情况

当使用 new 操作符创建对象是,ES5 官方文档在 函数定义 一节中做了如下定义 13.2.2 [[Construct]]:

When the [[Construct]] internal method for a Function object F is called with a possibly empty list of arguments, the following steps are taken:       Let obj be a newly created native ECMAScript object.      Set all the internal methods of obj as specified in 8.12.      Set the [[Class]] internal property of obj to Object.      Set the [[Extensible]] internal property of obj to true.      Let proto be the value of calling the [[Get]] internal property of F with argument "prototype".      If Type(proto) is Object, set the [[Prototype]] internal property of obj to proto.      If Type(proto) is not Object, set the [[Prototype]] internal property of obj to the standard built-in Object prototype object as described in 15.2.4.      Let result be the result of calling the [[Call]] internal property of F, providing obj as the this value and providing the argument list passed into [[Construct]] as args.      If Type(result) is Object then return result.      Return obj.

看第 8、9 步:

  8)调用函数 F,将其返回值赋给 result;其中,F 执行时的实参为传递给 [[Construct]](即 F 本身) 的参数,F 内部 this 指向 obj;

  9)如果 result 是 Object 类型,返回 result;

这也就解释了如果构造函数显式返回对象类型,则直接返回这个对象,而不是返回最开始创建的对象。

***在看第 10 步:

  10)如果 F 返回的不是对象类型(第 9 步不成立),则返回创建的对象 obj。

如果构造函数没有显式返回对象类型(显式返回基本数据类型或者直接不返回),则返回最开始创建的对象。

2.2 箭头函数的情况

那如果构造函数是箭头函数怎么办?

箭头函数中没有 [[Construct]] 方法,不能使用 new 调用,会报错。

NOTICE:其中 [[Construct]] 就是指构造函数本身。

  相关规范在 es6 的官方文档 中有提,但自从 ES6 以来的官方文档巨难懂,在此不做表述。

三、new 调用函数完整过程

3.1 中文描述及相关代码分析

除了箭头函数之外的任何函数,都可以使用 new 进行调用,背后发生了什么,上节英文讲述的很清楚了,再用中文描述如下:

1)创建 ECMAScript 原生对象 obj;

2)给 obj 设置原生对象的内部属性;(和原型属性不同,内部属性表示为 [[PropertyName]],两个方括号包裹属性名,并且属性名大写,比如常见 [[Prototype]]、[[Constructor]])

3)设置 obj 的内部属性 [[Class]] 为 Object;

4)设置 obj 的内部属性 [[Extensible]] 为 true;

5)将 proto 的值设置为 F 的 prototype 属性值;

6)如果 proto 是对象类型,则设置 obj 的内部属性 [[Prototype]] 值为 proto;(进行原型链关联,实现继承的关键)

7)如果 proto 是不对象类型,则设置 obj 的内部属性 [[Prototype]] 值为内建构造函数 Object 的 prototype 值;(函数 prototype 属性可以被改写,如果改成非对象类型,obj 的 [[Prototype]] 就指向 Object 的原型对象)

8)9)10)见上节分析。(决定返回什么)

对于第 7 步的情况,见下面代码:

function Foo(name) {    this.name = name;  }   var o1 = new Foo("xiaoming");  console.log(o1.__proto__ === Foo.prototype); // true    // 重写构造函数原型属性为非对象类型,实例内部 [[Prototype]] 属性指向 Object 原型对象  // 因为实例是一个对象类型的数据,默认会继承内建对象的原型,  // 如果构造函数的原型不满足形成原型链的要求,那就跳过直接和内建对象原型关联  Foo.prototype = 1;  var o2 = new Foo("xiaohong");  console.log(o2.__proto__ === Foo.prototype); // false  console.log(o2.__proto__ === Object.prototype); // true

3.2 更简洁的语言描述

若执行 new Foo(),过程如下:

1)创建新对象 o;

2)给新对象的内部属性赋值,关键是给[[Prototype]]属性赋值,构造原型链(如果构造函数的原型是 Object 类型,则指向构造函数的原型;不然指向 Object 对象的原型);

3)执行函数 Foo,执行过程中内部 this 指向新创建的对象 o;

4)如果 Foo 内部显式返回对象类型数据,则,返回该数据,执行结束;不然返回新创建的对象 o。

四、几点说明

4.1 判断是否是 Object 类型

关于一个数据是否是 Object 类型,可以通过 instanceof 操作符进行判断:如果 x instanceof Object 返回 true,则 x 为 Object 类型。

由上可知,null instanceof Object 返回 false,所以 null 不是 Object 类型,尽管typeof null 返回 "Object"。

4.2 instanceof 原理

instanceof 的工作原理是:在表达式 x instanceof Foo 中,如果 Foo 的原型(即 Foo.prototype)出现在 x 的原型链中,则返回 true,不然,返回 false。

因为函数的原型可以被改写,所以会出现在 x 通过 Foo new 出来之后完全改写 Foo 的原型 x instanceof Foo 返回 false 的情况。因为实例创建之后重写构造函数原型,实例指向的原型已经不是构造函数的新的原型了,见下面代码:

const Foo = function() {};  const o = new Foo();  o instanceof Foo; // true  // 重写 Foo 原型  Foo.prototype = {};  o instanceof Foo; // false

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网JavaScript频道,感谢您对编程网的支持。

--结束END--

本文标题: JavaScript中利用new调用函数的原理是什么

本文链接: https://lsjlt.com/news/67607.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JavaScript中利用new调用函数的原理是什么
    JavaScript中利用new调用函数的原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1.1 无 return 语...
    99+
    2024-04-02
  • javascript new怎么调用构造函数
    本篇内容主要讲解“javascript new怎么调用构造函数”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“javascript new怎么调用构造函数”吧!说明在内存中创建新对象。新对象内部的...
    99+
    2023-06-20
  • javascript的构造函数, 原型,原型链和new是什么
    这篇“javascript的构造函数, 原型,原型链和new是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“j...
    99+
    2023-06-29
  • JavaScript中判断函数是new还是()调用的区别说明
    方式1 复制代码 代码如下: function Person(n,a){ this.name = n; this.age = a; if(this instanceof Person...
    99+
    2022-11-21
    判断函数 new
  • C语言函数的调用原理是什么
    C语言函数的调用原理是通过栈来实现的。当一个函数被调用时,系统会为该函数分配一块内存空间,这块空间被称为栈帧。栈帧包含了函数的参数、...
    99+
    2023-09-04
    C语言
  • JavaScript中函数柯里化的原理是什么
    今天就跟大家聊聊有关JavaScript中函数柯里化的原理是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。柯里化是这样的一个转换过程,把接受多个...
    99+
    2024-04-02
  • JavaScript中的回调函数是什么及如何用
    今天小编给大家分享一下JavaScript中的回调函数是什么及如何用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1.什么是...
    99+
    2023-07-04
  • Javascript中new()有什么用
    小编给大家分享一下Javascript中new()有什么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!要创建 Person 的...
    99+
    2024-04-02
  • JavaScript中new有什么用
    这篇文章给大家分享的是有关JavaScript中new有什么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。为了保证可读性,本文采用意译而非直译。当你使用new的时候,会:创建一...
    99+
    2024-04-02
  • JavaScript的回调函数是什么
    这篇文章主要介绍“JavaScript的回调函数是什么”,在日常操作中,相信很多人在JavaScript的回调函数是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java...
    99+
    2024-04-02
  • JavaScript中new操作符的作用是什么
    这篇文章给大家介绍JavaScript中new操作符的作用是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。JavaScript的特点1.JavaScript主要用来向HTML页面添加交互行为。2.JavaScrip...
    99+
    2023-06-06
  • JavaScript函数是怎么被调用的
    这篇文章主要介绍了JavaScript函数是怎么被调用的的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript函数是怎么被调用的文章都会有所收获,下面我们一起来看看...
    99+
    2024-04-02
  • JavaScript中函数的作用是什么
    本篇内容介绍了“JavaScript中函数的作用是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2024-04-02
  • javascript用函数式编程的原因是什么
    这篇“javascript用函数式编程的原因是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看...
    99+
    2024-04-02
  • JavaScript中怎么调用函数
    这期内容当中小编将会给大家带来有关JavaScript中怎么调用函数,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。首先让我们创建一个简单的函数,这个函数将在将在下文中使用...
    99+
    2024-04-02
  • javascript回调函数有什么用
    这篇文章主要为大家展示了“javascript回调函数有什么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“javascript回调函数有什么用”这篇文章吧。 ...
    99+
    2024-04-02
  • JavaScript中函数调用栈是怎么工作的
    这篇文章将为大家详细讲解有关JavaScript中函数调用栈是怎么工作的,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。合理地处理堆栈信息能使你清除无用的数据, 而只专注于...
    99+
    2024-04-02
  • PostgreSQL ExecAgg中调用的函数是什么
    本篇内容主要讲解“PostgreSQL ExecAgg中调用的函数是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“PostgreSQL ExecAgg中调用...
    99+
    2024-04-02
  • C语言函数调用底层实现原理是什么
    本文小编为大家详细介绍“C语言函数调用底层实现原理是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言函数调用底层实现原理是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。前言C语言程序执行实质上的函数...
    99+
    2023-07-05
  • C#中异步调用的原理是什么
    本篇文章为大家展示了C#中异步调用的原理是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。C#异步调用是什么呢?具体的内容又是什么呢?让我们开始C#异步调用的学习吧计算机中有些处理比较耗时。调用这...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作