关于JavaScript中this的指向,你知晓几分?请速来围观!
---恢复内容开始---
一、this是什么东东?
this是指包含它的函数作为方法被调用时所属的对象。这句话理解起来跟卵一样看不懂,但是如果你把它拆分开来变成这三句话后就好理解一点了。
1.包含它的函数
2.作为方法被调用时
3.所属的对象
二、this的绑定规则
1、默认绑定
var x = 0; function num(){this.x = 1; } console.log(this.x);//0 num(); console.log(this.x);//1 //当没有使用let或者var时,声明的变量是全局变量,指向window,//在这一形态下,其函数内部的this是与全局作用域时一样,直接指向window,执行完num()后,更改了x的值,所以其形态 依然等价于window。
function foo(){console.log(this.a)}var a = 2;foo(); //2 console.log(this.document === document); // true// 在浏览器中,全局对象为 window 对象: console.log(this === window); // truethis.a = 3;console.log(window.a); // 3this指向全局对象。在非严格模式中,当funcion被不带任何修饰的函数直接引用进行调用的,只能使用默认绑定,无法应用其他规则
2、隐式绑定
先看两段例子
function foo(){console.log(this.a) }var obj = {a:2,foo:foo }obj.foo() //2
//隐式绑定————调用位置使用obj上下文来引用函数,可以说函数被调用时obj对象“拥有”或者“包含”它,它就指向谁。
function foo(){console.log(this.a) }var obj2 = {a:42,foo:foo }var obj1 = {a:2,obj2:obj2, foo:foo }obj1.foo() //2 obj1.obj2.foo() //42 //此时可以控制台查看obj1,obj2对象里究竟包含了什么//当函数引用有上下文对象时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象 //对象属性引用链中只有最后一层在调用位置中起作用
下面思考这一段会输出什么呢?
function foo(){console.log(this.a) }var obj = {a:2,foo:foo }var bar = obj.foo; //这里bar将引用foo函数本身,所以不带有函数对象的上下文,this会直接指向window
bar() //? //为什么没有隐式绑定?这种情况称为隐式丢失。
//因为bar=obj.foo 而obj.foo指向foo 也就是bar = function foo(){console.log(this.a)} foo中的this指向window,//在window中并没有对a进行定义,so,结果是undefined
接下来再看一段会是什么结果呢?(参数传递时的隐式赋值)
function foo(){console.log(this.a) }function doback(fn){fn() }var obj = {a:2,foo:foo }var a = 'global';doback(obj.foo) //? 显然答案是global,但是为什么呢?请继续往下看! //隐式丢失--被隐式绑定的函数会丢失绑定对象然后应用默认绑定。//最后函数执行 doback(obj.foo)时,会进行参数传递,也就是 fn = obj.foo,就和上一个例子一样了。既this指向的是window。
3、显示绑定
function foo(){console.log(this.a) }var obj = {a:2 } foo.call(obj) //2 //显式绑定--第一个参数是一个对象,接着在调用函数时将其绑定到this,通过foo.call(obj),我们可以在调用foo时强制把他的this绑定到obj上
function foo(){console.log(this.a) }var obj = {a:2 }var a = '3333333';var bar = function(){foo.call(obj) }
bar() // 2
bar.call(window) //2 // 硬绑定后bar无论怎么调用,都不会影响foo函数的this绑定// 通过创建函数bar(),并在内部调用foo.call(obj),强制把foo的this绑定到obj上。硬绑定的bar之后无论如何调用函数,都只会在obj上调用foo。
我们来看一下他的应用:
function foo(num) {console.log( this.a, num);return this.a + num; }var obj = {a: 2 };var bar = function() {return foo.call( obj, ...arguments ); // 将obj对象硬编码进去
//return foo.apply( obj, arguments ); // 也可以使用apply将obj对象硬编码进去
};var b = bar( 3 ); // 2 3 console.log( b ); // 5
function fn1(){console.log(1); } function fn2(){console.log(2); }fn1.call(fn2); //输出 1 fn1.call.call(fn2); //输出 2 这个暂时没有搞懂,但是东鸽子大师中有讲解,感兴趣的小伙伴可以看看。
4、new绑定
我们不去深入了解构造函数,但要知道new来调用函数,或者说发生构造函数调用时,执行了哪些
当代码 new foo(...) 执行时:
(1) 创建一个新对象,它继承自foo.prototype.
(2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);new foo 等同于 new foo(),只能用在不传递任何参数的情况。
(3) 执行构造函数中的代码(为这个新对象添加属性) ;
(4) 返回新对象, 那么这个对象会取代整个new出来的结果。如果构造函数没有返回对象,那么new出来的结果为步骤1创建的对象。
function foo(a){this.a = a; }var bar = new foo(2); //创建一个新对象bar,它继承了foo.prototype. 也就是bar这个对象有a这个属性,且传进去的是2,使用new来调用foo(..)时,会构造一个新对象,并把它绑定到foo(..)调用中的this上
console.log(bar.a) //2
三、下面做一个小练习看看你学会了吗?
例一: function foo(a){console.log(this.a) }var obj1 = {a:2,foo:foo }var obj2 = {a:3,foo:foo }obj1.foo() //? obj2.foo() //? obj1.foo.call(obj2) //? obj2.foo.call(obj1) //? 答案:
obj1.foo() //2 隐式绑定 obj2.foo() //3 隐式绑定obj1.foo.call(obj2) //3 显式绑定 obj2.foo.call(obj1) //2 显式绑定
通过答案得出:显示绑定 > 隐式绑定显示绑定优先级更高,所以在判断时 应当 优先考虑 是否 存在 显示绑定
例二: function foo(someting){this.a = someting }var obj1 = {foo:foo } var obj2 = {} obj1.foo(2) var bar = new obj1.foo(4) console.log(obj1.a)//? console.log(bar.a)//? 答案:
console.log(obj1.a) //2 console.log(bar.a) //4 通过答案得出: new绑定 > 隐式绑定
显示绑定优先级更高,所以在判断时 应当 优先考虑 是否 存在 new绑定
需要注意的是:new和call/apply无法一起使用,因此无法通过new foo.call(obj)来直接测试 function foo(someting){this.a = someting }var obj1 = {}var bar = foo.bind(obj1) //不知道bind()方法的同学可以直接点击此处查看最骚的就是你同学贡献的详解。 bar(2) console.log(obj1.a)//?var baz = new bar(3) console.log(obj1.a)//? console.log(baz.a)//? 答案:2 2 3 通过答案得出:new绑定 > 显示绑定new修改了硬绑定调用bar(..)中的this,因为使用了new绑定,得到了一个名字为baz的新对象,并且baz.a的值为3.所以 new绑定 > 显示绑定 > 隐式绑定 > 默认绑定
在此特别鸣谢同事Jason大哥的share!!!
---恢复内容结束---
转载于:https://www.cnblogs.com/colinliu666/p/10384874.html
关于JavaScript中this的指向,你知晓几分?请速来围观!相关推荐
- JAVAscript中的this指向和this指向的修改
JAVAscript中的this指向和this指向的修改 this 关键字 一般在函数中使用,表示哪个对象执行了当前函数. 每一个函数内部都有一个关键字是 this . 函数内部的 this 只和函数 ...
- $.ligerdialog.open中确定按钮加事件_彻底搞懂JavaScript中的this指向问题
JavaScript中的this是让很多开发者头疼的地方,而this关键字又是一个非常重要的语法点.毫不夸张地说,不理解它的含义,大部分开发任务都无法完成. 想要理解this,你可以先记住以下两点: ...
- JavaScript中this的指向问题
this是面向对象语言中一个重要的关键字,理解并掌握该关键字的使用对于我们代码的健壮性及优美性至关重要.而javascript的this又有区别于Java.C#等纯面向对象的语言,这使得this更加扑 ...
- 理解JavaScript中this的指向详解
this的定义和理解: this是JavaScript语言的一个关键字,它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内使用. 1.this和执行环境对象有关,和函数的声明无关. var ...
- JavaScript中this的指向问题及面试题你掌握了吗?
this 作为JavaScript中的一个关键字,它的复杂度很高,主要原因是它所处不同场景的代表的指向是不一样的.这里先做一个结论,重要事情说三遍: this的指向是由上下文环境动态决定的 this的 ...
- JavaScript中this的指向
JavaScript之this指向问题 js中的this指向问题一直不是很清楚,看了coderwhy老师的文章后特此记录一下. this在全局作用域下使用 this在全局作用域下指向的就是window ...
- JavaScript中的 this指向问题
以下文章均已附上原文链接 ,侵删 文章一:vue中的this指向问题 vue中的this指向问题_JingG459的博客-CSDN博客_vue中this指向问题 最近写项目遇到很多this指向的问题, ...
- JS每日一题: JavaScript中的数组和函数在内存分别是如何存储的?
要了解数组和函数在内存中如何存储的,首先的了解数组与函数属于什么数据类型 JavaScript数据类型 基本数据类型:Number.String.Boolean.Undefined.Null, 引用数 ...
- 38 JavaScript中的this指向问题
技术交流QQ群:1027579432,欢迎你的加入! 欢迎关注我的微信公众号:CurryCoder的程序人生 1.函数内this指向问题 函数内部的this指向是当我们调用函数的时候确定的.调用方式的 ...
- javascript中关于this指向问题详解
前 言 LiuDaP 在前端的学习中,我们必然要用到js,js可以说是前端必不可少的的东西.在学习js的过程中,我们会经常用到this这个东西,而this的指向问题就变得尤为重要.今天正好有空闲 ...
最新文章
- BZOJ4292 : [PA2015]Równanie
- mysql设计数据集市_数据集市设计
- HashMap的工作原理
- WIN10系统如何取消任务栏处的窗口缩略图
- 蓝桥杯2017年第八届C/C++省赛C组第二题-兴趣小组
- centos中mysql操作命令_CentOS系统常用的MySQL操作命令总结
- 使用java实现敏感词汇过滤功能
- wget 下载 设置cookie
- dev、test、prod、pre是什么意思?
- gentoo下载与安装
- Matlab突然闪退 出现Fatal Error On Startup解决办法
- 如何提升产品经理的综合素质?
- 面试题总结:volatile的功能
- 未上线PP模块的生产领料处理
- [openstack][keystone]架构分析
- c++ 文件操作记录
- vim的配置(c语言)
- 比较好个性5页面简历
- kickstart无人值守
- android加入图片命名规则