前言

this这个话题,学习、工作、面试,绕不开的难点。

先来看个题目:

var name = "小红";
function a() {var name = "小白";console.log(this.name);
}
function d(i) {return i();
}
var b = {name: "小黄",detail: function() {console.log(this.name);},show: function() {return function() {console.log(this.name);}}
}
var c = b.detail;
b.a = a;
var e = b.show();
a();
c();
b.a();
d(b.detail);
e();

先自己做一下,再把这段代码放进控制台输出一下结果查看答案。

如果有不对的,下面我就来讲个故事,带你梳理一下this关键字绑定的考点。

默认绑定

小明是个吹牛大王,每当人家问他有没有女朋友时,他看到哪个女孩就说这就是他的女朋友。

没有明确到具体说哪一个是他的,他的女朋友在这儿就是全局范围的,似乎全世界的女孩子都属于他一样。

例如以下代码:

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

定义一个girl 函数,直接输出this ,在全局环境下调用这个函数。查看控制台能看到结果输出的是Window

隐式绑定

过来几年又有人问小明的女朋友,这时候小明真的有女朋友了,给人介绍了具体的姓名,身高,体重等信息。

这就相当于一个对象里面的属性值都是明确的,例如以下代码:

var girl = {name: "小红",height: 170,weight: 55,detail: function() {console.log(`姓名:${this.name}`);console.log(`身高:${this.height}`);console.log(`体重:${this.weight}`);}
}
girl.detail();

创建一个girl对象,里面分别有姓名,身高,体重和一个函数,也就是girl对象的方法,这个方法输出小红的信息。每当调用这个方法时,就会出现隐式绑定。这里调用是girl对象里的方法,输出的里面的this就会绑定girl对象。

硬绑定

时间过了两年,小明变得很花心了,同时拥有三个女朋友,除了原本的小红,还有小白和小黄。但是小明并不想介绍小红给别人认识,只想介绍小白和小黄。

例如以下代码:

var girlName = {name: "小红",sayName: function() {console.log(`My girlfriend is ${this.name}`);}
}
var mistress_one = {name: "小白"
}
var mistress_two = {name: "小黄"
}
girlName.sayName.call(mistress_one);
girlName.sayName.call(mistress_two);

创建一个girlName对象,里面有个输出名字的方法。再创建两个对象,分别记录各自的姓名,最后用call分别调用对象的方法。

讲到call,就不得不提到apply,最后输出换成apply,输出的结果是一样的。

girlName.sayName.apply(mistress_one);
girlName.sayName.apply(mistress_two);

apply 和 call

JS中,每一个Function对象都有一个apply()方法和一个call()方法。

apply

调用一个对象的一个方法,用另一个对象替换当前对象。

语法:

function.apply(thisObj[, argArray]);

call

调用一个对象的一个方法,用另一个对象替换当前对象。

语法:

function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);

从上就可以看出它们的异同之处,相同的就是它们的定义,也就是作用是一样的,不同就是它们的使用语法不一样,具体就是传入的参数列表形式不同。

最常用的例子就是函数继承:

function Animal(name) {this.name = name;this.show = function() {console.log(this.name);}
}
function Cat(name) {Animal.apply(this, [name]);// animal.call(this, name);
}
var myCat = new Cat("一天");
myCat.show();

还有个apply的妙用,实现两数组的合并。

var a = [1,2,3];
var b = [4,5,6];
Array.prototype.push.apply(a, b);

输出结果是一个数组的长度,但打印a查看就发现a被修改成合并之后的值了。a调用了push方法,参数是通过apply将数组转换为参数列表的集合。

可以试试这里采用call会是什么样结果。

构造函数绑定

又过去一段时间,小明幡然悔悟,将自己脚踏三只船的行为告诉了小红恳求原谅,没成想小红竟然原谅了他,两人步入婚姻修成正果。

例如以下代码:

function Lover(name) {this.name = name;this.sayName = function() {console.log(`my wife is ${this.name}`)}
}
var name = "小白";
var hostess = new Lover("小红");
hostess.sayName();

创建一个构造函数,用小红这个变量名进行对象的实例化,这时候this就会和实例化后的新对象小红进行绑定,即使出现了同名变量name小白,也不会有影响,查看输出结果仍是小红。

总结

this是因为函数出现而出现,函数在调用的时候就会自动获取this,不管函数声明是在哪个位置,this都能动态指向实际调用的对象。

