javascript - js中this指向问题
PHPz
PHPz 2017-04-11 12:51:42
[JavaScript讨论组]

1、这两个代码的this指向让我懵逼了


2.1、

    var length = 10;
    function fn() {
        console.log(this.length);
    }
    var obj = {
        a: fn,
        length: 5,
        method: function (f) {
            //console.log(this===obj);//true
            f();
            //console.log(arguments)
            //arguments[0]();//
            //arguments[0].call(this);//
            //arguments[0].call(obj);//
        }
    };
    obj.method(obj.a);

2.2、

var name = 'out';
var obj = {
    name: 'in',
    prop: {
        name: 'inside',
        getName: function () {
            return this.name;
        }
    }
};

//console.log(obj.prop.getName());//
var test = obj.prop.getName;//
console.log(test());//


PHPz
PHPz

学习是最好的投资!

全部回复(4)
怪我咯

this 绑定的是当前对象,必须是直接调用。

非严格模式下

var length = 10;
var fun = function(){
    console.log(this.length);
};
var obj = {
   length : 5,
   test : function(){
     console.log(this.length);
   },
   test2 : fun
}

obj.test(); //5
obj.test2(); //5
fun(); //10 非直接调用,this == undefined;非strict会调用window

严格模式下

'use strict';
var length = 10;
var fun = function(){
    console.log(this.length);
};
var obj = {
   length : 5,
   test : function(){
     console.log(this.length);
   },
   test2 : fun
}

obj.test(); //5
obj.test2(); //5
fun(); //跑出异常,this == undefined;undefined.length 错误

所以:

 var length = 10;
    function fn() {
        console.log(this.length);
    }
    var obj = {
        a: fn,
        length: 5,
        method: function (f) {
            //console.log(this===obj);//true
            f();
            //console.log(arguments)
            //arguments[0]();//
            //arguments[0].call(this);//
            //arguments[0].call(obj);//
        }
    };
    obj.a();
    /*
      5
      因为符合直接调用的模式
    */
    obj.method(obj.a);
    /*
      10
      这里的 obj.a 仅是当作值来传,值为 一个函数
      f();不符合 object.method(),严格模式下报错
    */
var name = 'out';
var obj = {
    name: 'in',
    prop: {
        name: 'inside',
        getName: function () {
            return this.name;
        }
    }
};

//console.log(obj.prop.getName());//
var test = obj.prop.getName;//
console.log(test());//
/*
    out
    和上边一样,也不是 object.method() 这种情况
*/
怪我咯

只要看最后是谁调用就行了
1.obj.method(obj.a)//这时obj.a和obj.a()是不一样的,obj.a是取这个属性的引用,而不是调用
等价于 obj.method(function(){})//所以执行的时候就是直接执行函数而,this指向全局或者undefined
2.一样的道理obj.prop.getName是取属性值的引用,obj.prop.getName()这样才是调用,所以这时候this还是指向全局或者undefined

大家讲道理

1.this指向不看定义的时候在哪,而是看调用的时候指向。obj.method(obj.a)。那么调用的就是obj,而obj在全局作用域里面,所以this指向windowundefined(严格模式)。

2.调用的是testtest在全局作用域,所以name也是全局下的name。如果一定要修改这个指向,可以在这行:

    var test = obj.prop.getName.bind(obj);
    //或者
    var test = obj.prop.getName.bind(obj.prop);
    

再调用的时候就是in或者inside了

巴扎黑

上面的大哥回答的很好了,我稍作一点补充
问题1,2实际是一个道理,咱们三段论的方式来看一下这个问题

  1. var a = function(){console.log(this)}; 当调用a()时,this指向的window,因为a()window.a()等价

  2. 承上var obj = {method: a};'与var obj = {};obj.method = a`等价

  3. 承上obj.methodwindow.obj.method等价,则调用obj.method()this指向window.obj

  4. 承上

var length = 10;
function fn() {
    console.log(this.length);
}
var obj = {
    a: fn,
    length: 5,
    method: function (f) {
        f();
    }
};
obj.method(obj.a);

其中

// 我们一般称f为回调函数
obj.method = function (f) {
  f();
}
obj.a = fn
obj.method(obj.a)
//等价
(function(f){f();})(fn);
//等价
fn();
//等价
window.fn();
//等价
console.log(window.length);// 10

题目二你可以尝试自己分析一下,如果有哪里说得不对也欢迎大家指出。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号