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
对象么?
巴扎黑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
的指向就会变得一目了然。这就是为什么所有的代码规范都不推荐用新对象覆盖原型属性的原因(之一)。
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
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作用域相关知识
巴扎黑2017-04-10 14:41:50
一个function是一个作用域,click 的 function里面的作用域和A的作用域不同。
呃,有人踩我,一个function是一个闭包,this指向不同,我哪里说错了啊,理解这个好多问题都解释通了