Javascript 函数使用“this =”给出“赋值中的左侧无效”

发布于 2024-08-24 16:14:03 字数 1250 浏览 10 评论 0 原文

我试图让一个 JavaScript 对象使用另一个对象的构造函数的“this”赋值,并假设所有该对象的原型函数。这是我试图完成的一个例子:

 /* The base - contains assignments to 'this', and prototype functions
  */
 function ObjX(a,b) {
     this.$a = a;
     this.$b = b;
 }

 ObjX.prototype.getB() {
     return this.$b;
 }

 function ObjY(a,b,c) {
    // here's what I'm thinking should work:
    this = ObjX(a, b * 12); 
    /* and by 'work' I mean ObjY should have the following properties:
     * ObjY.$a == a, ObjY.$b == b * 12,
     * and ObjY.getB == ObjX.prototype.getB
     * ... unfortunately I get the error: 
     *     Uncaught ReferenceError: Invalid left-hand side in assignment
     */

    this.$c = c; // just to further distinguish ObjY from ObjX.
 }

我很感激您关于如何让 ObjY 将 ObjX 的分配包含到“this”的想法(即不必重复所有 this.$* = *< /code> ObjY 构造函数中的赋值)并让 ObjY 假定 ObjX.prototype。

我的第一个想法是尝试以下操作:

function ObjY(a,b,c) {
   this.prototype = new ObjX(a,b*12);
}

理想情况下,我想学习如何以原型方式执行此操作(即不必使用任何“经典”OOP 替代品,例如 Base2)。

值得注意的是,ObjY 将是匿名的(例如,factory['ObjX'] = function(a,b,c) { this = ObjX(a,b*12); ... }) ——如果我的术语正确的话。

谢谢。

I am trying to get a JavaScript object to use the "this" assignments of another objects' constructor, as well as assume all that objects' prototype functions. Here's an example of what I'm attempting to accomplish:

 /* The base - contains assignments to 'this', and prototype functions
  */
 function ObjX(a,b) {
     this.$a = a;
     this.$b = b;
 }

 ObjX.prototype.getB() {
     return this.$b;
 }

 function ObjY(a,b,c) {
    // here's what I'm thinking should work:
    this = ObjX(a, b * 12); 
    /* and by 'work' I mean ObjY should have the following properties:
     * ObjY.$a == a, ObjY.$b == b * 12,
     * and ObjY.getB == ObjX.prototype.getB
     * ... unfortunately I get the error: 
     *     Uncaught ReferenceError: Invalid left-hand side in assignment
     */

    this.$c = c; // just to further distinguish ObjY from ObjX.
 }

I'd be grateful for your thoughts on how to have ObjY subsume ObjX's assignments to 'this' (i.e. not have to repeat all the this.$* = * assignments in ObjY's constructor) and have ObjY assume ObjX.prototype.

My first thought is to try the following:

function ObjY(a,b,c) {
   this.prototype = new ObjX(a,b*12);
}

Ideally I'd like to learn how to do this in a prototypal way (i.e. not have to use any of those 'classic' OOP substitutes like Base2).

It may be noteworthy that ObjY will be anonymous (e.g. factory['ObjX'] = function(a,b,c) { this = ObjX(a,b*12); ... }) -- if I've the terminology right.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

听风念你 2024-08-31 16:14:03

你实际上不能这样做,因为 this 值根据定义是不可变的,您无法以这种方式更改它引用的内容。

解决方法是使用 callapply 方法在 ObjYthis 对象中运行 ObjX 构造函数:

function ObjY(a,b,c) {
  ObjX.call(this, a, b * 12); 
  this.$c = c;
}

在上面的示例中,执行了 ObjX 函数更改其 this 值,因此您在此函数中对该对象进行的所有属性扩展都将反映在 ObjY 中 this 值引用的新对象中构造函数。

一旦 call 方法结束,this 对象就会被扩充,您可以进行更多属性扩展,例如添加 $c 值。

编辑:关于原型,您的示例将不起作用,因为 prototype 属性对于对象实例没有特殊含义,它就像任何其他属性一样,应该是用于构造函数

我认为您可能会将构造函数的 prototype 属性与所有对象都具有的内部 [[Prototype]] 属性混淆。

[[Prototype]] 属性只能由 new 运算符设置(通过 [[Construct]] 内部操作),此属性无法更改,(尽管某些实现,例如 Mozilla 的实现,您可以通过以下方式访问它obj.__proto__;,在 ECMAScript 5 中, Object.getPrototypeOf 方法已经被引入,但我不建议你直接使用它)。

实际上,当执行构造函数时,this 值引用的对象的内部 [[Prototype]] 属性已经设置为其构造函数的 原型 属性。

因此,正如 @Anurag 评论,您可以将 ObjY.prototype 设置为新创建的 ObjX 对象:

function ObjY(a,b,c) {
  ObjX.call(this, a, b * 12); 
  this.$c = c;
}

ObjY.prototype = new ObjX();
ObjY.prototype.constructor = ObjY;

这将使您的 ObjY 也继承添加到 ObjX.prototype 的属性,如您所见,我更改了 ObjY.prototype.constructor,因为上面行中的赋值将使该属性错误地指向ObjX

推荐文章:

You can't really do that, because the this value by definition is immutable, you can't change in that way what it references to.

A workaround would be to use the call or apply methods to run your ObjX constructor function in the this object of ObjY:

function ObjY(a,b,c) {
  ObjX.call(this, a, b * 12); 
  this.$c = c;
}

In the above example, the ObjX function is executed changing its this value, so all property extensions you make to that object in this function, will be reflected in the new object that the this value refers in the ObjY constructor.

As soon the call method ends, the this object will be augmented and you can make more property extensions, like adding your $c value.

Edit: About the prototypes, your sample will not work, because the prototype property has no special meaning for object in stances it will be just as any other property, it should be used on constructor functions.

I think you might be confusing the prototype property of constructors with the internal [[Prototype]] property that all objects have.

The [[Prototype]] property can only be set by the new operator (through the [[Construct]] internal operation), this property can't be changed, (although some implementations, like the Mozilla one, you can access it through obj.__proto__;, and in ECMAScript 5, the Object.getPrototypeOf method has been introduced, but I wouldn't recommend you to mess directly with it).

Actually, when your constructor function is executed, the internal [[Prototype]] property of the object that the this value refers, has already been set to its constructor's prototype property.

So, as @Anurag comments, you could set the ObjY.prototype to a newly created ObjX object:

function ObjY(a,b,c) {
  ObjX.call(this, a, b * 12); 
  this.$c = c;
}

ObjY.prototype = new ObjX();
ObjY.prototype.constructor = ObjY;

That will make that your ObjY inherit also the properties added to the ObjX.prototype, and as you see, I changed the ObjY.prototype.constructor, since the assignment in the line above will make this property to wrongly point to ObjX.

Recommended articles:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文