【问题标题】:JavaScript Function Get ObjectJavaScript 函数获取对象
【发布时间】:2018-06-15 17:27:00
【问题描述】:

函数有没有办法在函数名之前获取对象值?下面是我想要实现的一个例子。我希望能够在函数中读取 myElement 变量,但不将其作为参数传递,而是在带点的函数之前传递它。

任何简单的例子或解释都会很有帮助。

var myElement = document.getElementById('myID');

myElement.myFunction();

function myFunction() {
     alert(myElement);
}

【问题讨论】:

  • myElement.myFunction 未定义(与myFunction 无关),因此您一开始就没有要调用的函数。
  • @melpomene 是的,你是对的。我正在尝试做的是创建一个与下面的链接一样工作的函数,但它不是 getAttribute() 它可以是我自己的函数。 pastebin.com/ZYvxYXyQ
  • “但不将其作为参数传递” 为什么不呢?那将是最明智的做法。

标签: javascript object methods


【解决方案1】:

您可以这样做的唯一方法是将myFunction 添加到HTMLElements 原型(这是document.getElementById().That's usually frowned upon 返回的内容,但如果这是您自己的项目并且您知道自己在做什么,你可以这样做。

var myElement = document.getElementById('myID');

HTMLElement.prototype.myFunction = function() {
  console.log(this);
}

myElement.myFunction();
<div id="myID"></div>

有了这个原型,您可以在代码中的每个 HTMLElement 上调用 myFunction


关于您的最后一条评论,函数可能是

HTMLElement.prototype.myFunction = function() {
  alert(this.id);
}

我不明白你为什么要这样做,因为这样做更容易

alert(myElement.id);

关于 cmets,这就是我要做的。与其扩展任何东西,不如创建你自己的类(或函数),它需要一个 HTMLElement。现在在这个类上,你可以添加任何你想要的方法,操作你的元素,然后从 getter 中返回普通的 HTMLElement。您显然可以将其更改为您想要的任何回报。

class MyHtmlElement {
  constructor(htmlElement) {
    this._htmlElement = htmlElement;
  }

  alertId() {
    alert(this._htmlElement.id);
    // optional
    return this;
  }

  logId() {
    console.log(this._htmlElement.id);
    // optional
    return this;
  }
  
  setId(newId) {
    this.htmlElement.id = newId;
    // optional
    return this;
  }

  setStyle(prop, val) {
    this._htmlElement.style[prop] = val;
    // optional
    return this;
  }

  get htmlElement() {
    return this._htmlElement;
  }

  set htmlElement(value) {
    this._htmlElement = value;
  }
}

const el = new MyHtmlElement(document.getElementById('foo'));

el
  .setId('bar')
  .logId()
  .alertId()
  .setStyle('background-color', 'red')
  .setStyle('width', '100vw')
  .setStyle('height', '100vh');
  
// If you need the plain element, return it

const plainHTMLElement = el.htmlElement;
console.log(plainHTMLElement);
<div id="foo"></div>

【讨论】:

  • 为什么不受欢迎?
  • 我在问题文本中添加了一个链接,请在做之前检查一下。 stackoverflow.com/questions/14034180/… ...就像我说的,如果是你自己的项目,并且代码不会在插件或库中使用,那应该不是太大的问题
  • @Peter 修改现有类只是糟糕的设计,它破坏了封装。向 HTMLElement 原型添加新方法会令其他人感到困惑,也会令 Future You 感到困惑,他们明年会回到这段代码并摸不着头脑。浏览器更新也有可能添加同名的方法,与您的自定义方法冲突。
  • @JacqueGoupil 所以与示例 A myOwnFunction(element) 发生冲突的可能性比示例 B element.myOwnFunction() 更小?我的函数覆盖另一个同名函数的几率是多少?
  • @Peter 风险很小,有办法避免这种情况,但老实说,我认为此时我只是想让你对 JavaScript 的怪癖感到困惑。我建议先学习 OOP 的基本原理。
【解决方案2】:

当一个函数存储在一个对象中,然后用theObject.theFunction()调用时,函数内this的值将是theObject

function sayHello() {
  alert('Hello, my name is ' + this.name);
}

let myObject = { name: 'Bob', speak: sayHello };
myObject.speak(); // shows the message 'Hello, my name is Bob'

现在,如果您希望能够创建自己的函数并让元素使用它,您要么需要先将函数存储在 Element 实例中,要么将其添加到 Element 原型中,这两者我都非常重视不鼓励。如果您觉得必须这样做,则说明您的设计存在缺陷。

不过,如果您有充分的理由向现有对象添加自定义方法,我建议您查看有关 JavaScript 中原型继承的课程,或者如果您不确定它是如何工作的,请在此处阅读 my old answer 了解它.你可以说,创建一个函数,在调用对象时向它添加方法,如下所示:

function addMethods(elem) {
  elem.speak = sayHello;
}

let myElement = document.getElementById('myID');
addMethods(myElement);

myElement.speak(); // Hello, my name is <value of the element's name attribute>

或者您可以将方法添加到所有元素的原型中:

Element.prototype.speak = sayHello;
let myElement = document.getElementById('myID');
myElement.speak();

虽然浏览器从很久以前就允许人们这样做,但从技术上讲,不能保证 Element 是公开可用的,或者它的原型是可修改的,或者您可以向 Element 实例添加方法。 Prototype 框架(一个不方便命名的第三方库)已经使用这些技术很长时间了,但它确实给它们带来了一些问题。 jQuery 更喜欢使用不同的方法,将元素包装在另一个放置自定义方法的对象中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    相关资源
    最近更新 更多