javascript - JS嵌套原型(prototype)访问父节点

标签 javascript class oop instance

根据以下代码,我在访问原型(prototype)中的 this 变量时遇到了一个小问题。

var MyClass = function(number) {
  this.number = number || 4;
};
MyClass.prototype = {
  run: function() {
    //direct access to object
    console.log(this.number);

    //access to object with the "self" object
    var self = this;
    setTimeout(function() {
      console.log(self.number);
    }, 1000);

    //access to object with the "self" object as a parameter
    this.events.test_a(self);

    //here is the problem
    this.events.test_b();
  },
  events: {
    test_a: function(self) {
      //access to object with the "self" object as a parameter
      console.log(self.number);
    },
    test_b: function() {
      console.log(this.number); // 👈 The problem
    }
  }
};

//----

var myClass = new MyClass(110);
myClass.run();


有什么方法可以访问 this 对象并具有如下结构?

myClass.events.test_b();

I need this👆 without using the instance that I've just created like following:👇

myClass.events.test_a(myClass);

最佳答案

一般来说,最好避免以这种方式设计结构。

但您可以通过在构造函数中绑定(bind) events 函数来实现,这意味着创建 events 对象的“自己的”副本。请参阅此最小更改版本中的 *** 注释:

// NOTE: Sticking to ES5 as the OP seems to be doing that

var MyClass = function(number) {
  this.number = number || 4;
  // *** Bind the functions on `this.events` to `this`
  var self = this;
  var events = self.events;
  self.events = {};
  Object.keys(events).forEach(function(key) {
    if (typeof events[key] === "function") {
      self.events[key] = events[key].bind(self);
    }
  });
};
// I've added the "name" parameter that's being passed around
// so we can be sure that the results for multiple
// instances are correct
MyClass.prototype = {
  constructor: MyClass, // *** Don't break prototype.constructor
  run: function(name) {
    //direct access to object
    console.log(name, "Direct access in object:", this.number);

    //access to object with the "self" object
    var self = this;
    setTimeout(function() {
      console.log(name, "In setTimeout callback:", self.number);
    }, 1000);

    //access to object with the "self" object as a parameter
    this.events.test_a(name, self);

    //here is the problem
    this.events.test_b(name);
  },
  events: {
    test_a: function(name, self) {
      //access to object with the "self" object as a parameter
      console.log(name, "In test_a:", self.number);
    },
    test_b: function(name) {
      console.log(name, "In test_b:", this.number); // 👈 Not a problem anymore
    }
  }
};

//----

var mc1 = new MyClass(110);
var mc2 = new MyClass(220);
setTimeout(function() {
    mc1.run("mc1");
}, 1000);
setTimeout(function() {
    mc2.run("mc2");
}, 2000);
.as-console-wrapper {
    max-height: 100% !important;
}


旁注:请参阅我添加到您要分配给 prototype 的对象的这一行:

constructor: MyClass, // *** Don't break prototype.constructor

默认情况下,函数的 prototype 对象有一个 constructor 属性指向函数,所以最好这样做。

关于javascript - JS嵌套原型(prototype)访问父节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56803135/

相关文章:

Javascript - 使用可选主题标签搜索字符串

javascript - 是否可以在 javascript 中获取远程图像的一部分?

javascript - 单击图像时不出现圆圈,但对其他人有效

c++ - vector 类错误

swift - 类声明和使用

java - 创建对象时出现 StackOverflowError

.net - 在多个项目中使用相同的模块

javascript - Angular2 + ngrx/存储 : how to change state within a loop?

c++ - 什么样的数据或函数放在C++类的保护区比较好?

java - 为什么更喜欢变量的 getter 和 setter 方法而不是将其公开?