search

Home  >  Q&A  >  body text

javascript中的this问题,帮帮忙。

function A() {
    this.age = 100;
}

A.prototype = {
    constructor : A,
    sex : this.age,
    click : function () {
        return this.age;
    }
};

var a = new A();
console.log(a.sex);     // undefined
console.log(a.click()); // 100

为什么a.sex没有值,而click()却可以?原理上是怎么回事,最后不都是指向a对象么?

黄舟黄舟2906 days ago562

reply all(6)I'll reply

  • 巴扎黑

    巴扎黑2017-04-10 14:41:50

    你的写法等同于以下:

    function A() {
      this.age = 100;
    }
    
    A.prototype.constructor = A;  // 这个 OK,没有歧义,很好理解
    A.prototype.sex = this.age;   // 此时的 this 是谁?没有歧义,是 window 对象
    A.prototype.click = function () {
      return this.age; // 此时的 this 是谁?不知道。直到 click 方法被调用的那一刻才能知道
    };
    

    因此:

    var a = new A();
    
    console.log(a.sex);  // 实际访问的是 window.age,一个不存在的属性,所以 undefined
    console.log(a.click()); // click 被 a 对象调用,返回 this.age,也就是 a.age,所以 100
    

    如果在 a.sex 之前定义 window.age

    var a = new A();
    
    window.age = 50;
    console.log(a.sex);     // 50
    console.log(a.click()); // 100
    

    补充:我觉得你的错误就在于在此种情况下:


    A.prototype = { constructor: A, sex: this.age, click: function () {...} };

    很单纯的把 = {...} 这里的对象字面量当成了 A 原型对象,所以就得出结论:

    A 的实例对象一定会继承 A.prototype = {}

    然而,当你这样写 A.prototype = {} 的时候,你并没有去扩展 A.prototype,而是用一个新的对象字面量重写了 A.prototype,而这个新的对象字面量创建于 window 之下,于是里面的 this.xxx 自然不可能指向你设想的 a

    这种错误很容易察觉,只要你坚持这样去写:

    A.prototype.sex = this.age;
    

    this 的指向就会变得一目了然。这就是为什么所有的代码规范都不推荐用新对象覆盖原型属性的原因(之一)。

    reply
    0
  • 高洛峰

    高洛峰2017-04-10 14:41:50

    在你给sex赋值的时候,this的值是window,至于原理,你可以参考一下页面右边的相似问题

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 14:41:50

    var age=100;
    function A() {
        this.age = 100;
    }
    
    A.prototype = {
        constructor : A,
        sex : this.age,
        click : function () {
            return this.age;
        }
    };
    
    var a = new A();
    console.log(a.sex);     // 100
    //this 是在调用到它时,才定的; a.sex  中的 this  指向了 window 对象
    console.log(a.click()); // 100
    // a.click()  中 this 指向了 a
    // ps 这只是我的理解,详细可以看 汤姆大叔的博客中的说明
    

    http://www.cnblogs.com/TomXu/archive/2012/01/17/2310479.html

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 14:41:50

    sex : this.age 是A.prototype的一个属性,A.prototype也是一个普通的对象,所以这个sex找的是A.prototype所包含的age属性,没有则undefined,

    click : function () {
            return this.age;
        }
    

    中的this.age指向A的一个本地属性,实例固然可以访问到,

    请先了解javascript作用域相关知识

    reply
    0
  • 怪我咯

    怪我咯2017-04-10 14:41:50

    prototype 应该要跟函数的吧 ,直接赋予属性是不行的

    reply
    0
  • 巴扎黑

    巴扎黑2017-04-10 14:41:50

    一个function是一个作用域,click 的 function里面的作用域和A的作用域不同。

    呃,有人踩我,一个function是一个闭包,this指向不同,我哪里说错了啊,理解这个好多问题都解释通了

    reply
    0
  • Cancelreply