Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/472.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在CustomElement中对self(this)的引用_Javascript_Custom Element - Fatal编程技术网

Javascript 在CustomElement中对self(this)的引用

Javascript 在CustomElement中对self(this)的引用,javascript,custom-element,Javascript,Custom Element,我用它在JavaScript中实现了一个自定义元素。但是,self变量在我的方法中引用窗口,除非我首先调用const self=this 有人能向我解释一下为什么会这样,并建议一种更好的方法来访问方法中的自定义元素实例吗 class DocumentPreview extends HTMLElement { constructor(self, documents) { self = super(self); self.documents = documents || [];

我用它在JavaScript中实现了一个自定义元素。但是,
self
变量在我的方法中引用
窗口
,除非我首先调用
const self=this

有人能向我解释一下为什么会这样,并建议一种更好的方法来访问方法中的自定义元素实例吗

class DocumentPreview extends HTMLElement {
  constructor(self, documents) {
    self = super(self);
    self.documents = documents || [];
    self.innerHTML = Handlebars.templates['document_preview']();
  }

  connectedCallback() {
    // if I don't do this first ...
    const self = this;   // <<----------------------------------
    console.log("connected now");
    document.addEventListener('mqttsub', function(event) {
      // ... onMessage is undefined here:
      self.onMessage(event.detail);
    });
  }

  disconnectedCallback() {
    console.log("disconnected");
  }

  onMessage(message) {
    // Same story ...
    const self = this;   // <<----------------------------------
    Promise.resolve(true)
    .then(json("/documents/"))
    .then(ds => ds
      .filter(x => x.name==message.payload)
      .reduce((x, y) => y, undefined)
    )
    .then(d => json(sprintf("/document/%d/", d.id))())
    // ... here:
    .then(d => self.renderDocuments(d))
    .catch(console.log);
  }

  renderDocuments(d) {
    console.log('render', d);
  }
}
class DocumentPreview扩展了HtmleElement{
建造商(自身、文件){
self=超级(self);
self.documents=文档| |[];
self.innerHTML=handlebar.templates['document_preview']();
}
connectedCallback(){
//如果我不先这么做。。。
const self=this;//json(sprintf(“/document/%d/”,d.id))())
//……这里:
。然后(d=>self.renderDocuments(d))
.catch(console.log);
}
渲染文档(d){
console.log('render',d);
}
}

在JavaScript中,
这个
关键字指的是当前函数的上下文

document.addEventListener('mqttsub', function(event) {
  // this here corresponds to your function(event) {...} context
  this.onMessage(event.detail); // Will fail
});
解决这个问题的一个简单方法是使用箭头函数。默认情况下,箭头函数使用外部上下文

document.addEventListener('mqttsub', (event) => {
  // this here corresponds to the outer context = your class
  this.onMessage(event.detail);
});
否则,还可以绑定上下文

document.addEventListener('mqttsub', (function(event) {
  this.onMessage(event.detail);
}).bind(this)); // Set the function context to be the class context

在JavaScript中,
这个
关键字表示当前函数的上下文

document.addEventListener('mqttsub', function(event) {
  // this here corresponds to your function(event) {...} context
  this.onMessage(event.detail); // Will fail
});
解决这个问题的一个简单方法是使用箭头函数。默认情况下,箭头函数使用外部上下文

document.addEventListener('mqttsub', (event) => {
  // this here corresponds to the outer context = your class
  this.onMessage(event.detail);
});
否则,还可以绑定上下文

document.addEventListener('mqttsub', (function(event) {
  this.onMessage(event.detail);
}).bind(this)); // Set the function context to be the class context

尝试使用
bind()
在构造函数中绑定方法
onMessage()
renderDocuments()
,如
this.methodName=this.methodName.bind(this)
。有了它,您可以通过
this
访问属性和方法

class DocumentPreview extends HTMLElement {
  constructor(documents) {
    super();

    this.documents = documents || [];
    this.innerHTML = Handlebars.templates['document_preview']();

    this.onMessage = this.onMessage.bind(this);
    this.renderDocuments = this.renderDocuments.bind(this);
  }

  connectedCallback() {
    document.addEventListener('mqttsub', this.onMessage);
  }

  disconnectedCallback() {
    console.log("disconnected");
  }

  onMessage(event) {
    const { detail: message } = event;

    Promise.resolve(true)
      .then(json("/documents/"))
      .then(ds => ds
        .filter(x => x.name==message.payload)
        .reduce((x, y) => y, undefined)
      )
      .then(d => json(sprintf("/document/%d/", d.id))())
      // ... here:
      .then(d => this.renderDocuments(d))
      .catch(console.log);
  }

  renderDocuments(d) {
    console.log('render', d);
  }
}

希望这有帮助

尝试使用
bind()
在构造函数中使用
this.methodName=this.methodName.bind(this)
绑定方法
onMessage()
renderDocuments()
。有了它,您可以通过
this
访问属性和方法

class DocumentPreview extends HTMLElement {
  constructor(documents) {
    super();

    this.documents = documents || [];
    this.innerHTML = Handlebars.templates['document_preview']();

    this.onMessage = this.onMessage.bind(this);
    this.renderDocuments = this.renderDocuments.bind(this);
  }

  connectedCallback() {
    document.addEventListener('mqttsub', this.onMessage);
  }

  disconnectedCallback() {
    console.log("disconnected");
  }

  onMessage(event) {
    const { detail: message } = event;

    Promise.resolve(true)
      .then(json("/documents/"))
      .then(ds => ds
        .filter(x => x.name==message.payload)
        .reduce((x, y) => y, undefined)
      )
      .then(d => json(sprintf("/document/%d/", d.id))())
      // ... here:
      .then(d => this.renderDocuments(d))
      .catch(console.log);
  }

  renderDocuments(d) {
    console.log('render', d);
  }
}

希望这有帮助

构造函数中的
self
参数不能被其他方法访问,这是一个基本的范围问题。如果使用的是
onMessage()
中的箭头函数,则不需要
self
变量,只需直接使用
this
。对于事件侦听器回调中的非箭头函数,您可以执行所显示的操作,也可以使用
。将(this)
与该回调绑定,然后将
this
而不是回调中的
self
。构造函数中的
self
参数不能被其他方法访问,这是一个基本的范围问题。如果使用的是
onMessage()
中的箭头函数,则不需要
self
变量,只需直接使用
this
。对于事件侦听器回调中的非箭头函数,您可以执行所显示的操作,也可以使用
。将(this)
与该回调绑定,然后在回调中使用
this
而不是
self
。非常好,最重要的是,它显著提高了可读性。快速一:在JS:
const{detail:message}=event中,这个构造被称为什么
这种模式匹配是否有一个特定的名称?OP的问题围绕在一个基本的层次上,不必将
这个
分配给每个方法内部的变量。
bind()
方法应该通过确保类方法绑定到所需的范围来帮助实现这一点@沖原ハーベスト 这在ES6中称为可用。在本例中,它使用键
detail
解压变量,并为其分配
消息的别名/名称。谢谢非常感谢@nnnnnn你完全正确,完全错过了。谢谢你指出这一点,我将更新它,改为调用
this.renderDocuments(d)
。谢谢很好,最重要的是它显著提高了可读性。快速一:在JS:
const{detail:message}=event中,这个构造被称为什么
这种模式匹配是否有一个特定的名称?OP的问题围绕在一个基本的层次上,不必将
这个
分配给每个方法内部的变量。
bind()
方法应该通过确保类方法绑定到所需的范围来帮助实现这一点@沖原ハーベスト 这在ES6中称为可用。在本例中,它使用键
detail
解压变量,并为其分配
消息的别名/名称。谢谢非常感谢@nnnnnn你完全正确,完全错过了。谢谢你指出这一点,我将更新它,改为调用
this.renderDocuments(d)
。谢谢