一直以来对this的理解只在可以用,会用,却没有去深究其本质。这次,借着《JavaScript The Good Parts》,作了一次深刻的理解。(所有调试都可以在控制台中看到,浏览器F12键)
下面我们一起来看看这个this吧。
在我们声明一个函数时,每个函数除了有定义时的parameters(形参),自身还会有额外的两个参数,一个是this,一个是arguments(实参)。arguments就是函数实际接受到的参数,是一个类数组。arguments我只做个简略的介绍,重点我们放在this指针上。
在面向对象变成中,this十分重要,它的值取决于调用的模式。而在JavaScript中,一共有4中调用模式:方法调用模式、函数调用模式、构造函数调用模式、apply调用模式。
方法调用模式
当一个函数是作为一个对象的属性时,我们通常称这个函数是这个对象的一个方法。当这个方法被调用时,this就会指向该方法所属对象。
<script type="text/javascript"> var people = { name : "Yika", sayName : function(){ console.log(this.name); //"Yika" //this已经绑定在了people对象上了 } } people.sayName(); </script>
如栗子所示,this指向了sayName对象,这种通过this取得所属对象上下文的方法,就是公共方法。(publice method)
函数调用模式
当一个函数被调用时并非某个对象上的方法,那么它就是作为一个函数被调用的。
这种模式调用,this会指向window对象,即使这个函数或许是在外部函数里调用的,我们来看栗子。
<script type="text/javascript"> var name = "window-Yika"; var people = { name : "people-Yika", student : function(){ console.log(this); //这里的this绑定的是对象people function sayName(){ var name = "sayName-Yika"; console.log(this.name); //window-Yika //即使sayName函数本身和它所在的people对象都有name值,但是this是指向window的 }; sayName(); } }people.student(); </script>
这样一看,是不是大概知道该怎么解决JavaScript这个“设计错误"了呢。
是的只要在student函数里面,也就是第6行,将this缓存起来。然后再将this通过变量转移到sayName函数里就可以解决啦!
var people = { name : "people-Yika", student : function(){ var self = this; //将this缓存起来 function sayName(){ var name = "sayName-Yika"; console.log(self.name); //"people-Yika",此时的self指向的是people对象 }; sayName(); } }
构造函数调用模式
JavaScript里一讲到构造函数,脑海里就会有:“函数名大写!调用的时候要用new操作符!” 函数名大写好理解,是为了规范统一构造函数的命名。可是你有没有深究过为什么要用new呢?如果在一个函数前面带上new来调用,那么函数后台会创建一个指向该函数prototype的新对象,同时this也绑定在新对象上。JavaScript是一门基于原型继承的语言,对原型prototype不是很清楚的同学可以自己去查一下资料,我重点放在this上面。
我们先来看看构造函数一般长什么样子。
<script type="text/javascript"> function People(name){ this.name = name; //这里的this,用new调用后便指向了新对象Yika this.sayName = function(){ console.log(this.name); //输出 } } var Yika = new People("Yika"); Yika.sayName(); //输出“Yika" ,因为Yika是通过new调用得来的,this都绑定在了Yika对象上。 </script>
乍一看,好像不是好懂,怎么刚才在函数里的this是指向window,现在不用缓存就可以指向People函数呢?
没关系,刚才不是说函数通过new调用,会在背地里自己做“做坏事”么,我们一起看看到底做了哪些事。
<script type="text/javascript"> function People(name){ var that = {}; //坏事一:自己生成一个对象 that.name = name; that.sayName = function(){ console.log(that.name); }; return that; //坏事二,自己会改变return的行为,return刚生成的对象 } var Yika = People("Yika"); //这里可以省略new,模仿调用new操作符 Yika.sayName(); //和刚才一样输出"Yika" </script>
这样看就明白清楚了吧,new不仅会生成一个对象,而且还会自动return这个对象,这样自然this便指向了这个新对象。
千万记得要用 new 去调用构造函数,不然出了问题,是没有警告的,所有大写约定还是十分有必要的。
Apply调用模式
apply方法让我们构建一个参数数组传递给调用函数,也允许我们改变this值。
function.apply(this绑定的值, arguments参数数组)
apply可以说的东西太多了,我这里只举个的栗子来帮助大家理解:
<script type="text/javascript"> function People(name){ this.name = name; this.sayName = function(){ console.log(this.name); //sayName这个方法是属于People构造函数的 } } function Student(name){ People.apply(this, arguments);//借用构造函数的集成方式,就是在Student构造函数里,通过apply调用People构造函数,并改变People的this值 //这样每次创建Student实例时,都会调用People构造函数 } var student = new Student("Yika"); student.sayName(); //输出“Yika” </script>
我们可以通过apply轻易的修改函数的this绑定对象,和apply相似的方法call也有一样的效果,有兴趣的同学可以自己搜索学习一下。
好了,总算讲完改变this的四种调用模式了,方法调用模式和构造函数调用模式会用的更多,也会更重要一点,而函数调用模式,我们则要学会避开其中的陷阱。
若有错误,请及时反映,我会尽快纠正,以防误导他人,谢谢!
本文向大家介绍针对JavaScript中this指向的简单理解,包括了针对JavaScript中this指向的简单理解的使用技巧和注意事项,需要的朋友参考一下 首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然网上大部分的文章都是这样说的,虽然在很多
本文向大家介绍详解C++中的this指针与常对象,包括了详解C++中的this指针与常对象的使用技巧和注意事项,需要的朋友参考一下 C++ this指针详解 this 是C++中的一个关键字,也是一个常量指针,指向当前对象(具体说是当前对象的首地址)。通过 this,可以访问当前对象的成员变量和成员函数。 所谓当前对象,就是正在使用的对象,例如对于stu.say();,stu 就是当前对象,系统正
本文向大家介绍我所理解的JavaScript中的this指向,包括了我所理解的JavaScript中的this指向的使用技巧和注意事项,需要的朋友参考一下 前言 JS 中的 this 指向是一个经常被问到的问题,网上也有很多文章是关于 this 的。本文整理一下我理解下的 this 以及一些我比较疑惑的关于 this 问题。 this 指向 有几个 this 的指向问题是几乎每篇文章都会说的,比如
问题内容: 我有一个关于在嵌套函数方案中如何处理“ this”指针的问题。 假设我将以下示例代码插入到网页中。当我调用嵌套函数“ doSomeEffects()”时出现错误。我检查了Firebug,它表明当我使用该嵌套函数时,“ this”指针实际上指向全局“ window”对象,这是我所没有想到的。我一定不能正确理解某些东西,因为我认为自从我在对象的函数中声明了嵌套函数以来,它就应该具有相对于该
C++ 类 & 对象 在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址。this 指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象。 友元函数没有 this 指针,因为友元不是类的成员。只有成员函数才有 this 指针。 下面的实例有助于更好地理解 this 指针的概念:#include <iostream> using namespace std; c
本文向大家介绍Java中的this指针使用方法分享,包括了Java中的this指针使用方法分享的使用技巧和注意事项,需要的朋友参考一下 Java中, 一般来说this指针指的是当前正在访问的这段代码的对象 ,但是如果在内部类中需要使用外部类中的对象,这时就需要使用外部类的类名进行限定。 这种方式在Android开发中也比较常见 。 Inner是内部类,访问类A中的outer()方法