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对象么?

A。prototype之后不应该等之后不应该等同于

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

这样吗?


写 A.prototype = {} 的时候,你并没有去扩展 A.prototype,而是用一个新的对象自变量重写了 A.prototype,而这个新的对象字面量创建于 window 之下,于是里面的 this.xxx 自然不可能指向你设想的 a?
网上看到的解释,但是不懂什么叫拓展,这样怎么就成了新的对象自重写了?

阅读 3.3k
4 个回答

注释:新手忽视这一段。以一下说的都是 ES5.1 且没有用use strict 在更高的版本中兼容,但是新定义的东西有些许区别,不过也只是 ES5.1 的语法糖。(先不讨论,call,apply,bind)
1、this
这个是在运行时,函数调用的时候决定次函数中的this等于什么的。首先函数是一个对象,跟其他对象/变量没有本质的区别,所以一个函数可以赋值给一个变量或是一个对象的属性,可以通过这个变量或是对象的属性调用这个函数。那么在写代码的时候函数调用可以分为两种写法 function_name() ; object.function_name() 后一种包括 obj1.obj2.function_name()的形式。第一种写法this的值是 window,第二种情况,this的值就是 function_name前面那个对象,而不管你实际的代码写在那里,值关心你调用函数时的写法。但是对于你这种情况,this 不在任何函数中,那么 this 的值就是 window。所以 sex的值是 window.age 也就是undefined,所以,不是不能访问,而是,就是 undefined

了解更多,可以继续往下读。不过不太好理解,多度几遍。

2、 其实还存在一种 this
其实函数调用还存在一种形式,那就是new functioin_name() 这个时候浏览器会创建一个新的对象,并且给这个对象添加用 js 代码不可访问的属性[[prototype]](先不讨论如何访问他的问题)。这个属性值就等于function_name.prototype。然后 this 就等于新创建的对象,然后运行函数中定义的代码。new的返回值就是这个新创建的对象(js 太麻烦了,先不讨论其他情况)。

3、原型链
上面说道new 的时候会创建一个新的对象,并且给一个内部属性赋值为函数的prototype,所以新创建的这个对象有一个 [[prototype]] 属性,某些当然[[prototype]]也可能存在[[prototype]] 属性。那么一个对象就有这样的属性obj.[[prototype]].[[prototype]].[[prototype]]...而他的值就是它构造函数的 prototype 属性,叫做原型链。那么当我们 "读取" 对象的属性的时候,其实读取的是

if(obj.prop) return obj.prop
else if(obj.[[prototype]].prop) return obj.[[prototype]].prop;
else if(obj.[[prototype]].[[prototype]].prop) return obj.[[prototype]].[[prototype]].prop;
......一直这样找下去
else { return undefined;}

但是 写入 的时候就是 就不会从原型链里面查找,仅仅会赋值 obj.prop

那个解答基本上正确的。
你做的事情是覆盖了A的prototype。
sex : this.age
这句话在执行时就会去找window.age,这显然是undefined,而click是调用这个方法时再去找,执行时this.age已经被构造函数赋值为100。

(新手,可能有些理解的不对,请各位指出,谢谢!)

function A(){
    //这里一般存放值
    age: 100
}
A.prototype = {
    constructor : A      //这句没什么作用在此处
    //这里一般存放方法
    sex: this.age        //此处this 指向的应该是 window,既然要获取age的值,这自然是一个方法.
}

题主,sex: this.age 中的 this 指向的是(在你这个情况下)全局对象(或者说 window),而且JavaScript是按值传递的,因此,sex 属性并不保存对 this.age 的引用,保存的是其值。用代码说就是酱紫:

var age = 1;
var test = {
    sex: this.age
};
console.log(test.sex);//1
age = 2;
console.log(test.sex);//1

因此,执行 sex: this.age 的时候 sex 属性的值就是 this.age 指向的值,即 undefined 了,不会出现楼主期待的,当 GET sex 时会动态返回 this.age

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题