使用"this ="的Javascript函数给出"赋值时无效的左侧"

Bri*_*unt 7 javascript oop inheritance prototypal-inheritance prototype-programming

我试图让一个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.
 }
Run Code Online (Sandbox Code Playgroud)

我很感激你关于如何让ObjY包含ObjX对'this'的赋值(即不必重复this.$* = *ObjY构造函数中的所有赋值)并让ObjY假设ObjX.prototype的想法.

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

function ObjY(a,b,c) {
   this.prototype = new ObjX(a,b*12);
}
Run Code Online (Sandbox Code Playgroud)

理想情况下,我想学习如何以原型方式执行此操作(即不必使用任何像Base2这样的'经典'OOP替代品.

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

谢谢.

CMS*_*CMS 19

你不能真的这样做,因为this定义的值是不可变的,你不能以它所引用的方式改变它.

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

function ObjY(a,b,c) {
  ObjX.call(this, a, b * 12); 
  this.$c = c;
}
Run Code Online (Sandbox Code Playgroud)

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

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

编辑:关于原型,你的样本将无法工作,因为该prototype属性对于stances中的对象没有特殊含义,它将与任何其他属性一样,它应该用在构造函数上.

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

[[Prototype]]属性只能由new运营商设置(通过[[Construct]]内部操作),此属性不能更改,(虽然某些实现,如Mozilla,您可以通过它访问它obj.__proto__;,并且在ECMAScript 5中,该Object.getPrototypeOf方法已被引入,但我不建议你直接搞乱它).

实际上,当执行构造函数时[[Prototype]],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;
Run Code Online (Sandbox Code Playgroud)

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

推荐文章: