资讯专栏INFORMATION COLUMN

一道面试题引发的思考 --- 理解 new 运算符

shengguo / 3270人阅读

摘要:首先,我先去上搜索了的定义运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

今天看到一道面试题,如下,问: 实例化 Person 过程中,Person返回什么(或者 p 等于什么)?

function Person(name) {
    this.name = name
    return name;
}
let p = new Person("Tom");

说实话,第一反应我以为值为 "Tom",等到我把代码丢到控制台一输出,才明白我错了。天呐,new运算符给无视掉了吗???
撇开 new 的存在,我们修改下代码

function Person(name) {
    this.name = name
    return name;
}
let p = Person("Tom");
console.log(p);

很显然,输出的结果是 "Tom", 但是有 new 存在呢?接下去,我们来捋一捋。
首先,我先去 MDN上搜索了 new 的定义

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

emmmm,相当晦涩难懂。

那我们试着写几个栗子看看结果吧

function Person1(name) {
  this.name = name;
  // 没有返回值
}

function Person2(name) {
  this.name = name;
  return name;
  // 返回非对象
}

function Person3(name) {
  this.name = name;
  return { a: 1 };
  // 返回对象
}

function Person4(name) {
  this.name = name;
  return null;
  // 返回null
}

var p1 = new Person1("aa");
var p2 = new Person2("bb");
var p3 = new Person3("cc");
var p4 = new Person4("dd");

console.log(p1); // Person1 {name: "aa"}
console.log(p2); // Person2 {name: "bb"}
console.log(p3); // {a: 1}
console.log(p4); // Person4 {name: "dd"}

根据上面几个栗子,我们能得出结论:当使用 new 来创建对象||调用构造函数时,如果函数没有返回值|| 返回值是非对象,那么返回的就是构造函数实例后的对象;如果函数return对象,那么返回这个对象(特例:return null,返回的也是构造函数实例后的对象而非null)

我们接着看 MDN 文档的解释,毕竟光光看这几个demo没有说服力。

一起来理解下 new 到底做了什么工作吧~
就拿下面这个 demo分析

function Person(name) {
  this.name = name;
  return {a: 1}
}
var p = new Person("fefeng")

当调用 new Person(...)时,会进行以下几步:

首先是 继承自 Person.prototype的新对象会被创建

使用参数 "fefeng" 调用构造函数 Person, 并将 this 绑定到新创建的对象

Person 返回的对象就是 new 表达式的结果 =》 Person 返回的对象是 {a: 1} 所以new 表达式的结果为 {a:1} ; 如果 Person 没有返回值(一般构造函数都不返回值)那么使用步骤1创建的对象,即==》 继承自 Person.prototype 的新对象

貌似照着文档能够些许理解了,倘若模拟实现 new运算符更能深入理解 new
以下是 new 的模拟实现,代码来源 : JavaScript深入之new的模拟实现

function objectFactory() {
  var obj = new Object(),
  cons = [].shift.call(arguments)
  obj.__proto__ = cons.prototype
  var ret = cons.apply(obj, arguments)
  return typeof ret === "object" ? ret|| obj : obj
}
function Person(name) {
  this.name = name;
  return {a: 1}
}
var p = objectFactory(Person, "fefeng")

当然了,学习别人的代码不能仅仅只是照搬过来,起码得理解这个代码吧。
使用

首先是创建一个对象,

cons 是调用 objectFactory 方法的第一个参数,即构造函数; 因为 shift 会改变原数组,所以改变后的 argument 即为调用构造函数的参数 (这里补充说明下: arguments 是一个对应于传递给函数的参数的类数组对象。)

obj 的原型指向构造函数, 这样 obj 就能访问到构造函数原型上的属性

将构造函数 consthis 指向 obj,这样 obj 能访问构造函数里的属性

判断返回的值是不是一个对象,如果是对象即返回它(当然这里要处理 return null 的特例);如果不是对象就返回 obj (注意:这里的 obj 已经不是一个空对象)

如果你耐心看到了这里,那么十分感谢。如文章有错误,望给予指正~

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100230.html

相关文章

  • 一道前端面试引发思考

    摘要:直接开始题目是厉害了说句实话开发中谁写成这样保证会被打死。不过面试就是面试,有面试官的考量点。官方是这么说的。结果完美,不过小姐姐的意思是数组的方法会自动触发数组的。 直接开始题目是 if(a==1 && a==2 && a==3){ alert(厉害了) } 说句实话开发中谁写成这样保证会被打死。 不过面试就是面试,有面试官的考量点。 我理解的点有两个 1、隐式类型转换 先说...

    gaomysion 评论0 收藏0
  • 一道面试引发思考 --- Event Loop

    摘要:想必面试题刷的多的同学对下面这道题目不陌生,能够立即回答出输出个,可是你真的懂为什么吗为什么是输出为什么是输出个这两个问题在我脑边萦绕。同步任务都好理解,一个执行完执行下一个。本文只是我对这道面试题的一点思考,有误的地方望批评指正。 想必面试题刷的多的同学对下面这道题目不陌生,能够立即回答出输出10个10,可是你真的懂为什么吗?为什么是输出10?为什么是输出10个10?这两个问题在我脑...

    betacat 评论0 收藏0
  • 一道面试引发思考

    摘要:下面我们来使用面向对象类图这里就不再画了首先面试题中所提到的我们都可以看成类,比如停车场是一个类吧,它里面的车位是一个类吧,摄像头,屏幕。。。 以下是某场的一道面试题(大概): 1、一个停车场,车辆入场时,摄像头记录下车辆信息2、屏幕上显示所接收的车辆的信息情况(车牌号)以及各层车位的车位余量3、停车场一共四层车位,其中的三层都为普通车位,还有一层为特殊车位(体现在停车计费价格上面的不...

    Apollo 评论0 收藏0
  • 一道面试引发思考

    摘要:下面我们来使用面向对象类图这里就不再画了首先面试题中所提到的我们都可以看成类,比如停车场是一个类吧,它里面的车位是一个类吧,摄像头,屏幕。。。 以下是某场的一道面试题(大概): 1、一个停车场,车辆入场时,摄像头记录下车辆信息2、屏幕上显示所接收的车辆的信息情况(车牌号)以及各层车位的车位余量3、停车场一共四层车位,其中的三层都为普通车位,还有一层为特殊车位(体现在停车计费价格上面的不...

    soasme 评论0 收藏0

发表评论

0条评论

shengguo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<