一、new做了哪些事

先看看new的使用场景:

// 1、创建一个构造函数
function Vehicle(name, price) {
    this.name = name
    this.price = price
}
​
// 2、new一个实例对象
let truck = new Vehicle()
console.log(truck); //Vehicle { name: undefined, price: undefined }
console.log(Object.prototype.toString.call(truck)); //[object Object]
​
// 传入参数
let car = new Vehicle('car', '¥9999999')
console.log(car);
//Vehicle { name: 'car', price: '¥9999999' }

司空见惯的代码,烂熟于心的写法,那你知道new具体做了哪些事情嘛?从上述代码可以看出,一个构造函数使用new操作符调用的时候,会生成一个具有构造函数相同属性的新对象。是不是很奇怪?明明Vehicle是构造函数:

console.log(typeof Vehicle); //function

然而,经过new的一番操作后,它的实例化是一个对象!!!new到底做了哪些事情呢?对于这个例子,我们可以概括为以下事情:

​
    // 第一件:在构造函数内部,创建一个this对象
    let this = {
        name = name,
        price = price
    }
​
    // 第二件:返回this对象
    return this;
​
    // 第三件:给this对象的属性赋值
    this.name = name
    this.price = price

很抽象,看不懂。。。进一步剖析如下:

function Person(name, gender) {
    console.log('赋值前的this=', this); //赋值前的this= Person {}
    this.name = name
    this.gender = gender
    console.log('赋值后的this=', this); //赋值后的this= Person { name: '小灰灰', gender: 'boy' }
}
​
let child = new Person('小灰灰', 'boy')//Person { name: '小灰灰', gender: 'boy' }
console.log(child);

由以上代码可以看出,

第一:在构造函数内部有一个空的this对象,通过new操作符,会创建生成一个全新的对象(实例对象)。

第二:实例对象会执行[[Prototype]]( .proto)链接,并且实例对象的this会指向构造函数的this(实例对象会绑定函数调用的this)。通过new创建的实例对象最终被[[Prototype]]( .proto)链接到构造函数的Prototype对象上。也就是说,实例对象的隐式原型===构造函数的显示原型

二、返回不同类型时有哪些表现

创建一个构造函数X,通过new操作符,实例化X得到实例化对象x,打印x,一定会是X{...}这个对象嘛?当构造函数内部有返回值,并且返回的是不同类型的值,打印的结果又会是怎么样呢?

function Student(id, name) {
    this.id = id
    this.name = name
​
    // 返回基本类型的值时:返回的结果依然是对象Student {name:xxx,age:xxx}
    // return null   //Student { id: '1001', name: 'cat' }
    // return undefined //Student { id: '1001', name: 'cat' }
    // return 123        //Student { id: '1001', name: 'cat' }
    // return 'hello world'   //Student { id: '1001', name: 'cat' }
    // return true  //Student { id: '1001', name: 'cat' }
    // return false  //Student { id: '1001', name: 'cat' }
    //return Symbol('abc')  //Student { id: '1001', name: 'cat' }
​
    // 返回引用类型时:
    //返回空对象时:返回的结果是空对象
    // return {}  //{}
    //返回函数时,返回的结果是函数
    return function() {} //[Function (anonymous)]
    // return [] //[]
    // return new Date() //2022-10-24T04:44:18.581Z
    // return new Error() //Error...
}
​
let student = new Student('1001', 'cat')
console.log(student); //构造函数内部返回不同类型的值时,这里的打印结果是一样的吗?

三、手写new的实现原理

思路:new的实现原理核心是new做了哪些事情。

总结:

(1)通过new操作符调用构造函数,会返回一个全新的对象,这个对象的属性是构造函数的参数。

若构造函数内部有返回值,且返回值是基本数据类型(number|string|null|undefined|Symbol|boolean),则实例对象的返回结果是原本的对象;

若返回值是引用数据类型(Object|Array|Function|Date|RegExp|Error),则实例对象的返回的结果就是引用类型对应的值。

