未定义的NodeJS'toUpperCase'(由typescript生成)
为什么这个工作,当我从nodejs发射:
var a = function (name) { return "Hello, " + name.toUpperCase(); }; var result = a("bob"); console.log(result)
但是这个:
var A = (function () { function A(msg) { this.msg = " "; this.msg = msg; } A.prototype.hello = function (name) { return "Hello, " + name.toUpperCase(); }; A.prototype.helloToBob = function (fn) { return fn.apply("Bob"); }; return A; })(); var test = new A("some message"); var msg = test.hello("Bob1"); var msg2 = test.helloToBob(test.hello); console.log(msg);
失败:
return "Hello, " + name.toUpperCase(); ^ TypeError: Cannot call method 'toUpperCase' of undefined
?
该JS代码从TypeScript代码生成/编译(编译没有错误)
问题在于这行代码。
return fn.apply("Bob");
这里有几个问题。
-
.apply(obj, arrayOfArguments)
的第一个参数需要是在方法调用期间希望this
指针设置为的对象。 -
.apply()
的第二个参数是一个参数数组,而不是一个参数。
这里有一个可能的解决scheme,你用this
作为对象并切换到fn.call()
因为fn.apply()
接受一个参数数组,但是你只有一个参数。
改变这个:
return fn.apply("Bob");
对此:
return fn.call(this, "Bob");
而且,所有的代码在一起:
var A = (function () { function A(msg) { this.msg = " "; this.msg = msg; } A.prototype.hello = function (name) { return "Hello, " + name.toUpperCase(); }; A.prototype.helloToBob = function (fn) { return fn.call(this, "Bob"); }; return A; })(); var test = new A("some message"); var msg = test.hello("Bob1"); var msg2 = test.helloToBob(test.hello); console.log(msg);
仅供参考,还有其他解决scheme。 你也可以这样做:
var A = (function () { function A(msg) { this.msg = " "; this.msg = msg; } A.prototype.hello = function (name) { return "Hello, " + name.toUpperCase(); }; A.prototype.helloToBob = function (fn) { return fn("Bob"); }; return A; })(); var test = new A("some message"); var msg = test.hello("Bob1"); var msg2 = test.helloToBob(test.hello.bind(test)); console.log(msg);
因为应该传递给apply()的第一个参数是上下文对象,所以它不是函数本身的第一个参数。 检查文档。
由于helloToBob()是A的类方法,我假设,你打算在当前对象的上下文中调用fn,这是你在做什么:
A.prototype.helloToBob = function (fn) { return fn.apply(this, ["Bob"]); }; // or, since you have a single static argument, use function.call instead: A.prototype.helloToBob = function (fn) { return fn.call(this, "Bob"); };