JavaScript chaining method to function - TypeError: (intermediate value).methodName is not a function

JavaScript chaining method to function - TypeError: (intermediate value).methodName is not a function

我正在学习针对初学者的在线课程,该课程使用 apply/bind 方法为函数设置 'this' 上下文。

我看到您可以将 bind 方法直接链接到功能块,这对我来说是新的。所以这让我想到为什么我不能链接 bind/call/apply 以外的其他方法来影响返回值。

let obj = {
  name: 'john',
};

let sayHello = function() {
  return 'hello there ' + this.name;
}.apply(obj).toUpperCase();

let sayBonjour = function() {
  return 'Bonjour!';
}.toUpperCase();

console.log(sayHello);
console.log(sayBonjour());

在上面的示例中,为什么我可以在使用 apply 方法的 sayHello 函数上使用 .toUpperCase() 方法,而不是在不使用 apply 方法的 sayBonjour 函数上使用。在尝试这样做时,我得到了错误:

'Uncaught TypeError: (intermediate value).toUpperCase is not a function'.

我意识到这不是字符串方法(或其他方法)is/are 的使用方式,出于学习目的,我希望有人能解释是什么阻止我以这种方式使用该方法.

非常感谢您的宝贵时间和帮助

可以,但是您尝试在函数上使用 .toUpperCase。您可以在将由函数表达式返回的字符串上使用它。您可以使用 IIFE 来实现这一点。

let obj = {
  name: 'john',
};

let sayHello = function() {
  return 'hello there ' + this.name;
}.apply(obj).toUpperCase();

let sayBonjour = (function() {
  return 'Bonjour!';
})().toUpperCase();

console.log(sayHello);
console.log(sayBonjour);

此示例显示执行代码时发生的情况。

function print(value) {
 const str = Object.prototype.toString.apply(value);
 console.log("Type: " + str.slice(7, str.length - 1) + "\tValue: " + value);
}

let obj = {
 name: "john"
};
/*
let sayHello = function() {
 return 'hello there ' + this.name;
}.apply(obj).toUpperCase();
*/
// equals to
{
 console.log("sayHello case");
 let step1 = function () {
  return "hello there " + this.name;
 };
 print(step1);
 let step2 = step1.apply(obj);
 print(step2);
 let sayHello = step2.toUpperCase();
 print(sayHello);
}
/*
let sayBonjour = function() {
 return 'Bonjour!';
}.toUpperCase();
*/
// equals to
{
 console.log("sayBonjour case");
 let step1 = function () {
  return "Bonjour!";
 };
 print(step1);
 let sayBonjour = step1.toUpperCase();
 print(sayBonjour);
}