this 是函数执行时所在的上下文环境
js 全局对象:在 html 页面中引入的 js 文件 全局对象 是 window 对象,使用 node 命令执行 js 文件 全局对象 是 global 对象
console.log(this); // 全局对象
"use strict";
function a() {
console.log(this); // undefined
}
a();
// 构造函数
function A() {
this.name = "alias";
this.age = 20;
this.show = ()=>{
console.log(this);
}
}
console.log(new A()); // {name: 'alias', age: 20}
new A().show() // {name: 'alias', age: 20}
console.log(window.age); // undefined , 说明构造函数中的this不指向全局对象
// 外层直接调用:this 是全局对象
function a() {
this.username = "alias";
this.password = 123456;
}
a();
console.log(window.username); // alias
console.log(this.username); // alias
// 对象方法:this 的指向取决于调用对象方法的方式
const objB = {
xcxv: "xcxv",
getXcxv() {
console.log(this.xcxv);
},
};
objB.getXcxv(); // alias , 以对象的方法的方式调用:this 指向对象方法所在的对象
const bbb = objB.getXcxv;
bbb(); // undefined, 将对象的方法取出并在 script 标签外层调用:this 指向全局对象
<div onclick="show(this)">hello world</div>
<script>
function show(params) {
console.log(params); // 当前dom元素 <div onclick="show(this)">hello world</div>
}
</script>
- call、apply、bind 三者都可改变 this 的指向,且都只是临时的改变 this 的指向
- call 和 bind 方法传参方式一样,第一个参数是 this 指向的实例对象,其他是方法参数,以逗号隔开,区别是 bind 方法不立即执行,需要以方法的方式调用
- apply 方法,第一个参数是 this 指向的实例对象,其他是方法参数,放在数组中以逗号隔开
// 让 A 的 this 指向 B,并调用 A 函数,此时 A 和 B 的实例属性会合并
function A(p1, p2) {
this.a = 'AAAAA'
this.p1 = p1
this.p2 = p2
console.log(this);
}
var B = { b: "BBBBB" };
A.call(B, "x", "xx"); // 结果: { name: 'B' } x xx
A.apply(B, ["x", "xx"]); // 结果: { name: 'B' } x xx
A.bind(B, "x", "xx")(); // 结果: { name: 'B' } x xx
new A() //结果: {a: 'AAAAA', p1: undefined, p2: undefined},说明改变 this 指向只是临时的
// 父类
function A() {
this.name = "AAAAAAA";
this.age = 18;
}
// 子类
function B() {
this.BBBBB = "BBBBB"; // 与父类不同名的属性可以写在 A.call(this) 上面
A.call(this) // 将父类 A 的 this 指向子类 B 实例对象,并执行 A,此时 A 和 B 的实例属性会合并,也就是B继承了A实例属性(函数中this总是指向实例对象)
this.name = "B"; // 与父类同名的属性要写在 A.call(this) 下面,否则会在 A.call(this) 时被父类属性覆盖掉
}
console.log(new (A)); // {name: 'AAAAAAA', age: 18}
console.log(new (B)); // {BBBBB: 'BBBBB', name: 'B', age: 18}