摘要:作为一个菜鸡的我而言,在之前讲到过那么多的链式查找机制,比如说原型链,作用域链等等,想当然的把这个机制带入到了指向上边,结果就是这个指向指的我万脸懵逼标题换字了,担心被河蟹在经过漫长的通俗易懂的规范阅读之后,分享一下我所认知的指向简而言之,
作为一个js菜鸡的我而言,在之前讲到过那么多的js链式查找机制,比如说原型链,作用域链等等,想当然的把这个机制带入到了this指向上边,结果就是这个this指向指的我万脸懵逼(标题换字了,担心被河蟹),在经过漫长的通(gou)俗(pi)易(bu)懂(tong)的 ECMAScript规范阅读之后,分享一下我所认知的this指向常见的几种调用方式简而言之,js中this的指向不是在函数定义的时候确定的,而是在调用的时候创建阶段确定的,也就是说this指向谁,完全取决于函数的调用方式
直接调用, 比如说
function a() {
console.log(this);
}
a();
这个例子里边this指向的是全局对象,在客户端的全局对象是window对象,在node 中的全局对象是global对象
(function a() { function b() { console.log(this); } b() })()
直接调用指的是直接用函数名称后边加()执行调用的函数,无论是否在全局作用域
间接调用
const obj ={
name:"obj对象", a(){ console.log(this) }
}
obj.a()
如图
在图中我们可以看到我们在对象里边调用对象里边的方法的时候,this指向的是obj对象,
或者说外边有一个函数 然后给一个obj对象的属性赋值
const obj ={ name:"obj对象", a(){ console.log(this) } } obj.a() obj.b=function(){ console.log(this,"b") } obj.b()
打印的结果都是obj对象
new调用
当我们他用过new 创建一个新的对象的时候,new会调用这个构造函数来创建一个对象,那么这个对象里边的this是这个被new的函数调用的,那么自然 new调用的时候,this就是指向这个新对象的
function A(data) { this.data = data; } class B{ constructor(data){ this.data = data } } let a = new A("A"); let b = new B("B"); console.log(a.data); console.log(b.data);
如图
这个new,在创建对象的时候做了什么,我们会在下一篇博客里边仔细说明
箭头函数中的this
箭头函数可以理解成是是一个语法糖,他没有自己的this绑定,箭头函数中使用的this是包含他的那个函数的this
比如说
const obj = { a() { return () => { console.log(this); }; } }
上边这段代码被转译成es5 的时候如下
const obj = { a: function a() { var _this = this; return function () { console.log(_this); }; } };
综合以上所有的代码,得出一个结论就是,在js中this的绑定正常来讲是指向调用这个方法的对象来确定的,当然还有一些不正常的方法,可以改变this的指向
注意 ,下边介绍的几种方法,不能改变箭头函数的this指向,箭头函数本身是没有this绑定的,在介绍完不正常的情况后,再来说一说那些能够改变this指向的方法ECMAScript 5.1 规范的this指向
js中this的绑定正常来讲是指向调用这个方法的对象来确定的
这句话在理论上是这么讲,在工作中正常的调用的话,这个理论是没有毛病的,在 ECMAScript 5.1 的规范里边规定,在js里边分为语言类型和规范类型
语言类型
ECMAScript 里边的语言类型规定的是我们可以直接操作的一些类型,比如string number,object等等这些
规范类型
规范类型ECMAScript 里边指的是一种抽象的规范,他们并不是让我们用来进行操作的,二是用来描述一些行为或者逻辑的,比如说typeof delete等等
ECMAScript 5.1 里边的this规定大概讲就是这样的,每个对象里边有一个Reference 规范类型,this会根据Reference这个规范类型进行赋值
ECMAScript 5.1
规范奉上 Reference 这个东西大家简单的理解成是()前边的那一块就好了,上边我们讲的那些正常的就是说左边是
函数定义表达式
属性访问表达式
对象创建表达式
属性创建表达式
这几种情况,在这几种情况的时候上边那句话是成立的
但是如果不是这上边的那几句话的时候,比如说括号里边是一个和函数相关计算或者一个运算符等等
这个时候this会指向undefined ,这个时候在非严格模式的情况下会被隐式转换成window对象
var value = 1; var obj = { value: 2, a() { return this.value; } } console.log(obj.a()); console.log((obj.a)()); console.log((obj.a = obj.a)()); console.log((false || obj.a)()); console.log((obj.a, obj.a)());
记得之前看到过这个一个例子,运行结果如图
时间关系就说这些,下一篇博客会说new在运行时候过程和改变this指向的一些方法,
以上是我对this指向的一些认识,有不足的地方希望之处
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/105503.html
摘要:无关紧要的开头作为一个年轻的前端从业者,近期趾高气昂的去各种面试,抱着找虐心态去单挑的结果就是被各种面试题晃断脚踝并被射,然后开始质问自己对的掌握为何如此浅薄,为何当初不好好学世界上最好的语言。 /*===无关紧要的开头start===*/作为一个年轻的前端从业者,近期趾高气昂的去各种面试,抱着找虐心态去单挑的结果就是被各种面试题晃断脚踝并被yan射,然后开始质问自己对js的掌握为何如...
摘要:值得注意的是,如果值在前面也就是值小于值,那么值域会被认为是零长度,而不是负增长。 underscore.js源码加注释一共1500多行,它提供了一整套函数式编程实用的功能,一共一百多个函数,几乎每一个函数都可以作为参考典范。初读的时候,真是一脸懵圈,各种函数闭包、迭代和嵌套的使用,让我一时很难消化。在这里,我来记录一下我学习underscore.js的一些发现,以及几个我认为比较经典...
摘要:那默认绑定到哪呢,一般是上,严格模式下是。这种情况下,函数里的默认绑定为上下文对象,等价于打印故输出。只接受两个参数,且第二个参数必须是数组,这个数组代表原函数的参数列表。即继承原函数的原型将这个新对象绑定到此函数的上。 js 的 this 绑定问题,让多数新手懵逼,部分老手觉得恶心,这是因为this的绑定 ‘难以捉摸’,出错的时候还往往不知道为什么,相当反逻辑。让我们考虑下面代码: ...
摘要:那默认绑定到哪呢,一般是上,严格模式下是。这种情况下,函数里的默认绑定为上下文对象,等价于打印故输出。只接受两个参数,且第二个参数必须是数组,这个数组代表原函数的参数列表。即继承原函数的原型将这个新对象绑定到此函数的上。 js 的 this 绑定问题,让多数新手懵逼,部分老手觉得恶心,这是因为this的绑定 ‘难以捉摸’,出错的时候还往往不知道为什么,相当反逻辑。让我们考虑下面代码: ...
阅读 2339·2021-11-16 11:52
阅读 2324·2021-11-11 16:55
阅读 751·2021-09-02 15:41
阅读 2983·2019-08-30 15:54
阅读 3144·2019-08-30 15:54
阅读 2253·2019-08-29 15:39
阅读 1511·2019-08-29 15:18
阅读 969·2019-08-29 13:00