勤奋鸟旗下 软件定制开发 安全交付平台!一次合作,终身售后!全程项目经理一对一跟进测试!公司以自研团队结合搭档圈,为用户提供安全快速稳定的软件源码开发服务!

javascript的this指向

2024-09-04 16:59:16
复制链接

2612

javaScript

接触js这么久,经常因为this指向问题头疼,前两天我在网上好好了解了一下this,并整理了相对来说比较易懂的讲解,希望能有帮助!

this的那些绑定规则

常见的绑定规则有如下四种:

  1. 默认绑定
  2. 隐式绑定
  3. 显示绑定
  4. new 绑定
   接下来让我们好好说道说道。

默认绑定

什么是默认绑定?默认绑定不就是什么处理都不做的时候的绑定规则吗?很显然就是我们直接调用函数的时候,这时候就是默认绑定。不需要多说,默认绑定的this就是window

全局调用全局函数

在全局定义的函数,直接调用,很明显绑定的是window

function foo(){
    console.log(this);
}

// window
foo()

函数内调用全局函数

在全局定义的函数,如果在其他函数内调用,那么this是绑定的是那个对象?肯定还是window了,毕竟函数还是直接调用嘛。

function foo(){
    console.log(this);
}
function bar(){
    foo();
}
// window
bar()

隐式绑定

隐式绑定就是通过对象的形式调用函数。其实也可以说是调用方法,因为这些函数都是定义在对象上的。当然方法只是函数在不同位置的叫法而已,这里不需要纠结。

比如我们定义对象obj,并在上面定义方法(函数)foo。那么通过对象obj调用函数foo,绑定的this的值会是????

var obj = {
	name: "zs",
    foo: function(){
        console.log(this);
    }
}
// ?
obj.foo(); // obj

当然隐式绑定的this的值是对象obj了。那么结果显而易见,隐式绑定的优先级是大于默认绑定的。

而隐式绑定调用的函数的this的指向可以理解为,谁调用,this就指向谁。之所以我们说是叫做隐式绑定,是因为我们没有在函数上直接绑定this的值是xxx对象。

显示绑定

显示绑定就是显示的告诉函数,我要绑定this的值是xxx对象。

全局函数显示绑定this

定义的全局函数,如果在执行的时候,直接显示的绑定this的值,那么很显然,this的值肯定是我们手动绑定上去的喽!

function foo(){
      console.log(this);
    }
foo(); // window
foo.call("123"); // '123'
foo.apply(123); // 123
foo.bind({name:"zzz"})(); // {name: "zzz"}

结果可以证明: 显示绑定的this的优先级是大于默认绑定规则的。

那么接下来我们应该比较一下显示绑定和隐式绑定的优先级。

对象的方法(函数)显示绑定this

我们定义一个对象,并对该函数的方法进行显示的绑定,看其中的this是指向哪里的。

 var obj = {
     name: "zs",
     foo: function () {
         console.log(this);
     }
 }
obj.foo.call("123"); // '123'
obj.foo.apply("123"); // '123'
obj.foo.bind("123")(); // '123'

通过取出对象obj的方法foo,然后对其进行显示的this绑定,我们发现结果是:this的指向是我们显示绑定的对象。

那么这样是否就证明了:显示绑定的优先级就一定大于隐式绑定?其实不然,我们通过对象.方法名的形式,已经是直接取出了这个定义在方法中的函数的引用,接下来进行该函数的显示绑定,严格来说已经和对象obj没有关系了。

var obj = {
      name: "zs",
      foo: function () {
        console.log(this);
      }
    }
    var fn = obj.foo;
    fn(); // window

可以看见,取出了对象中定义的函数,然后在进行调用,可以对比函数直接定义在全局中,然后通过默认绑定规则的调用该函数,所以最终this也是绑定在全局对象window上的。

那么,我们要如何证明显示绑定和隐式绑定的优先级的大小呢?

我们的目的就是进行显示的绑定this,且隐式的调用这个显示绑定的函数,这样最终的this指向,就可以证明出我们两种方式的优先级了。

我们实现定义好函数,然后定义对象obj,且将定义好的全局函数通过显示的绑定this的值,然后将这个显示绑定好this的函数赋值给obj对象的foo属性。最后通过obj.foo()调用该函数,就知道显示绑定和隐式绑定的优先级了。

function foo(){
    console.log(this);
}
var obj = {
    name: "zs",
    foo: foo.bind("123")
}
obj.foo(); // "123"

根据结果,我们可以知道,显示绑定this的优先级肯定是大于隐式绑定的。

new 绑定

new绑定,其实就是通过构造函数创建对象。当我们new的时候,会创建一个空对象,且将空对象的引用赋值给构造函数的this,这样this就会指向这个空对象,且会在构造函数的最后,如果没有返回值,自动帮我们返回这个this。

写成伪代码大概就是:

function Person(name,age){
	this.name = name;
    this.age = age;
    // 不需要我们返回this
    return this;
}

new绑定需要的函数是构造函数,构造函数没有显示指定的返回值,且构造函数一般首字符是大写。

function Person(name,age){
    this.name = name;
    this.age = age;
}
var person = new Person("zs",21);
console.log(person);


new 绑定,其中的this的指向就是我们通过new关键字创建出来的空对象。然后通过构造函数给这个空对象添加各种属性。

ES6的箭头函数 arrow function

