functionuppercaseName() {returnthis.name.toUpperCase();}functionsayHi() {console.log(`Hello, I am ${uppercaseName.call(this)}, and ${this.age} years old.`);}let Tom = { name:'tom', age:8};let Jerry = { name:'jerry', age:9};sayHi.call(Tom);sayHi.call(Jerry);
没有this的情况:
functionuppercaseName(that) {returnthat.name.toUpperCase();}functionsayHi(that) {console.log(`Hello, I am ${uppercaseName(that)}, and ${that.age} years old.`);}let Tom = { name:'tom', age:8};let Jerry = { name:'jerry', age:9};sayHi(Tom);sayHi(Jerry);
原因2:没有this,class无法实现
classPerson {constructor(name, age){this.name = name;this.age = age; }uppercaseName() {returnthis.name.toUpperCase(); }sayHi() {console.log(`Hello, I am ${this.uppercaseName()}, and ${this.age} years old.`); }}
如果没有this,没办法将属性挂载到实例上,属性函数内部也无法相互调用
二、this指向谁
this一般出现在函数中,this的指向取决于函数执行场景,一般分为4个场景:
1、默认:this -> 全局变量(非严格模式)/上下文
var name = 'Tom';
function sayName() {
console.log(`Hi, I am ${this.name}!`);
}
//this隐式指向全局
sayName(); //严格模式指向undefined,非严格模式下正常
输出:
浏览器:
Hi, I am Tom!
node.js:
TypeError: Cannot read properties of undefined (reading 'name')
全局中this的指向:
浏览器:this -> window
node.js:this -> undefined
2、隐式:this -> 调用对象
let Tom = { name:"Tom",sayName:function () {console.log(`Hi, I am ${this.name}!`); },};Tom.sayName();functionsayHi() {console.log(`Hi, I am ${this.name}!`);}let Jerry = { name:"Jerry", sayName:Tom.sayName, sayHi: sayHi,};Jerry.sayName(); //this隐式指向JerryJerry.sayHi();
输出:
Hi, I am Tom!
Hi, I am Jerry!
Hi, I am Jerry!
3、显式:this -> 指定对象
let Tom = { name:"Tom",sayName:function () {console.log(`Hi, I am ${this.name}!`); },sayTitle(...titles) {this.sayName();console.log(`my title: ${[...titles].join("、")}`); },};Tom.sayName();Tom.sayTitle("developer");let Jerry = { name:"Jerry",sayName:function () {console.log(`Hi, I am ${this.name}!`); },};let Jack = { name:"Jack",};//this显式指向JeryTom.sayTitle.apply(Jerry, ["developer","programmer","engineer"]);Tom.sayTitle.apply(Jack, ["developer","programmer","engineer"]);
输出:
Hi, I am Tom!
Hi, I am Tom!
my title: developer
Hi, I am Jerry!
my title: developer、programmer、engineer
TypeError: this.sayName is not a function
4、new:this -> 新对象
new实例化时经典4步中的第3步
functionPerson(name) {this.name = name;this.sayName=function () {console.log(`Hi, I am ${this.name}!`); }}//this显式指向Person的实例let Tom =newPerson('Tom');Tom.sayName();let Jerry =newPerson('Jerry');Jerry.sayName();
三、破解this的困局
函数的调用方式决定了 this 的值(运行时绑定),this 不能在执行期间被赋值,并且在每次函数被调用时 this 的值也可能会不同: