1. 普通函数 this 指向window
function fn() {
console.log('普通函数的this' + this);
}
window.fn();
2. 对象的方法 this指向的是"这个对象"
var o = {
sayHi: function() {
console.log('对象方法的this:' + this);
}
}
o.sayHi();
3.构造函数 this 指向 ldh 这个实例对象 原型对象里面的this 指向的也是 ldh这个实例对象
function Star(name,age) {
this.name = name
this.age = age
console.log(this)
};
Star.prototype.sing = function() {
console.log(this.name + '在唱歌')
}
var ldh = new Star("张三",22);
console.log(ldh)
ldh.sing()
4. 绑定事件函数 this 指向的是函数的调用者 btn这个按钮对象
var btn = document.querySelector('button');
btn.onclick = function() {
console.log('绑定时间函数的this:' + this);
};
5.定时器函数 this 指向的是window
window.setTimeout(function() {
console.log('定时器的this:' + this);
}, 1000);
6. 立即执行函数 this指向window
改变this指向的方法
js提供了三种方法 call()
apply()
bind()
1.call
- call 第一个可以调用函数 第二个可以改变函数内的this 指向
var obj = {
name: 'andy'
}
function fn(a, b) {
console.log(this);
console.log(a + b);
};
fn.call(obj, 11, 230)
- call 的主要作用可以实现继承(call方法的第二个作用)
function Father(uname, age, sex) {
this.uname = uname;
this.age = age;
this.sex = sex;
}
function Son(uname, age, sex) {
Father.call(this, uname, age, sex);
}
var son = new Son('刘德华', 18, '男');
console.log(son);
2.apply
- 调用函数 第二个可以改变函数内部的this指向
- 但是他的参数必须是数组(伪数组)
var o = {
name: 'andy'
}
function fn(a, b) {
console.log(this);
console.log(a + b);
};
fn.apply(o, [1, 2])
3.bind
- 不会调用原来的函数 可以改变原来函数内部的this 指向
- 返回的是原函数改变this之后产生的新函数
应用场景:
有函数但不需要立即调用时
,但是又想改变这个函数内部的this指向此时用bind
var o = {
name: 'andy'
};
function fn(a, b) {
console.log(this);
console.log(a + b);
};
var f = fn.bind(o, 1, 2);
f();
- 应用场景举例
<button>点击</button>
<button>点击</button>
<button>点击</button>
var btns = document.querySelectorAll('button');
console.log(btns)
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function() {
this.disabled = true;
setTimeout(function() {
console.log(this)
this.disabled = false;
}, 2000);
}
}
call,apply,bind区别
call,apply,bind主要作用都是改变this指向的,但使用上略有区别,说一下区别:
call和apply的主要区别是在传递参数上不同,call后面传递的参数是以逗号的形式分开的,apply传递的参数是数组形式 [Apply是以A开头的,所以应该是跟Array(数组)形式的参数]
bind返回的是一个函数形式,如果要执行,则后面要再加一个小括号 例如:bind(obj,参数1,参数2,)(),bind只能以逗号分隔形式,不能是数组形式