javascript绑定事件绑定-js中storm绑定和storm委托的3种方法_彻底理解JavaScript中的this点

2023-08-26 0 6,755 百度已收录

JavaScript中的this让很多开发者头疼,this关键字是一个非常重要的句点。 可以毫不夸张地说,如果不理解其含义,大多数开发任务都无法完成。

要理解这一点,首先可以记住以下两点:

1:this始终指向一个对象;

2:this的意义完全取决于函数调用的位置;

上面第一点很容易理解。 无论在哪里使用它,它都必须指向一个对象; 重点说明了这个问题,但关键是在JavaScript语言中,一切都是对象,运行环境也是对象,所以函数是在某个对象下运行的,而这就是函数所在的对象(环境)运行。 这本来并不让我们困惑,但是JavaScript支持运行环境的动态切换,也就是说this的指向是动态的,很难预先确定它指向哪个对象。 这是我们最困惑的地方。

先看原理

function fun(){
    console.log(this.s);
}
​
var obj = {
    s:'1',
    f:fun
}
​
var s = '2';
​
obj.f(); //1
fun(); //2

上面的代码中javascript绑定事件绑定,fun函数被调用了两次,很明显两次的结果是不同的;

很多人会这样解释,在obj.f()的调用中,因为运行环境在obj对象中,所以函数中的this指向对象obj;

而当在全局作用域中调用fun()时,函数中的this会指向全局作用域对象window;

但大多数人不会告诉你这个点为什么变化,这个点的变化是什么时候发生的; 了解了这些之后,这个的用处就不会出乎意料了;

首先我们要知道,在JS中,数组、函数、对象都是引用类型,在传递参数时也是按引用传递;

上面的代码中,obj对象有两个属性,但是属性的值类型不同javascript绑定事件绑定,在显存中的表示形式也不同;

调用时看起来像这样:

因为函数在js中可以作为值传递和返回,也可以作为对象和构造函数,所以所有的函数在运行时都需要确定自己当前的运行环境,而这就是诞生的,所以这会根据运行环境而改变并且改变,同时函数中的this只能在运行时最终确定运行环境;

看看下面的代码,你可能会更加了解这个对于运行环境的动态切换规则:

var A = {
    name: '张三',
    f: function () {
        console.log('姓名:' + this.name);
    }
};
​
var B = {
    name: '李四'
};
​
B.f = A.f;
B.f()   // 姓名:李四
A.f()   // 姓名:张三

上面代码中,将Af属性赋值给Bf,即A对象将匿名函数的地址赋值给B对象;

然后在调用时,函数根据运行环境的不同,分别指向对象A和B。

function foo() {
    console.log(this.a);
}
var obj2 = {
    a: 2,
    fn: foo
};
var obj1 = {
    a: 1,
    o1: obj2
};
obj1.o1.fn(); // 2

obj1对象的o1属性值为obj2对象的地址,obj2对象的fn属性值为函数foo的地址;

函数foo的调用环境在obj2中,所以this指向对象obj2;

那么,我们来总结一下这个最常用的情况。 最常见的是以下五种:

对象中的方法、事件绑定、构造函数、定时器、函数对象的call()、apply()方法;

上面解释的this的原理是我们在对象方法中使用this来解释的,所以这里不再重复解释,不懂的朋友请回去再看一遍;

事件绑定中的 this

事件绑定有三种形式:内联绑定、动态绑定、事件监听;

内联绑定的两种情况:



    function clickFun(){
        this // 此函数的运行环境在全局window对象下,因此this指向window;
    }

​

内联绑定storm的句型在html节点中,通过节点属性的方法进行绑定,属性名称为storm名称后的“on”,属性的值为可执行的JS代码段; 而属性值最常见的是函数调用;

当风暴触发时,属性值将作为JS代码执行。 当前运行环境中没有clickFun函数,所以浏览器需要跳出当前运行环境,在整个环境中找到一个名为clickFun的函数并执行这个函数,因此该函数内部的this指向全局对象window ; 如果不是函数调用并且直接在当前节点对象的上下文中使用this,那么即使this也会指向当前节点对象;

动态绑定和风暴攻击:



    var btn = document.getElementById('btn');
    btn.onclick = function(){
        this ;  // this指向本节点对象
    }

因为动态绑定的storm是将节点对象的属性重新参数化(事件名后加‘on’)为一个匿名函数,所以该函数是在节点对象的环境中执行的,而this自然指向节点对象;

事件监听中这一点的原理与动态绑定基本相同,不再赘述;

构造函数中的 this

function Pro(){
    this.x = '1';
    this.y = function(){};
}
var p = new Pro();

对于接触过JS面向对象编程的朋友来说,上面的代码和图基本上都能看懂。 创建新的构造函数并执行函数内部代码的过程分为五个步骤。 当 JS 引擎指向第三步时,this 将被强制指向新创建的对象; 基本不用懂,因为这是JS中的语法规则,记住就好;

这在窗口计时器中

var obj = {
    fun:function(){
        this ;
    }
}
​
setInterval(obj.fun,1000);      // this指向window对象
setInterval('obj.fun()',1000);  // this指向obj对象

setInterval() 是 window 对象下的外部方法。 它接受两个参数。 第一个参数可以是一个函数或者一段可执行的JS代码,第二个参数是执行下面的函数或者代码的时间。 间隔;

前面的代码中,setInterval(obj.fun,1000)的第一个参数是obj对象的fun,因为JS中的函数可以通过引用作为值传递,实际上这个函数的地址传递为给定了一个参数setInterval方法,也就是说setInterval的第一个参数接受一个函数,那么1000毫秒后,该函数的操作已经在window对象下了,也就是说,该函数的调用者已经成为了window对象,所以里面的this指向全局window对象;

setInterval('obj.fun()',1000)中的第一个参数实际上是传入的一段可执行的JS代码; 当JS引擎在1000毫秒后执行这段代码时,它通过obj对象找到fun函数并调用它执行,那么该函数的运行环境仍然在对象obj中,因此函数内部的this也指向obj目的;

函数对象的call()、apply()方法

函数以对象的形式提供 call() 和 apply() 方法,它们也可用于调用函数。 这两个方法都接受一个对象作为参数,用于指定本次调用时函数中this的方向;

调用()方法

通话模式使用的语法规则

函数名.call(obj,arg1,arg2...argN);

参数说明:

obj:函数中this要指向的对象,

arg1,arg2...argN:参数列表,用冒号分隔

var lisi = {names:'lisi'};
var zs = {names:'zhangsan'};
function f(age){
    console.log(this.names);
    console.log(age);
    
}
f(23);//undefined
​
//将f函数中的this指向固定到对象zs上;
f.call(zs,32);//zhangsan

apply() 方法

函数名.apply(obj,[arg1,arg2...,argN])

参数说明:

obj : this 所指向的对象

[arg1,arg2...argN] :参数列表,要求格式为链表

var lisi = {name:'lisi'}; 
var zs = {name:'zhangsan'}; 
function f(age,sex){
    console.log(this.name+age+sex); 
}
//将f函数中的this指向固定到对象zs上;
f.apply(zs,[23,'nan']);

注意:call和apply的功能是一样的,只是函数参数传递的方式不同;

这两个方法最大的作用基本上就是在指定函数调用时强制指向this;

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 javascript javascript绑定事件绑定-js中storm绑定和storm委托的3种方法_彻底理解JavaScript中的this点 https://www.wkzy.net/game/154257.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务