关于JavaScript中this的指向,你知晓几分?请速来围观!
---恢复内容开始---
一、this是什么东东?
this是指包含它的函数作为方法被调用时所属的对象。这句话理解起来跟卵一样看不懂,但是如果你把它拆分开来变成这三句话后就好理解一点了。
1.包含它的函数
2.作为方法被调用时
3.所属的对象
二、this的绑定规则
1、默认绑定
var x = ;
function num(){
this.x = ;
}
console.log(this.x);//
num();
console.log(this.x);//1 //当没有使用let或者var时,声明的变量是全局变量,指向window,
//在这一形态下,其函数内部的this是与全局作用域时一样,直接指向window,执行完num()后,更改了x的值,所以其形态 依然等价于window。
function foo(){
console.log(this.a) } var a = ; foo(); // console.log(this.document === document); // true // 在浏览器中,全局对象为 window 对象: console.log(this === window); // true this.a = ; console.log(window.a); // this指向全局对象。在非严格模式中,当funcion被不带任何修饰的函数直接引用进行调用的,只能使用默认绑定,无法应用其他规则
2、隐式绑定
先看两段例子
function foo(){
console.log(this.a)
} var obj = {
a:,
foo:foo
} obj.foo() //2
//隐式绑定————调用位置使用obj上下文来引用函数,可以说函数被调用时obj对象“拥有”或者“包含”它,它就指向谁。
function foo(){
console.log(this.a)
} var obj2 = {
a:,
foo:foo
} var obj1 = {
a:,
obj2:obj2,
foo:foo
}
obj1.foo() //2
obj1.obj2.foo() //42
//此时可以控制台查看obj1,obj2对象里究竟包含了什么
//当函数引用有上下文对象时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象
//对象属性引用链中只有最后一层在调用位置中起作用
下面思考这一段会输出什么呢?
function foo(){
console.log(this.a)
} var obj = {
a:,
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:,
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:
}
foo.call(obj) //2 //显式绑定--第一个参数是一个对象,接着在调用函数时将其绑定到this,通过foo.call(obj),我们可以在调用foo时强制把他的this绑定到obj上
function foo(){
console.log(this.a)
} var obj = {
a:
} 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:
}; var bar = function() {
return foo.call( obj, ...arguments ); // 将obj对象硬编码进去
//return foo.apply( obj, arguments ); // 也可以使用apply将obj对象硬编码进去
}; var b = bar( ); // 2 3
console.log( b ); //
function fn1(){
console.log();
}
function fn2(){
console.log();
} 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(); //创建一个新对象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:,
foo:foo
} var obj2 = {
a:,
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()
var bar = new obj1.foo()
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()
console.log(obj1.a)//? var baz = new bar()
console.log(obj1.a)//?
console.log(baz.a)//? 答案:2 2 3 通过答案得出:new绑定 > 显示绑定
new修改了硬绑定调用bar(..)中的this,因为使用了new绑定,得到了一个名字为baz的新对象,并且baz.a的值为3.
所以 new绑定 > 显示绑定 > 隐式绑定 > 默认绑定
在此特别鸣谢同事Jason大哥的share!!!
---恢复内容结束---
关于JavaScript中this的指向,你知晓几分?请速来围观!的更多相关文章
- 关于Number的属性和方法你知晓几分?速来围观!
1.Number.isFinite() 方法用来检测传入的参数是否是一个有穷数(finite number)返回值为布尔值. 和全局的 isFinite() 函数相比,这个方法不会强制将一个非数值的参 ...
- javascript中this的指向
作为一个前端小白在开发中对于this的指向问题有时候总是会模糊,于是花时间研究了一番. 首先this是JS的关键字,this是js函数在运行是生成的一个内部对象,生成的这个this只能在函数内部使用. ...
- Javascript中的this指向。
一.JavaScript中的函数 在了解this指向之前,要先弄明白函数执行时它的执行环境是如何创建的,这样可以更清楚的去理解JavaScript中的this指向. function fn(x,y,n ...
- JavaScript中 this 的指向
很多人都会被JavaScript中this的指向(也就是函数在调用时的调用上下文)弄晕,这里做一下总结: 首先,顶层的this指向全局对象. 函数中的this按照调用方法的不同,其指向也不同: 1.函 ...
- 前端面试之JavaScript中this的指向【待完善!】
JavaScript中this的指向问题! 另一个特殊的对象是 this,它在标准函数和箭头函数中有不同的行为. 在标准函数中, this 引用的是把函数当成方法调用的上下文对象,这时候通常称其为 t ...
- JavaScript中的this指向
this是谁 技术一般水平有限,有什么错的地方,望大家指正. this代指当前对象super调用父类的构造函数,应表会运网数物,加载驱动建立链接执行SQL处理结果,直到现在每想起这三点就能想起我上大学 ...
- Javascript 中的this 指向的对象,你搞清楚了吗?
Javascript 中的this 总让人感到困惑,你能分清以下三种test1(),test2(),test3() 情况下的输出吗? 注:以下Javascript运行环境中为浏览器 //1 this在 ...
- javascript中的this指向问题
在深入学习JavaScript之后,我们越来越多的会遇到函数或者在对象内部中,对于this的指向问题的疑惑,其实基本上每一个编程语言中都有一个this,这个this的指向都是大同小异,你也可以汉化它的 ...
- 谈谈 JavaScript 中的 this 指向问题
JavaScript 中的 this 为一个重难点,它不像静态语言 C#.Java 一样,就表示当前对象.而在 JS 中, this 是运行时确定,而并非定义时就已确定其值. 谈起 this ,必须少 ...
随机推荐
- Spring、Spring MVC、MyBatis 整合文件配置详解
使用SSM框架做了几个小项目了,感觉还不错是时候总结一下了.先总结一下SSM整合的文件配置.其实具体的用法最好还是看官方文档. Spring:http://spring.io/docs MyBatis ...
- Python数据分析------例子1(信用卡欺诈)
1.读取数据 data=read_csv(path) data.head() #画图(查看class即分类的数据条形图),函数sort_index()是将dataframe按照行索引来排序输出值 co ...
- Java web课程学习之会话(Session)
Session会话 l web应用中的会话是指一个客户端浏览器与web服务器之间连续发生一系列请求和响应过程 l web应用的会话状态是指web服务器与浏览器在会话过程中产生的状态信息,借助会话状 ...
- POJ 2774 Long Long Message (后缀数组+二分)
题目大意:求两个字符串的最长公共子串长度 把两个串接在一起,中间放一个#,然后求出height 接下来还是老套路,二分出一个答案ans,然后去验证,如果有连续几个位置的h[i]>=ans,且存在 ...
- 洛谷10月月赛II
#A: P4924 [1007]魔法少女小Scarlet 这道题考了矩阵旋转 其实很考验推公式的能力和代码能力 这里有个小技巧 可以设(x, y)为原点,然后去推公式,然后实际操作中横坐标加上x,纵坐 ...
- Vue经典开源项目
Vue常用的开源项目和插件库 UI组件 element ★34,784 - 饿了么出品的基于Vue2的web UI工具套件storybook ★33,503 - 响应式UI 开发及测试环境Vux ★1 ...
- Mysql学习总结(30)——MySQL 索引详解大全
什么是索引? 1.索引 索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据.对于索引,会保存在额外的文件中. 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构.类 ...
- Mybatis动态代理实现函数调用
如果我们要使用MyBatis进行数据库操作的话,大致要做两件事情: 1. 定义DAO接口 在DAO接口中定义需要进行的数据库操作. 2. 创建映射文件 当有了DAO接口后,还需要为该接口创建映射文件. ...
- 字符串的HashCode可能相同
字符串的HashCode可能相同 学习了:http://blog.csdn.net/hl_java/article/details/71511815
- weblogic部署struts2项目訪问action404错误
近期有个project部署到tomcat上是正常的,部署到weblogic上时訪问action报404错误.依据报错日志.在网上找到了原因例如以下: 部署到weblogic上.struts.xml配置 ...