一、作为独立函数调用
function printThis() {
return this;
}
console.log(printThis() === window) // 严格模式下打印 false,非严格模式下打印 true
在严格模式下 printThis 调用时 this 指向 undefined
。 非严格模式下 printThis 调用是 this 指向 window
。
二、作为对象中的方法调用
function printThis() {
return this;
}
const obj = {printThis}
console.log(obj.printThis() === window) // 输出 false
当函数被作为对象的方法调用时 obj.printThis(),此时 this 的指向为 obj
。
三、作为构造函数调用
new
关键字实例化
function Dog() {
this.name = 'Puppy'
}
/**
* 正确
* 通过 new 关键字实例化构造函数
*/
const dog = new Dog()
console.log(dog.name) // 输出 Puppy
/**
* 错误
*/
const dog = Dog()
console.log(dog.name) // 报错,name 找不到
作为构造函数调用时必须使用 new 关键字,返回的实例,也就是 dog,此时 dog 指向 Dog。
- 改变构造函数实例
const puppet = {
rules: false
};
function Emperor() {
this.rules = true;
return puppet;
}
const emperor = new Emperor();
console.log(emperor.rules); // 输出 false
虽然 Emperor 函数被当作构造函数调用时,this 指向使用构造函数的实例,也就是 emperor, 但是 Emperor 构造函数在实例化中返回 puppet,有返回值并且返回值是对象,此时的实例其实是 puppet,所以 emperor.rules 输出 false。
四、作为 apply、call、bind 方法调用
- Function.prototype.apply 方法和 Function.prototype.call 方法有什么异同?
-- 第一个参数为冒充对象的 this,不传 this 在非严格模式下指向 window,在严格模式下指向 undefined。
// 非严格模式
var sData = 'Wisen'
function display() {
console.log('sData value is %s ', this.sData);
}
display.call(); // sData value is Wisen
'use strict';
var sData = 'Wisen';
function display() {
console.log('sData value is %s ', this.sData);
}
display.call(); // 报错,'sData' of undefined
-- 参数格式不同,apply 接收数组字面量,实事上可以接收任何类数组的参数,NodeList
、arguments
,只要是有 length
属性并且是 (0..length-1)
范围的整数就可以。
fun.apply(this, ['a', 'b']);
fun.apply(this, new Array(['a', 'b']));
fun.apply(this, { length: 2, '0': 'a', '1': 'b' });
- 在浏览器中运行以下脚本,点击页面后,会打印出 false。请问为什么会打印出 false?
function Button() {
this.clicked = false;
this.click = function () {
this.clicked = true;
console.log(button.clicked, 'clicked');
};
}
const button = new Button();
document.addEventListener("click", button.click)
当点击的时候,this.clicked 指向的是点击的 DOM 元素,点击的 DOM 元素 clicked 属性置为 true,所以 button.clicked 依然打印 false。
- 修改代码打印 true
-- 箭头函数方式,箭头函数没有自己的 this 值,箭头函数中的 this 值是由初始定义的代码块上下文中的 this 决定的,也就是箭头函数被定义时 this 指向本次的构造函数。
function Button() {
this.clicked = false;
this.click = () => {
this.clicked = true;
console.log(button.clicked, 'clicked');
};
}
const button = new Button();
document.addEventListener("click", button.click)
-- bind
方式,调用时创建并返回改变 this 指向的函数,并在稍后手动执行,apply
、call
在调用时会立即执行。
function Button() {
this.clicked = false;
this.click = function () {
this.clicked = true;
console.log(button.clicked, 'clicked');
};
}
const button = new Button();
document.addEventListener("click", button.click.bind(button))