除了以上四种绑定规则,更重要的就是理解this引用是函数执行的环境对象,也就是说实际上是哪个对象执行的this,该对象当前执行环境是什么。

JS this关键字相关推荐

  1. JS中关键字in的作用

    JS中关键字in的作用 in关键字可以用来检测某个属性是否存在某个对象中,对于对象的属性要用字符串指定属性的名称("属性名") // 举个栗子:console.log(" ...

  2. 【Jquery】-------JS实现关键字检索html内容,符合关键字的匹配项,进行标注背景色,可进行上一个,下一个切换定位

    JS实现关键字检索html内容,符合关键字的匹配项,进行标注背景色 核心代码 全部代码 展示效果 核心代码 全部代码 这个代码主要功能: 通过关键字检索出html内容匹配项 可进行上一个,下一个切换定 ...

  3. js实现关键字匹配高亮显示

    JS实现搜索关键字匹配高亮显示 首先看效果 需求:用户输入文字之后,调用后台接口查询匹配关键字(模糊搜索),并把匹配到的关键字进行高亮显示. 实现思路:将拿到的数据进行拆分,例如:用户输入" ...

  4. JS高效关键字搜索---转

    原文地址: http://www.cnblogs.com/index-html/archive/2013/04/17/js_keyword_match.html 重点关注评论中的代码.. var tr ...

  5. js搜索关键字,并高亮显示

    当我们搜索时,总想要自己输入的字体显示为重点,今天我为大家解决这个问题 <!DOCTYPE html> <html lang="en"><head&g ...

  6. JS label关键字详解

    在 JavaScript 中,使用 label 语句可以为一行语句添加标签,以便在复杂结构中,设置跳转目标.语法格式如下: label : states label 为任意合法的标识符,但不能使用保留 ...

  7. 一段最短的代码,用上js所有关键字

    newfunction() { dobreak;while(typeofdeletethis); for(vara;void 0;) continueif(null) with(0) try{ swi ...

  8. 写一段最短的代码,用上js所有关键字

    void function() {//abcd do break;while(typeof delete this); for(var a;;) if (true) with(null) try{}c ...

  9. JS一起学01:css复习、js基础知识、事件、参数、函数、网页换肤、if判断、className问题、浏览器执行顺序

    一.html/css 1. 什么是盒子模型?     padding+border+width/height 2. float 浮动 (1)浮动的特性         脱离文档流         行内 ...

最新文章

  1. [20160910]低级错误.txt
  2. javaweb学习总结(五)——Servlet开发(一)
  3. 计算机网络解决数据包丢失,数据包丢失时网络控制系统的稳定性分析及设计
  4. 5分钟读完华为区块链白皮书关键信息:推动构建一种新型价值网络
  5. 成功解决C4996: ‘fopen‘: This function or variable may be unsafe. Consider using fopen_s instead
  6. Java Spring研究之MavenSandBox - noHandlerfound debug
  7. java int stack_java Stack的使用
  8. Linux网络设置(第二版) --Linux网络设置
  9. win8.1搭建php环境,WIN8.1下搭建PHP5.6环境
  10. 毕生精力总结的电脑技巧
  11. 电子政务信息系统整合共享管理研究
  12. 2022年六款最好用的运动耳机、骨传导耳机推荐
  13. java发送QQ群邮件,Java使用腾讯企业邮箱 、javamail 、 SSL 发送邮件/群发
  14. CAD怎么去掉右上角的搜索及用户信息工具条
  15. ArcGIS Pro 转换Smart3D生成的倾斜3D模型数据osgb——创建集成网格场景图层包
  16. 加密通讯元年:Signal下载量暴增4200%
  17. 送餐机器人定位系统设计
  18. data:image 用法
  19. 关于Redis清理大量Key的方法
  20. TextView文本颜色状态选择器

热门文章

  1. ‘gbk‘ codec can‘t decode byte 0x80 in position 2: illegal multibyte sequence
  2. 分析Padavan的代码三
  3. SuppressWarnings
  4. 三菱FX5U系列PLC使用FX5-CCL-MS模块无需编程即可实现CC-Link总线通信的具体步骤
  5. Eureka API文档
  6. html页面弹出dialog,自定义H5页面dialog弹窗
  7. 学校运动会计算机系仪仗队入场词,运动会入场方阵解说词
  8. 嵌入式开发:安全嵌入式系统的5个要素—第5部分:安全存储
  9. Ogre游戏 - Torchlight
  10. 苹果充电器不能充电了怎么办?