平时遇到的this指向问题
例1
function a() {
this.a = 1;
console.log(this); // window
}
a(); // 执行a或者window.a后this指向到window
const aa = new a(); // 构造函数方式 打印this为a {a: 1}
console.log(aa.a); // => 1
例2
const a = {
a: 'isa',
say: function(name) {
console.log(this.a + ': ' + name)
}
}
a.say('yuan') // say方法this指向为a
// 如果将say改变成es6箭头函数写法?
const a = {
a: 'isa',
say: (name) => {
console.log(this.a + ': ' + name)
}
}
// 执行a.say
a.say('yuan');
// this.a 为undefined 因为箭头函数没有他自己的this,所以指向父级window
例3
const a = {
a: 'isa',
say: function(name) {
console.log(this.a + ': ' + name)
}
}
function b(name) {
this.a = 'isb';
this.setA = (val) => {
this.a = val;
}
}
a.say('我叫a'); // => isa: 我叫a
b.apply(a, ['1']); // b的this指向到a的this上
b.call(a, '2');
b.bind(a)('3');// or b.bind(a, '3');
// apply, call, bind, 方法都可改变this的指向
// 此时不改变a,通过b可以改变a的属性值
a.say('我叫b'); // => isb: 我叫b
// 现在我们希望利用b.setA方法动态改变this.a
const bb = new b('bb');
bb.setA(11);
// 运行a.say发现this.a没有改为11,看例4使用prototype
a.say('我叫11'); // => isb: 我叫11
// 假如我们再加一个方法c,同时让它this指向b,也可以改变this.a
function c() {
this.c = 'c';
this.a = 'isc';
}
c.call(b); // 使用call改变this
a.say('我叫c'); // => isb: 我叫c 并没有改变为isc
// b的this指向是可以拿到,但是a的没有,需要通过b方法做指向
function b(name) {
this.a = 'isb';
this.setA = (val) => {
this.a = val;
}
c.call(this); // 写在b方法里
}
a.say('我叫c'); // => isc: 我叫c 通过c改变了a
例4
const a = {
a: 'isa',
say: function(name) {
console.log(this.a + ': ' + name)
}
}
function b(name) {
this.a = 'isb';
this.setA = (val) => {
this.a = val;
}
c.call(this);
}
function c() {
this.c = 'c';
this.a = 'isc';
}
b.prototype = a;
const bb = new b('bb');
bb.say('我叫b'); // => isb: 我叫b
bb.setA('setA');
bb.say('我叫b, 改变了a'); // => setA: 我叫b, 改变了a
c.prototype = new b('cc');
const cc = new c();
cc.say('我叫c'); // => isc: 我叫c
b.prototype.newSay = function() {
console.log(this.a);
}
bb.newSay(); // => setA
// 可以发现后面在原型上增加的方法调用bb也是可以找到最后设置的setA