javascript里函数的this指向
this简介
this是JavaScript的一个关键字,函数调用时才会出现; 一个函数在函数未调用时,this没有任何指向。
一、事件绑定
1. 行内绑定事件
行内绑定事件函数,this指向window 形式:<标签名 事件名 = “函数名();”></标签名>
<button onclick = "fn();"></button>
<script>
function fn(){
console.log(this);
}
</script>
2. 行内的this
行内的this指向当前节点对象 形式: <标签名 事件名 = “直接使用this;”></标签名>
<button onmousedown = "console.log(this);"></button> <!-- <button onmousedown = "console.log(this);"></button> -->
<button onclick = "fn(this);"></button>
<script>
function fn(a){
console.log(a);
}
</script>
3. 动态绑定事件
动态绑定事件的this指向绑定对象的节点对象 形式:节点对象.事件名(带on)= function(){}
<button></button>
<script>
let btnObj = document.querySelector("button");
btnObj.onclick = function () {
console.log(this);
}
</script>
4. 事件监听
语法:节点对象.addEventListener(event, function , usecapture);
第一个参数: 事件类型,不加on,要加引号; 第二个参数: 函数,触发事件后,需要执行的函数; 而第三个参数: 可选,布尔值,事件的捕获与冒泡, 为true(默认值)时捕获,false时冒泡。
事件监听的this指向绑定的节点对象。
<div id="div" style="width:20px;height:20px;background:red;"></div>
<script>
let btnObj = document.querySelector("#div");
btnObj.addEventListener('click', function () {
console.log(this);
}, false);
</script>
二、函数的调用
1. 普通调用
普通的函数调用this指向window 形式:函数名();
<script>
function fn(){
console.log(this);
}
fn();
</script>
2. 作为类的方法被调用
当函数作为类的方法被调用时,this指向调用方法的对象(谁调用就指向谁) 形式:实例对象.方法名();
<script>
function Obj(){
this.name = "zs";
this.say = function(){
console.log(this);
}
}
new Obj().say();
</script>
3. 作为构造函数被调用
作为构造函数被调用,this指向实例化的对象
<script>
function Obj(){
this.name = "zs";
console.log(this);
}
let a = new Obj();
</script>
三、箭头函数
箭头函数的this没有明确的指向,但它永远指向它的宿主对象
<script>
function Obj() {
this.name = "zs";
this.say = () => {
console.log(this);
}
this.print = function () {
var fn = () => {
console.log(this);
}
fn();
}
}
let a = new Obj();
a.say();
a.print();
</script>
当箭头函数的宿主(上级)是对象时,会发现this穿透现象,效果如下:
<script>
let Obj = {
name: "zs",
say: () => {
console.log(this);
},
print: {
fn: () => {
console.log(this);
}
},
a:function(){
var fn2= () =>{
console.log(this);
}
fn2();
}
}
Obj.say();
Obj.print.fn();
Obj.a();
</script>
四、call、apply、bind改变this指向
使用方法都是:函数名.方法名(this指向的对象,实参);
共同点:
- 三个方法的第一个参数都是想要this指向的对象
- 实参都可有多个
特点(区别):
- call :实参可以任意类型数据,与形参一一对应,改动的是原函数的this
- apply:第一个实参(即第二个位置的参数)必须是数组形式的数据,改动的是原函数的this
- bind:实参可以是任意类型的数据,且与形参一一对应,返回的是一个新的函数,改的也是新函数的this指向
call 例:
<script>
var a = {
fn: function () {
console.log(this);
}
}
var b = a.fn;
b();
b.call(a);
</script>
apply例:
<script>
var a = {
fn: function () {
console.log(this);
}
}
var b = a.fn;
b();
b.apply(a);
</script>
bind例:
<script>
var a = {
fn: function () {
console.log(this);
}
}
var b = a.fn;
b();
b.bind(a);
let c = b.bind(a);
c();
</script>
以上内容如有错误,欢迎指正。
|