(2)通过new操作符创建的实例对象的隐式原型会挂载到构造函数的显示原型上。实例对象.proto==构造函数.prototype。

(3)通过new操作符创建的实例对象的this会绑定调用函数的this 请看如下代码:

// new的实现原理
function newPerson() {
    // 先return一个对象
    var obj = {};
    
    var constructor = Array.prototype.shift.call(arguments); //把数组的shift方法借给constructor使用
    
    // 实例对象的隐式原型===构造函数的显示原型
    obj._proto_ = constructor.prototype;
    var result = constructor.apply(obj, arguments);
    return typeof result === 'object' && result != 'null' ? result : obj;
}
​
let p = newPerson(Person, 'hunny')
console.log(p); //{ _proto_: {}, name: 'hunny', age: undefined }

以上就是JavaScript中new操作符的原理与实现详解的详细内容,更多关于JavaScript new操作符的资料请关注Devmax其它相关文章!

JavaScript中new操作符的原理与实现详解的更多相关文章

  1. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  2. HTML5数字输入仅接受整数的实现代码

    这篇文章主要介绍了HTML5数字输入仅接受整数的实现代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. amaze ui 的使用详细教程

    这篇文章主要介绍了amaze ui 的使用详细教程,本文通过多种方法给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  4. html5简介_动力节点Java学院整理

    这篇文章主要介绍了html5简介,用于指定构建网页的元素,这些元素中的大多数都用于描述网页内容,有兴趣的可以了解一下

  5. ios 8 Homescreen webapp,关闭和打开iPad停止javascript

    我有一个适用于iPad的全屏HTML5网络应用程序,并且刚刚安装了IOS8来试用它,它一切正常,直到你关闭并重新启动iPad.一旦web应用程序重新启动javascript就会停止并加载新页面不会重新启动它.在iPad上的Safari中打开同一页面时,关闭和打开iPad会继续按预期工作.其他人注意到了这个或想出了一个解决方案吗?解决方法这似乎是我在iOS8.1.1更新中解决的.

  6. iOS 6 javascript与object.defineProperty的间歇性问题

    当访问使用较新的Object.defineProperty语法定义属性的对象的属性时,有没有其他人注意到新iOS6javascript引擎中的间歇性错误/问题?https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty我正在看到javascript失败的情况,说

  7. ios – 如何使用JSExport导出内部类的方法

    解决方法似乎没有办法将内部类函数导出到javascript.我将内部类移出并创建了独立的类,它起作用了.

  8. 静音iOS推送通知与React Native应用程序在后台

    我有一个ReactNative应用程序,我试图获得一个发送到JavaScript处理程序的静默iOS推送通知.我看到的行为是AppDelegate中的didReceiveRemoteNotification函数被调用,但是我的JavaScript中的处理程序不会被调用,除非应用程序在前台,或者最近才被关闭.我很困惑的事情显然是应用程序正在被唤醒,并且它的didReceiveRemoteNotifi

  9. ios – 内存泄漏与UIWebView和Javascript

    清楚地包含一个Javascript文件到我的HTML是使UIWebView泄漏内存.当我重复使用相同的UIWebView对象时,或者每当我有内容实例化一个新的漏洞时,会出现泄漏的事实,导致我认为必须有一些JavaScript文件被loadHTMLString处理,导致泄漏.有人知道如何解决这个问题吗?

  10. iOS应用程序的UI自动化测试如何与乐器和Javascript

    从WWDC2010视频会议中了解iOS应用程序的自动化UI测试,但没有实践.从代码项目project,我们可以有一个例子.这个问题在这里听到有涉及这个的人.任何限制?解决方法我建议从AlexWollmer开始使用thisblogpost.他创建了一个非常有用的JavaScript库:tuneup_jswithtest()函数,它允许测试分离和有用的帮助者以及为自动化仪器编写测试的断言.

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部