博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
this的用法详解
阅读量:6511 次
发布时间:2019-06-24

本文共 4781 字,大约阅读时间需要 15 分钟。

this是 JavaScript 语言的一个关键字

它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用

个人比较喜欢将this理解成上下文语境 既然是语境一定有主语 我们只需要关注 主语是谁就可以了,因为谁用了this 那么this肯定是指向谁的

this的特性

要注意的是,this的语境绝对不是在创建时决定的,而是函数运行是决定的,还是那句话,谁用了this指向谁
列举几个简单的例子容易理解

作为普通函数在全局环境中被调用

var x = 1;function test() {console.log(this.x);}test();  // 1复制代码

这个函数很容易理解,作为一个普通函数在全局中调用 此时this是指向全局 为什么这么说,其实很简单,因为这是我们的简写

var x = 1;function test() {console.log(this.x);}window.test()  // 1复制代码

这才是完整的写法,只是我们平时都会省略window,此时我们的方法是通过window使用的,好我们此时主语是window,那么我们就会在window下 寻找x 就找到了全局下的x 输出1,所以我们要知道方法一定是有人调用的,如果没人用那就是window爸爸在用了,所以匿名函数的this一定指向window了

再看一个例子
var x = 1;function test() {var y=6    console.log(this.x);console.log(this.y);}window.test();  // 1  undefined复制代码

同样的道理,此时y就显示了undefined 此处显示undefined 并不是说没有y,我们都知道var是存在变量提升的,因为js是从上到下解析,如果我们把y放在函数外

var x = 1;   function test() {console.log(this.x);console.log(this.y);}var y=6    window.test();  // 1  6复制代码

此时就能输出6了,因为此时的window.y是等于6的

var x = 1;  function test() {     console.log(this.x);console.log(this.y);}window.test();  // 1var y=6    复制代码

此时放在下面又变成undefined了,因为此时的window.y是undefined

在对象中使用例子

var x=2;function test() {console.log(this.x);}var obj = {};obj.x = 1;obj.m = test;obj.m(); // 1复制代码

在对象中设置了俩个属性,一个是x,一个是m,此时obj就变成了

obj={ x:1, m:function test(){ console.log(this.x) }}复制代码

此时方法前面有对象了,这个对象是obj,也就是说此时的语境是obj了,那么翻译一下就是obj在使用m方法了,那么this此时是被obj使用的,那么this就指向obj这个对象,也就是说此时this.x==obj.x,很显然打印1

构造函数中使用

所谓构造函数,就是通过这个函数,可以生成一个新对象。这时,this就指这个新对象。

var name='mama';     var age='18';    function test(name,age) {     this.name=name;      this.age=age    }    var obj = new test('this','18');    console.log(name,age) //mama  18    console.log(obj.name,obj.age)  //this 18复制代码

其实我认为不需要解释了,很容易理解,谁调用此时的this指向谁,就会在谁的下面寻找属性

这里构造函数首字母要大写,不会报错但是是一种规范 额我是故意写这样的

再看一个构造函数的例子