箭头函数是ES6之后新增的编写函数的方法,写法比函数表达式更加简洁。

特点:

  1. 箭头函数不会绑定this,arguments属性;
  2. 箭头函数不能作为构造函数来使用(说白了就是不能搭配new使用);
箭头函数不使用上面的this的四种规则,通俗的说就是不绑定this,而是根据外层作用域来决定this的指向。
var foo = () => {console.log(this)}
// 均为 window
foo();
foo.call("123");
var obj = {
    name: "zs",
    foo: foo
};
obj.foo();
17330196230 13230981129

多线程同步开发
项目经理1v1跟进
源码定制交付
一次合作/终身售后

微信扫码登录/注册

提示

您的诉求已经提交请等待工作人员联系,快速通过请联系管理员

微信扫一扫快速联系

用户协议

欢迎访问我们的网站!我们非常重视用户的隐私权和信息安全,因此制定了以下用户协议,以明确我们与您之间的关系以及您在使用本网站时应遵守的条款。请您仔细阅读并同意本协议的所有条款,以便您能够合法、安全地使用本网站。如果您不同意本协议的任何内容,请立即停止使用本网站。

  1. 服务说明:本网站是一个提供定制软件开发服务和在线找技术搭档的互联网平台。我们保留随时更改、更新或暂停本网站的权利。我们会尽力确保网站的正常运行,但对于因技术问题、系统维护或其他原因导致的网站暂时不可用,我们不承担任何责任。

  2. 用户注册:用户需要通过提供手机号、微信扫码和其他必要信息来注册一个账户。您有责任保护您的用户名和密码,不得将其透露给任何第三方。对于因您的用户名和密码被泄露而导致的任何损失或损害,我们将不承担责任。

  3. 用户行为规范:用户应遵守中华人民共和国相关法律法规,不得发布或传播违法信息、侵犯他人权益的内容。用户应对其发布的内容负责,并承担因发布不当内容而引起的任何法律责任。

  4. 版权声明:本网站所包含的所有文字、图片、音频、视频等素材的著作权均归本网站所有(会员用户上传的默认承诺为不侵权的合法自有技术成果,本网站审核信息后可展示,所有权不归本网站)。未经本网站书面许可,任何单位或个人不得以任何形式复制、转载、修改或传播本网站的任何内容。对于侵犯本网站知识产权的行为,将依法追究其法律责任。

  5. 免责声明:本网站不对因使用本网站而引起的任何直接、间接、偶然、特殊或后果性的损害承担责任。包括但不限于利润损失、数据丢失、业务中断等。

  6. 适用法律和争议解决:本协议的签订、履行、解释及争议解决均适用中华人民共和国法律。如发生争议,双方应首先协商解决;协商不成的,任何一方均有权向有管辖权的人民法院提起诉讼。

  7. 本协议的解释权归本网站所有。如有未尽事宜,本网站保留最终解释权。

  8. 本协议自用户点击“同意”或“接受”按钮时生效。

同意

隐私政策

欢迎访问我们的网站!我们致力于为您提供一个安全、可靠的在线环境。本隐私政策旨在说明我们在您使用我们的网站时如何收集、使用和保护您的个人信息。请仔细阅读以下内容,以了解我们的隐私政策。

  1. 信息收集

在使用我们的网站时,我们可能会收集以下类型的信息:

a) 个人识别信息:如姓名、电子邮件地址、电话号码等。 b) 非个人识别信息:如浏览器类型、操作系统、设备类型、IP地址等。 c) 用户行为信息:如访问页面、点击链接、搜索查询等。

  1. 信息使用

我们收集的信息将用于以下目的:

a) 提供、改进和个性化我们的服务。 b) 与您联系,回应您的询问和请求。 c) 发送您请求的或我们认为对您有帮助的信息。 d) 进行市场调研和分析,以改进我们的产品和服务。 e) 防止欺诈和其他非法活动。

  1. 信息共享

我们不会出售、出租或以其他方式与第三方共享您的个人信息,除非:

a) 获得您的明确同意。 b) 与可信赖的合作伙伴共享,以提供您请求的服务。 c) 根据法律要求或政府机关的要求。 d) 为保护我们的权利、财产或安全。

  1. 信息安全

我们采取合理的安全措施,以保护您的个人信息不受未经授权的访问、披露、更改或破坏。然而,请注意,没有任何一种电子存储方法是100%安全的。

  1. Cookie和跟踪技术

我们的网站使用Cookie和类似的跟踪技术来收集有关您使用我们网站的信息。这些信息有助于我们分析和改进我们的网站,以及提供个性化的内容和广告。您可以通过浏览器设置拒绝接受Cookie,但这可能会影响您使用我们网站的能力。

  1. 第三方链接

我们的网站可能包含指向其他网站的链接。请注意,我们对其他网站的隐私政策和实践不承担任何责任。我们建议您在访问这些网站时查看其隐私政策。

  1. 隐私政策的变更

我们可能会不时更新本隐私政策。请定期查看此页面,以确保您了解我们对个人信息的最新政策。

  1. 联系我们

如果您对我们的隐私政策有任何疑问或建议,请通过以下联系方式与我们联系:

电子邮件:[wangye-101@163.com]

电话:+86-173-3019-6230

地址:中国石家庄市长安区吾悦广场2010室

感谢您的信任和支持!我们将竭诚为您提供更优质的服务。

同意