this
1、默认绑定
独立函数调用就是所谓的默认绑定
默认绑定时this指向全局对象window
<script>
function fn(){
console.log(this);
}
//独立函数调用
fn();
</script>
IIFE中的this表示的是window
2、隐式绑定
通过某个对象发起的函数调用称为隐式绑定,隐式绑定会将对象绑定到this上
隐式绑定必须在调用的对象内部有一个对函数的引用
<script>
function fn(){
console.log(this);
}
var obj = {
name: "cx",
fn:fn
}
//fn中this是谁,看.前面是谁
obj.fn();//隐式绑定,会将obj对象绑定到this上
</script>
3、显式绑定
如果不希望在对象内部包含这个函数的引用,还可以在这个对象上进行强制调用,可以使用call和apply方法。
1、call和apply
call和apply的第一个参数是相同的,都要求是一个对象,在调用这个函数时,会将this绑定到这个传入的对象上;后面的参数,call为参数列表,apply为数组。(call和apply的用法一样)
call和apply在函数中的作用:
- 1、显式绑定this
- 2、让函数执行
<script>
function fn(){
console.log("fn...");
console.log(this);
}
let obj = {name:"wc"}
//通过call可以显式绑定this为obj
fn.call(obj);
</script>
2、bind
bind的作用:
- 1、显式绑定this
- 2、不会让函数执行
- 3、返回一个绑定this之后的新函数
<script>
function fn(){
console.log("fn...");
console.log(this);
}
let obj = {name:"wc"}
let newFn = fn.bind(obj);
newFn();
</script>
附:
如果call,apply,bind后面跟的是基本数据类型,如下:
<script>
function fn(){
console.log("fn...");
console.log(this);
}
fn.call("hello");//会把"hello"包装成一个新的对象
fn.call(undefined);//参数是und,this指向window
fn.call(null);//参数是null,this指向window
</script>
如果在显式绑定中,传入一个null或者undefined,那么这个显式绑定会被忽略,使用默认规则
4、new绑定
使用new关键字来调用函数,会执行如下的操作:
1、创建一个全新的对象;
2、这个新对象会被执行prototype连接
3、这个新对象会绑定到函数调用的this上
4、如果函数没有返回其他对象,表达式会返回这个新对象
<script>
function Fn(){
this.name = "cx";
this.age = 20;
}
//创建一个空对象,绑定到this上,返回这个对象
let obj = new Fn();//new一个类,就得到一个对象
console.log(obj);
</script>
5、规则优先级
- 默认规则的优先级最低
- 显式绑定优先级高于隐式绑定
- new绑定优先级高于隐式绑定
- new优先级高于bind
- new绑定和call、apply不允许同时使用
附:
一些内置函数中也有this,并且这些this指向可以改变
例:
定时器中的this表示window
<script>
setTimeout(function(){
console.log(this);
},3000)
</script>
监听器中的this表示事件源
<div id="box">click me</div>
<script>
let box = document.getElementById("box");
box.onclick = function(){
console.log("hello DOM~");
console.log(this);//监听器中的this表示事件源
}
</script>
6、箭头函数this
箭头函数并不绑定this对象,那么this引用就会从上层作用域中找到对应的this。
<script>
console.log(this); //window
var fn = () => {
//箭头函数中的this都需要向外找一级
console.log(this);
}
fn(); //window
var obj = {name:"cx"}
fn.call(obj); //window
</script>