javascript this
很多初入前端行业的程序员, 对于 JS 中的 this 指向问题是一知半解, 往往需要靠自己的猜测或者在控制台里打印去判断, 然而这样久了, 对于 this 的指向问题还是模糊不清本篇文章将会用最通俗易懂的语言告诉你, 如何去深刻理解它
大多数人的认知:
javascript 中的 this, 在函数定义的时候, 是没有办法去确定它的指向的, 只有函数执行时才能确定 this 到底指向谁实际上 this 的最终指向的是那个调用它的对象
以上这句话并没有错, 但是并不完整我们接着往下看...
例 1:
- function example(){
- var user = "newArray8888";
- console.log(this.user); //undefined
- console.log(this); //Window
- }
- example();
我们上面说 this 只有在函数执行的时候, 才能去判断它最终指向的调用它的对象我们要明确一点, 函数与变量的定义, 都是被添加进 window 的属性的这里我们的 example 函数, 是等同于 window.exapmle 的所以函数是由 window 对象调用的, 所以自然指向 window, 然而在 window 的属性中, 彬没有 user 这个变量, 所以结果为 undefined
上面的代码等同于以下代码:
- function example(){
- var user = "newArray8888";
- console.log(this.user); //undefined
- console.log(this); //Window
- }
- window.example();
例 2:
- var person = {
- name:"newArray8888",
- say:function(){
- console.log(this.name); //newArray8888
- }
- }
- person.say();
这里的函数是定义在对象 person 上面的, 调用该函数的时候, 也是通过 person.say 调用的, 所以这里的 this 自然指向 person, 而 person 里面是有一个 name 属性值的, 所以结果为 newArray8888
以上两个例子是符合上述的认知的, 即 this 指向调用它的对象然而上面的认知是不完整的我们看下面这个例子
例 3:
- var name ="jack" ;
- var person = {
- name:"newArray8888",
- say:function(){
- console.log(this.name);
- }
- }
- window.person.say();//newArray8888
从这个例子可以看出, 如果按照上面认知的推论话, 这里的 this 最终应该指向 window, 结果为 jack 才对接着看下面这个例子
- var example = {
- a: 10,
- b: {
- a: 12,
- fn: function() {
- console.log(this.a);
- }
- }
- }
- example.b.fn(); //12
如果根据上面的推断的话, 这里的 this 应该指向 example 才对, this.a 结果应该为 10 才对这样看来, 可能你会觉得开头对于 this 指向的认知是错误的其实并不是, 只是不够准确而已以下三条补充
如果一个函数中有 this, 但是它没有被上一级的对象所调用, 那么 this 指向的就是 window
如果一个函数中有 this, 这个函数有被上一级的对象所调用, 那么 this 指向的就是上一级的对象
如果一个函数中有 this, 这个函数中被多个对象包含, 尽管这个函数是被最外层的对象所调用, this 指向的也只是它上一级的对象, 例 3 可以证明
接着往下看
例 4 : var example = {
- a: 10,
- b: {
- //a:12,
- fn: function() {
- console.log(this.a);
- }
- }
- }
- example.b.fn(); //undefined
这里 fn 函数被多个对象包含 (windowexampleb),
但是最终调用它的是它的上一级对象, 也就是 b 对象, 然而 b 对象中对于 a 属性的定义是没有的, 所以自然是 undefined, 即使 example 对象中拥有该属性 a = 10,
它也是访问不到的
还有下面这个更加迷惑人的
例 5:
- var example = {
- a: 10,
- b: {
- a: 12,
- fn: function() {
- console.log(this.a);
- }
- }
- }
- var other = example.b.fn;
- other() //undefined
这里我们将函数的定义赋给 oher 这个变量, 最终函数执行时, 是被 window 对象调用的, 即等于 window.other(), 在 window 对象中并没有对于 a 的定义, 所以为 undefined
当函数内部有返回值时, 即 this 碰到 return 时, 又会有些许的区别
例 6:
- function Factory(){
- this.name = "newArray8888";
- return {};
- }
- var example = new Factory();
- console.log(example.name)//undefined
例 7:
- function Factory(){
- this.name = "newArray8888";
- return funciton(){};
- }
- var example = new Factory();
- console.log(example.name)//undefined
例 8:
- function Factory(){
- this.name = "newArray8888";
- return 1;
- }
- var example = new Factory();
- console.log(example.name)//newArray8888
例 9:
- function Factory(){
- this.name = "newArray8888";
- return undefined;
- }
- var example = new Factory();
- console.log(example.name)//newArray8888
由以上四个例子我们可以看出, 如果返回值是一个对象, 那么 this 指向的就是那个返回的对象, 如果返回值不是一个对象那么 this 还是指向函数的实例但是又有一个特殊的, 即返回 null
例 10:
- function Factory(){
- this.name = "newArray8888";
- return null;
- }
- var example = new Factory();
- console.log(example.name)//newArray8888
虽然 null 也是对象, 但是在这里 this 还是指向那个函数的实例, 因为 null 比较特殊
来源: http://www.jianshu.com/p/c1f243d1db09