Code is never die !
1.0 函数内部的 this 指向
- 这些 this 的指向,是当我们调用函数的时候确定的
- 调用方式的不同决定了 this 的指向不同
- 一般指向我们的调用者
- 总结如下:
调用方式 |
this 指向 |
普通函数调用 |
window |
构造函数调用 |
实例对象,原型对象里面的方法也指向实例对象 |
对象方法调用 |
该方法所属对象 |
事件绑定方法 |
绑定事件对象 |
定时器函数 |
window |
立即执行函数 |
window |
代码:
<button>点击</button> <script> function fn() { console.log('普通函数的this' + this); } window.fn(); var o = { sayHi: function() { console.log('对象方法的this:' + this); } } o.sayHi(); function Star() {}; Star.prototype.sing = function() {
} var ldh = new Star(); var btn = document.querySelector('button'); btn.onclick = function() { console.log('绑定时间函数的this:' + this); }; window.setTimeout(function() { console.log('定时器的this:' + this);
}, 1000); (function() { console.log('立即执行函数的this' + this); })(); </script>
|
2.0 改变函数内部 this 指向
改变函数内 this 指向 js 提供了三种方法 call() apply() bind()
2.1 call 方法
- call()方法调用一个对象
- 简单理解为调用函数的方式,但是它可以改变函数的 this 指向
- 应用场景: 经常做继承
- call:打电话,在程序中有调用的意思
- 代码:
var o = { name: 'andy', }; function fn(a, b) { console.log(this); console.log(a + b); } fn(); fn.call(o, 1, 2);
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.2 apply 方法
- apply() 方法调用一个函数
- 简单理解为调用函数的方式,但是它可以改变函数的 this 指向
- 应用场景: 经常跟数组有关系
- apply:应用,运用
- 代码:
var o = { name: 'andy', }; function fn(a, b) { console.log(this); console.log(a + b); } fn(); fn.apply(o, [1, 2]);
var arr = [1, 66, 3, 99, 4]; var arr1 = ['red', 'pink'];
var max = Math.max.apply(Math, arr);
var min = Math.min.apply(Math, arr); console.log(max, min);
Math.max(1, 2); Math.max(1, 2, 3);
|
2.3 bind 方法
bind() 方法不会调用函数,但是能改变函数内部 this 指向,返回的是原函数改变 this 之后产生的新函数
如果只是想改变 this 指向,并且不想调用这个函数的时候,可以使用 bind
应用场景:不调用函数,但是还想改变 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();
var btns = document.querySelectorAll('button'); for (var i = 0; i < btns.length; i++) { btns[i].onclick = function () { this.disabled = true; setTimeout( function () { this.disabled = false; }.bind(this), 2000 ); }; }
|
2.4 call、apply、bind 三者的异同
共同点: 都可以改变 this 指向
不同点:
- call 和 apply 会调用函数, 并且改变函数内部 this 指向.
- call 和 apply 传递的参数不一样,call 传递参数使用逗号隔开,apply 使用数组传递
- bind 不会调用函数, 可以改变函数内部 this 指向.
应用场景
- call 经常做继承
- apply 经常跟数组有关系. 比如借助于数学对象实现数组最大值最小值
- bind 不调用函数,但是还想改变 this 指向. 比如改变定时器内部的 this 指向
Ending…