直接使用对象

时间:2016-08-16 20:57:10

标签: javascript html css

我正在创建一个接收选择器作为参数的对象,它有一个名为 stylise 的方法,用于更改HTML元素的CSS(s )选中。

代码:

/* ----- JavaScript ----- */
function get(selector) {
    var
        self = {},
        elements = Array.from(document.querySelectorAll(selector));
    
    this.stylise = function(object) {
        Object.keys(object).forEach(function(propertyName) {
            for (var index = 0; index < elements.length; index++) {
                elements[index].style[propertyName] = object[propertyName];
            };
        });
    };
    
    return Object.setPrototypeOf(self, this.prototype);
};
<!----- HTML -----> 
<input id = "text" type = "text" style = "padding: .5em .7em;"/>

如果跳过 return Object.setPrototypeOf(self, this.prototype); 行,则上述代码将按预期工作,如下所示:

var a = new get("#text");
a.stylise({
    backgroundColor: "yellow",
    borderRadius: "5px"
});

但是,我希望通过调用它来实现上述目的:

get("#text").stylise({
    backgroundColor: "yellow",
    borderRadius: "5px"
});

我尝试使用 Object.setPrototypeOf(self, this.prototype) 来实现这一目标,但无效,因为我在控制台中收到以下错误: Object doesn't support property or method 'stylise'

我的代码的哪一部分导致了这个问题,我该如何解决?

1 个答案:

答案 0 :(得分:5)

您不需要setPrototypeOf(非常非常少的情况,这是您要达到的目标),只需让get返回您创建并分配给{的对象{1}}并分配给self而不是self.stylise

this.stylise
/* ----- JavaScript ----- */
function get(selector) {
    var
        self = {},
        elements = Array.from(document.querySelectorAll(selector));
    
    self.stylise = function(object) {
        Object.keys(object).forEach(function(propertyName) {
            for (var index = 0; index < elements.length; index++) {
                elements[index].style[propertyName] = object[propertyName];
            };
        });
    };
    
    return self;
}
get("#text").stylise({
    backgroundColor: "yellow",
    borderRadius: "5px"
});

实际上,您可以在对象初始值设定项中创建<!----- HTML -----> <input id = "text" type = "text" style = "padding: .5em .7em;"/>。您还可以在stylise上使用forEach

elements
/* ----- JavaScript ----- */
function get(selector) {
  var elements = Array.from(document.querySelectorAll(selector));

  return {
    stylise: function(object) {
      Object.keys(object).forEach(function(propertyName) {
        elements.forEach(function(element) {
          element.style[propertyName] = object[propertyName];
        });
      });
    }
  };
}
get("#text").stylise({
  backgroundColor: "yellow",
  borderRadius: "5px"
});

你在其他地方已经说过要在构造函数之外定义<!----- HTML -----> <input id="text" type="text" style="padding: .5em .7em;" />(将stylise放在对象上就好了)。如果是这样,您可以使用elements创建由特定原型对象支持的对象(在我们的示例中为Object.create);这样做get.prototype在调用构造函数之前创建对象时所执行的操作,但是您已经说过不想使用new

请注意,此示例首先通过new创建两个对象,然后在其上调用get;在这种情况下,您发布尝试执行此操作的各种尝试都将失败:

stylise
/* ----- JavaScript ----- */

// The builder function
function get(selector) {
  // Create a new object we'll return, backed by `get.prototype`
  var obj = Object.create(get.prototype);
  
  // Put the elements matching the selector on it
  obj.elements = Array.from(document.querySelectorAll(selector));
  
  // Return it
  return obj;
}

// Add `stylise` to the prototype `get` assigns objects
get.prototype.stylise = function(object) {
  // Get our elements, so we don't have to worry about `this` in the callbacks below
  var elements = this.elements;
  
  // Style them
  Object.keys(object).forEach(function(propertyName) {
    elements.forEach(function(element) {
      element.style[propertyName] = object[propertyName];
    });
  });
};

// Using it
var t1 = get("#text1");
var t2 = get("#text2");
t1.stylise({
  backgroundColor: "yellow",
  borderRadius: "5px"
});
t2.stylise({
  backgroundColor: "green",
  borderRadius: "10px"
});

旁注:函数声明后面不需要<!----- HTML -----> <input id="text1" type="text" style="padding: .5em .7em;" /> <input id="text2" type="text" style="padding: .5em .7em;" />(虽然把它放在那里是无害的)。 ;用于终止语句。声明不是声明。