概念:创建一个像JavaScript中的构造函数一样的函数

时间:2017-04-11 19:41:00

标签: javascript methods constructor properties prototype

我们想要一个可以将方法应用于输入对象的函数。

首先,我们创建一个函数。

$ = function () { /* Constructor Code */ };

然后,我们添加一个方法。例如,type。该方法将使用此功能:

function () { return toString.call(this).slice(8, -1);

最后,我们测试函数以查看是否获得了正确的输出。这就是我们想要看到的:

$("test"); // Output: "test"
$("test").type(); // Output: "String"
$(document.body).type(); // Output: "HTMLBodyElement"

输出应与输入不同的唯一方法是使用方法。

使用Object.addProperties无法正常工作,因为它将输入转换为对象:

$("test").type(); // Output: "Object"

此外,使用与eval相关的方法也不会有效,因为有些对象无法转换为字符串:

$(document.body).type(); // Error: Can't convert element to string!

将对象的属性手动添加到对象也是如此。

$("test").type(); // Can't apply function to literal string!

问题是,我们做了什么

1 个答案:

答案 0 :(得分:2)

一种方法是将方法应用于输入的原始版本。

这是通过Object.assign完成的。这是一个快速实施:

$ = function (_) {
  return Object.assign(_, {
    type: function () { return toString.call(this).slice(8, -1) }
  })
};

这是输出:

$("test").type() // Output: "String"
$(document.body).type() // Output: "Date"

我们也可以使用变量作为方法列表,它将返回相同的输出:

$ = function (_) {
  return Object.assign(_, $.methods)
};

$.methods = ({
  type: function () { return toString.call(this).slice(8, -1) }
});

但是,这些解决方案都需要valueOf来检索某些对象的原始输入:

$("test"); // Returns a "pseudo-string"
$("test").valueOf(); // Output: "test"

由于valueOf可能不安全,我们可以在方法列表中添加一个属性来获取原始输入:

$ = function (_) {
  return Object.assign(_, ({
    type: function () { return toString.call(this).slice(8, -1) }, val: _
  });
};

现在使用val将返回原始输出而不进行函数调用:

$("test").val // Output: "test"
$(document.body).val // Output: <body>...</body>

它还不错,但也许有办法用这些方法返回一个真正未修改的值?