我们想要一个可以将方法应用于输入对象的函数。
首先,我们创建一个函数。
$ = function () { /* Constructor Code */ };
然后,我们添加一个方法。例如,类型
。该方法将使用这个函数:
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!
问题是,我们要做什么?
最佳答案
一种方法是将方法应用于输入的原始版本。
这是通过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>
这还不错,但也许有办法用方法返回一个真正未修改的值?
关于javascript - 概念 : Creating a function that acts like a constructor in JavaScript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43354832/