JavaScript中的new关键字在第一次遇到时可能会非常混乱,因为人们倾向于认为JavaScript不是一种面向对象的编程语言.

  • 这是怎么一回事?
  • 它解决了什么问题?
  • 什么时候合适,什么时候不合适?

推荐答案

它可以做5件事:

  1. 它会创建一个新对象.该对象的类型仅为object.
  2. 它将这个新对象的内部、不可访问的[[prototype]](即__proto__)属性设置为构造函数的外部、可访问的prototype对象(每个函数对象自动具有prototype属性).
  3. 它使this变量指向新创建的对象.
  4. 每当提到this时,它就会使用新创建的对象来执行构造函数.
  5. 它返回新创建的对象,除非构造函数返回非null对象引用.在本例中,将返回该对象引用.

注:constructor function是指new关键字后的函数,如下所示

new ConstructorFunction(arg1, arg2)

完成此操作后,如果请求新对象的未定义属性,脚本将判断对象的[[prototype]]对象中的属性.这就是如何在JavaScript中获得类似于传统类继承的东西.

最困难的是第二点.每个对象(包括函数)都有一个名为[[prototype]]的内部属性.它可以在对象创建时设置为only,或者设置为new,或者设置为Object.create,或者基于文本(函数默认为Function.prototype,数字设置为Number.prototype,等等).它只能用Object.getPrototypeOf(someObject)读.还有其他方法可以设置或读取该值.

除了隐藏的[[prototype]]属性之外,函数还有一个名为prototype的属性,您可以访问和修改该属性,以便为创建的对象提供继承的属性和方法.


下面是一个示例:

ObjMaker = function() {this.a = 'first';};
// ObjMaker is just a function, there's nothing special about it that makes 
// it a constructor.

ObjMaker.prototype.b = 'second';
// like all functions, ObjMaker has an accessible prototype property that 
// we can alter. I just added a property called 'b' to it. Like 
// all objects, ObjMaker also has an inaccessible [[prototype]] property
// that we can't do anything with

obj1 = new ObjMaker();
// 3 things just happened.
// A new, empty object was created called obj1.  At first obj1 was the same
// as {}. The [[prototype]] property of obj1 was then set to the current
// object value of the ObjMaker.prototype (if ObjMaker.prototype is later
// assigned a new object value, obj1's [[prototype]] will not change, but you
// can alter the properties of ObjMaker.prototype to add to both the
// prototype and [[prototype]]). The ObjMaker function was executed, with
// obj1 in place of this... so obj1.a was set to 'first'.

obj1.a;
// returns 'first'
obj1.b;
// obj1 doesn't have a property called 'b', so JavaScript checks 
// its [[prototype]]. Its [[prototype]] is the same as ObjMaker.prototype
// ObjMaker.prototype has a property called 'b' with value 'second'
// returns 'second'

这类似于类继承,因为现在,您使用new ObjMaker()创建的任何对象似乎也继承了‘b’属性.

如果你想要一个子类,那么你可以这样做:

SubObjMaker = function () {};
SubObjMaker.prototype = new ObjMaker(); // note: this pattern is deprecated!
// Because we used 'new', the [[prototype]] property of SubObjMaker.prototype
// is now set to the object value of ObjMaker.prototype.
// The modern way to do this is with Object.create(), which was added in ECMAScript 5:
// SubObjMaker.prototype = Object.create(ObjMaker.prototype);

SubObjMaker.prototype.c = 'third';  
obj2 = new SubObjMaker();
// [[prototype]] property of obj2 is now set to SubObjMaker.prototype
// Remember that the [[prototype]] property of SubObjMaker.prototype
// is ObjMaker.prototype. So now obj2 has a prototype chain!
// obj2 ---> SubObjMaker.prototype ---> ObjMaker.prototype

obj2.c;
// returns 'third', from SubObjMaker.prototype

obj2.b;
// returns 'second', from ObjMaker.prototype

obj2.a;
// returns 'first', from SubObjMaker.prototype, because SubObjMaker.prototype 
// was created with the ObjMaker function, which assigned a for us

我读了很多关于这个主题的废话,最后找到了this page个,用漂亮的图表很好地解释了这一点.

Javascript相关问答推荐

我的glb文件没有加载到我的three.js文件中

如何使用JavaScript用等效的功能性HTML替换标记URL格式?

根据总价格对航班优惠数组进行排序并检索前五个结果- Angular HTTP请求

如何为GrapesJS模板编辑器创建自定义撤销/重复按钮?

如何访问Json返回的ASP.NET Core 6中的导航图像属性

Javascript,部分重排序数组

还原器未正确更新状态

在HTML语言中调用外部JavaScript文件中的函数

以Angular 实现ng-Circle-Progress时出错:模块没有导出的成员

连接到游戏的玩家不会在浏览器在线游戏中呈现

变量在导入到Vite中的另一个js文件时成为常量.

Nextjs 13.4 Next-Auth 4.2登录(&Quot;凭据&,{});不工作

在不删除代码的情况下禁用Java弹出功能WordPress

基于产品ID更新条带产品图像的JavaScript命中错误

为什么我看到的是回复,而不是我的文档?

为什么我的SoupRequest";被重置为初始值,以及如何修复它?

设置复选框根据选中状态输入选中值

如何将对象推送到firestore数组?

JSX/React -如何在组件props 中循环遍历数组

使用python,我如何判断一个html复选框是否被隐藏,以及它是否被S选中?