javaScript初学者很容易被“this”绕晕,函数在不同的地方被调用,其“this”所指代的值都是不同的。但其实只要你掌握了方法,“this”的指代很容易判断。本文就介绍这找出“this”值的方法。
方法一:看函数左侧有没有点号(.)
例子:
cat = {
name: 'tom',
sayName: function() {
console.log(`My name is ${this.name}.`);
}
}
cat.sayName(); // My name is tom.
在上面例子中,sayName
方法左侧有点号,那么点号左侧就是“this”的指向。在这里,“this”指向cat
。
方法二:call、apply和bind
call、apply和bind是每个函数都有的方法,主要作用是为函数指定执行上下文。在这种情况下,“this”指向call、apply或bind的第一个参数。
cat = {
name: 'tom'
}
function sayName() {
console.log(`My name is ${this.name}.`);
}
sayName.call(cat); // My name is tom.
这里的cat
对象没有sayName方法,不能直接用cat.sayName()
的方法来调用,所以我们用call
,为sayName
指定执行上下文,所以这里的“this”指向了cat
。 apply
除了传参方式,其他跟call一样。以下代码展示两者传参差异:
cat = {
name: 'tom'
}
todos = ['todo1', 'todo2'];
function sayName(todo1, todo2) {
console.log(`name: ${this.name},todo1: ${todo1},todo2: ${todo2}`);
}
sayName.call(cat, todos[0], todos[1]);
sayName.apply(cat, todos);
call
一个一个的传参,apply
用数组传参,两者就只有这么一个区别。
还有一个bind
,bind
用法大体跟call
一样,只是bind
不立即执行函数,而是返回一个函数:
sayNameHandler = sayName.bind(cat);
sayNameHandler();
方法三:“this”是不是在构造函数中
当“this”在构造函数中的时候,它指向用该构造函数生成的实例对象。
function User(name, age) {
this.name = name;
this.age = age;
}
user1 = new User('vincent', 17);
console.log(user1); // {name: "vincent", age: 17}
方法四:全局调用
当函数在全局作用域被调用的时候,“this”指向window
;严格模式下,“this”指向undefined
。
function sayName() {
console.log(this.name);
}
sayName(); // undefined
如果给window.name
赋值:
window.name = 'jerry';
function sayName() {
console.log(this.name);
}
sayName(); // jerry
this.name
就指向window.name
。
在严格模式下:
'use strict';
window.name = 'jerry';
function sayName() {
console.log(this.name);
}
sayName(); // Uncaught TypeError: Cannot read property 'name' of undefined
“this”指向undefined
。
以上就是本文的主要内容了,下面留一道思考题给你:
var name= 'tom';
var MyObj = {
name: 'jerry',
showName: function(){
console.log(this.name);
}
}
setTimeout(MyObj.showName,1000);
这里打印的是什么?