function Person (name) {        console.log(this) // window        this.name = name;    }    Person('inwe')    //使用new    function Person (name) {        this.name = name        console.log(this) //people        that = this    }    var people    console.log(that === people) //false    var people = new Person('iwen')    console.log(that === people) //true复制代码

前面两个函数好理解,第二个函数,我们将this赋值给that,看看对比 在构造实例之前,此时函数在全局下,属于window,那自然不等于people 构造实例之后this指向构造的实例,此时this就相当于是people这个实例了

强行改变this语境

使用apply call bind 三个方法强行改变this语境,详情用法可以百度一下,此处只介绍apply

apply()是函数的一个方法,作用是改变函数的调用对象。它的第一个参数就表示改变后的调用这个函数的对象。因此,这时this指的就是这第一个参数

var x = 0;    function test() {     console.log(this.x);    }    var obj = {};    obj.x = 1;    obj.m = test;    obj.m.apply() // 0    obj.m.apply(obj); //1复制代码

apply()的参数为空时,默认调用全局对象。虽然是obj调用的方法,但是这时的运行结果为0,证明this指的是全局对象 最后一行又将this指向obj,输出1

从理论以及基础上面来讲 this并不难,谁调用this指向谁,当然还有很多复杂的情况,闭包啊原型链啊,但是万变不离其宗,谁用它就是指向谁,找几个笔试题我们可以分析一下

var name = "caibaojian.com";     var person = {    name: "kang",    pro: {        name: "Michael",        getName: function() {        return this.name;        }    }    };    console.log(person.pro.getName()); // Michael    var pepole = person.pro.getName;    console.log(pepole()); // caibaojian.com复制代码

首先我们分析第一个 person.pro.getName()注意此处是有括号的 函数体加()=函数执行 此时相当于返回的就是 好 谁用this指向谁,方法我们是person下的pro这个对象使用的, 很简单 分析接下来这个 注意此时是= 在js中=是指右边赋值给左边 此时右边是函数体,它并没有执行,那么此时函数赋值给了people,此时people此时就相当于一个函数 注意了,people前面可是省略了window的 也就是说相当于是window.people(),所以他返回的是全局下的name

'use strict';    var name = "caibaojian.com";     var person = {    name: "kang",    pro: {        name: "Michael",        getName: function() {        return this.name;        }    }    };    console.log(person.pro.getName()); //  Michael    var pepole = person.pro.getName;    console.log(pepole()); // undefined复制代码

本来是不想复制这个的,其实这里为什么undefined 因为最上面设置了严格模式,而严格模式下没有默认的window全局对象,捎带的提个醒

var name = "caibaojian.com",        person = {        name : "kang",        getName : function(){         return function(){             return this.name;         };        }        };    console.log(person.getName()()); // caibaojian.com  复制代码

这道题目有点小恶心啊,一步步分析,先看getName() 注意此时它有括号,函数执行返回第一个return 也就是返回一个function 注意 坑来了 此时它又有一个() 又执行了 这其实就相当于一个匿名函数了 一定注意,函数加括号代表执行 匿名函数一定指向window 因为它不需要谁调用 它一打开页面就开始跑了 它已经疯了

function a(xx){        this.x=xx;        return this    };    var x=a(5);    var y=a(6);    console.log(x.x); //undefined    console.log(y.x); //6复制代码

这道题可以说是相当的变态,我尽量表达清楚意思 注意了这个函数,它return返回的是this 一个函数的最终结果一定是return

我们要知道,函数改变相应数据结构的同时,并不代表函数结果,只有return 才是函数的结果 那么第一个 var x=a(5) 我们不管发生了什么,我们可以确定此时x已经是window了
同样的道理 var y=a(6) 不管发生了什么 y此时就是window return this返回的就是window 接下来我们逐步分析,var x =window 这个应该没问题 注意 这里是高潮 var y=window 没毛病 但是y执行函数的时候 触发了 this.x=6(这步没看懂的再捋一下) 前面一个var x=a(5)返回的结果是window 就是说this.x=window,执行y的时候对x进行了覆盖 也就是说此时的this.x它是等于6 发现没有 到这里,问题就解决了,返回的最终结果就是console.log(6.x,window.x) 所以答案是undefined 6 是不是很变态

多做一些题目自然而然对于this有很好的掌握,不过最好是在你掌握了原型,闭包,预解析,ES6的情况下,这边顺带提一下,箭头函数 它的this指向函数的父函数,我们实际开发并没有这么复杂,但是这种题很考验我们的js功底

转载地址:http://pwcfo.baihongyu.com/

你可能感兴趣的文章
在Ubuntu中部署并测试HyperLedger Fabric 0.6
查看>>
一题关于PHP的CTF
查看>>
phpmyadmin 免登陆
查看>>
【Linux相关配置】Wine1.12中文完美配置
查看>>
[uart]理解线路规程的作用
查看>>
RecyclerView的使用(2)之多Item布局的载入
查看>>
新华三《中国城市数字经济指数白皮书》发布在即
查看>>
手机平板巡检系统,掀起设备巡检的第2次革命
查看>>
阿里云在欧洲掀起技术旋风 POLARDB数据库亮相数据库顶会ICDE
查看>>
阿里云联手PTC ThingWorx打造行业物联网生态
查看>>
怎么评价牛津大学开设区块链课程?
查看>>
【AI也拯救不了Facebook】用户从未同意用隐私换便利
查看>>
联系方式
查看>>
科普时间:OCR是人工智能的基础之一
查看>>
2016年人工智能产业梳理:一朝引爆,稳步前进(中篇)
查看>>
科学家学习天竺葵特性,研制出用水分子来驱动的微型机器人
查看>>
CodeMap
查看>>
救命稻草来了,社交平台AltspaceVR获得帕胖的关注
查看>>
比特币的私钥【区块链生存训练】
查看>>
Facebook的Aquila无人机第二次试飞成功,比预期速度要快
查看>>