木灵鱼儿
阅读:348
关于this
为什么会有this
this在JavaScript中是一个非常复制的机制,它的存在其实是为了能让我们更好的复用代码,this提供了一种更优雅的方式来隐式“传递”一个对象引用,因此可以将API设计的更加简洁且易于复用。
我们举个例子:
new一个构造函数,我们可以得到一个新的实例对象,这个对象会继承原型,此时,如果没有this,如何在原型方法里去访问你的新的实例对象,以及获取属性这些操作。
显然是不太好做的,难道每次都把自身作为参数传递给prototype上的方法吗?
显然这非常不方便,如果使用了this,this会指向这个新的实例对象,那么我们在书写代码是就会更加方便了,复用也更加简单。
这个this不需要自己去声明,减少了大量啰嗦代码。
this的误区
如果不熟悉this到底是如何工作的,或者局限于字面的译意,很容易会产生误解,常见的两种错误认为:
- this指向自身
- this指向函数作用域
this指向自身
这个理解大部分人都是从字面译意上去理解的,我们看一个测试代码:
function foo(num) {
console.log("foo: " + num);
// 记录 foo 被调用的次数
this.count++;
}
foo.count = 0;
var i;
for (i = 0; i < 10; i++) {
if (i > 5) {
foo(i);
}
}
// foo: 6
// foo: 7
// foo: 8
// foo: 9
// foo 被调用了多少次?
console.log(foo.count); // 0 -- WT
如果this指向自身,那么函数foo上的count就应该为10,但是他是0。
this指向函数作用域
this会指向函数的作用域,如下代码:
function foo() {
var a = 2;
this.bar();
}
function bar() {
console.log(this.a);
}
foo(); // undefined
仔细阅读,你会发现,this.bar
函数被正确获取到并运行了,但是在打印this.a
的时候报错了,因为RHS查询没有在作用域中查询到该变量。
这样看上去this好像确实是指向了函数作用域,并通过作用域链查找到了bar函数。通过作用域的知识我们知道,bar函数的作用域里面没有a变量,因为它的作用域只有它自己,以及上层的全局作用域,所以它抛错也是可以理解的。
但是,我们再包一层函数,代码的表现就完全不一样了。
function test() {
function foo() {
var a = 2;
this.bar();
}
function bar() {
console.log(this.a);
}
foo();
}
test();
如果this指向函数作用域,那么它就可以通过作用域链获取到test函数下的bar函数,但是结果却是:Uncaught TypeError: this.bar is not a function
。
仔细看这个报错,他是TypeError
;说明查到了this这个变量,但是因为this上没有bar,得到是一个undefined,被运行是出现了类型错误。
所以,我们不能说this就是指向函数作用域,只是因为在某些情况下,表现的像是指向函数作用域。
需要明确的是,this 在任何情况下都不指向函数的词法作用域。每当你想要把 this 和词法作用域的查找混合使用时,一定要提醒自己,这是无法实现的。
this到底是什么?
首先我们需要知道,this是运行时绑定的,并不是在编写时绑定,包括ES6的箭头函数的this,都是运行时绑定的,这点尤为重要。this存储在函数的执行上下文中,而这个上下文的内容取决于函数的调用方式。
this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式(也就是运行时)。
当一个函数被调用时,会创建一个活动记录(有时候也称为执行上下文)。这个记录会包含函数在哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。this 就是活动记录中的一个属性,会在函数执行的过程中用到。
版权申明
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿 - 有梦就能远航站点。未经许可,禁止转载。
相关推荐
执行上下文
什么是执行上下文JavaScript引擎在执行代码阶段时,通常是调用函数的时候,就会先做一些准备工作,这个准备工作被称为执行上下文,简称EC,或者也可以叫做执行环境。执行上下文也是有不同的,有三个类型:全局执行上下文:最基础的执行上下文,一个程序也只会存在一个全局执行上下文,全局上下文会生成一个全局对象,这个对象就是window,并且会将该上下文的中this绑定到该全局对象上。函数执行上下文:当函数被调用时都是产生一个新的上下文对象,不管函数是否是重复调用Eval函数执行上下文:执行在 eval 函数内部的代码也会有它属于自己的执行上下文而this是由上下文中提供的,我们可以将上下文理解...
vue项目里使用Object.assign的一个小技巧
当我们请求一个api的时候,他返回的数据可能会有很多,这些数据可能需要分别拆分存放在data预设的变量中。这就导致我们可能要写好几个赋值操作this.xxx = xxx; this.xx = xxx; this.xx = xxx;我们可能会重复很多次上面这种操作,是不是有点麻烦。为此,我们可以利用Object.assign来达到我们的偷懒效果Object.assign(this,{xx:xxx},{xxx:xxx});使用这种方式,我们的vue可以检测到动态改变的值,也就是说watch监听是可以触发的。且效果和你写多个this.xxx=xxx是一样的。感觉这个方法妙啊,所以分享出来,当然...
什么是上下文节点???
学html+css的时候有在书上看到过上下文节点,但是也没详细说明,看视频的时候也有人说过,但是也是一笔带过,也没在意,今天学XPath的时候就有关于上下文节点有一个说明,但是只说了一点,没啥详细,所以自己百度了下,如下:代码:<html> <body> <a id = '1'>文本节点1</a> <a id = '2'>文本节点2</a> <a id = '3'>文本节点3</a> </body> </html> ...