js的new操作

本文深入探讨了JavaScript中的构造函数和原型链。通过`myNew`函数展示了对象创建过程,强调了`__proto__`属性的作用以及如何共享函数原型上的属性。同时,解释了对象属性覆盖的规则,提醒开发者更改`[[Prototype]]`可能带来的性能问题,并推荐使用`Object.create()`代替。此外,还提及了`fun`函数及其原型上的`role`属性示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 过程

function myNew(fn, ...args) {
  // 1.创建一个新的对象
  const obj = {};

  // 2.将构造函数的prototype设置为这个对象的__proto__,
  // 这样当这个对象不存在的属性或方法会顺着__proto__查找到fn.prototype
  // 所以写在fn.prototype的属性或方法会被公用
  obj.__proto__ = fn.prototype;

  // 3.以这个对象调用函数(this就会指向这个对象)
  const ret = fn.apply(obj, args);

  // 4.判断返回类型。如果构造函数有返回类型且是对象,就返回那个对象,new就相当于失效了
  return ret instanceof Object ? ret : obj;
}

  公用属性覆盖

  • 不会覆盖:执行赋值操作(f.role = { name: "f" }),是在f这个对象里加了role这个属性,所以不会影响到f2.role,f2.role依旧是f.__proto__.role
  • 会覆盖:而f.role.age = 123会影响f.__proto__.role

function fun(x, y) {
  this.x = x;
  this.y = y;
}

fun.prototype.role = { name: "tom", age: 18 };

let f = new fun(1, 2);
let f2 = new fun(3, 4);

console.log(f.role === f2.role); //true

f.role.age = 123;
f.role = { name: "f" };

console.log(f.role); // {name: "f"}
console.log(f2.role); // {name: "tom", age: 123}
console.log(f.__proto__.role); // {name: "tom", age: 123}

Object.create()

警告: 由于现代 JavaScript 引擎优化属性访问所带来的特性的关系,更改对象的 [[Prototype]]各个浏览器和 JavaScript 引擎上都是一个很慢的操作。其在更改继承的性能上的影响是微妙而又广泛的,这不仅仅限于 obj.__proto__ = ... 语句上的时间花费,而且可能会延伸到任何代码,那些可以访问任何[[Prototype]]已被更改的对象的代码。如果你关心性能,你应该避免设置一个对象的 [[Prototype]]。相反,你应该使用 Object.create()来创建带有你想要的[[Prototype]]的新对象。--- MDN

 

代码 url

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值