我正在通过在线阅读和编写一些简单的代码来学习JavaScript中的函数。我在网上文章中得到了以下示例
function toArray(obj) {
return Array.prototype.slice.call(obj);
}
Function.prototype.curry = function() {
if (arguments.length<1) {
return this; //nothing to curry with - return function
}
var __method = this;
var args = toArray(arguments);
return function() {
return __method.apply(this, args.concat(toArray(arguments)));
}
}
var add = function(a,b) {
return a + b;
}
var addTen = add.curry(10); //create function that returns 10 + argument
alert(addTen(20)); //alerts 30 correctly
然后我尝试在实例化函数的方法上尝试它。所以我试着跟随。但它给了我错误“无法获得未定义或空引用的属性'原型'在第二行。我知道这个错误与currying无关,但我搞砸了JS函数概念的一些基础知识。所以我哪里出错了。
function Person()
{
this.age = 15;
}
Person.ageAfter = function (years) {
return this.age + years;
}
var personObj = new Person();
var ageAfterFiveYears = personObj.ageAfter.prototype.curry(5); //**Error**
alert(ageAfterFiveYears());
答案 0 :(得分:4)
您不应在通话中包含原型:
var ageAfterFiveYears = personObj.ageAfter.curry(5);
“ageAfter”属性具有其值的功能,因此该功能可以像第一个示例中的功能一样访问“咖喱”功能。
当你在原型上调用它时,你函数中this
的值将是原型对象,而不是“ageAfter”函数。
另外,正如评论所指出的,你需要在原型上加上“ageAfter”:
Person.prototype.ageAfter = function(years) { ... }
编辑 - Alnitak指出的绑定问题也很重要。 (当我说“重要”时,我的意思是“使你的代码有效”。)
答案 1 :(得分:3)
您有两个问题:
ageAfter
函数不是实例方法 - 您已将其添加到“类”(即它有点像静态方法)。它应该添加到原型中。
当您对该函数进行操作时会丢失对象的上下文,因此您需要重新绑定上下文
e.g:
var ageAfterFiveYears = Person.prototype.ageAfter.curry(5).bind(personObj);
为您提供仅在当前实例上工作的功能,或者更好,正如@Pointy在评论中建议的那样,您应该将curried函数重新放回原型:
Person.prototype.ageAfterFiveYears = Person.prototype.ageAfter.curry(5);
然后将.ageAfterFiveYears
方法添加到每个 Person
对象。
答案 2 :(得分:1)
Curry不适用于您的用例。您需要绑定上下文,以便this
是您的personObj。
function Person() {
this.age = 15;
}
Person.prototype.ageAfter = function (years) {
return this.age + years;
}
var personObj = new Person();
var ageAfterFiveYears = personObj.ageAfter.bind(personObj, 5);
alert(ageAfterFiveYears());