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?
网上看到的解释,但是不懂什么叫拓展,这样怎么就成了新的对象自重写了?
注释:新手忽视这一段。以一下说的都是 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 属性,叫做原型链。那么当我们 "读取" 对象的属性的时候,其实读取的是但是 写入 的时候就是 就不会从原型链里面查找,仅仅会赋值
obj.prop