Js深入了解原型对象
无论什么时候,只要新创建了一个函数,就会自动为这个函数创建一个prototype属性,这个属性指向这个函数的原型对象。
与此同时,这个原型对象也会创建一个constructor属性,这个属性指向prototype属性所在的函数的指针。
举个例子:
就上一篇文章的Person函数来说,Person.prototype就指向它的原型函数,而原型函数Person.prototype.constructor指向Person,大概就是这个意思。
当用构造函数创建一个新实例后,其内部会创建一个指针指向构造函数的原型对象。[[prototype]]
如何判断一个由构造函数创建的实例的属性[[prototype]]所指向的对象是某个构造函数的原型那?
判断方法如下:
Person.prototype.isPrototypeOf(person1);如果person1实例的[[prototype]]属性指向了Person函数所指向的原型对象,则返回true否则返回false。
如何获取一个实例的[[prototype]]属性?
方法如下:
Object.getPrototypeOf(person1)==Person.prototype;返回true
Object.getPrototypeOf(person1).name;返回原型中的name属性值。
每当代码读取某个对象的某个属性时,都会执行一次搜索,搜索顺序是,首先搜索对象实例本身,如果在实例中找到了具有给定名字的属性,则返回改属性值,如果没找到,则去搜索指针所子祥的原型对象。
如果对象中的属性名称与原型中的属性名称相同,则会屏蔽掉原型中的同名属性。
要取得对象上,所有可枚举的属性,可使用Object.key()方法,这个方法接收一个对象或者对象的实例作为参数,返回这个对象的可枚举的属性的数组。
例如:
var keys = Object.key(Person.prototype);//以上一节的Person对象为例,此时数组keys的值为[name,age,job,sayName]。
注意,这里返回的只是所传对象或实例中的属性数组,并不包含对象的原型中的属性。
如果想取得对象中的所有属性,不管该属性是否可枚举,可以使用Object.getOwnPropertyNames(Person.prototype);//此时返回的数组中,多了一个constructor属性。
更简单的原型对象创建语法:
function Person() {} Person.prototype = { name:"aa", age:26, job:"bb", sayName:function(){ alert(this.name); } }
上边这段代码相当于向Person对象重新定义了一个prototype属性,这个属性的指针指向了一个自定的对象,而并非系统所创建的原型,所以Person.prototype中不再有属性constructor属性。
解决办法是手动在prototype属性中,加入属性constructor:Perosn。或者更严谨一点,在上边的代码的基础上,加入如下代码:
Object.defineProperty(Person.prototype,"constructor",{
enumerable:false,
value:Person
});
使用原型创建对象需要强调一点,不能把Js中的原型完全理解为真正意义上的对象,传统的对象我们在实例化它之后,会在堆中分配一段内存来存放期实例,也就是说我们确实实例化了一个完整的对象,而Js中实例化对象后,实际上是创建了一个指向一个(公共原型+特性对象)的指针,其中的公共原型是所有实例共享且唯一,所以一个实例对原型的修改同事会反映在其他实例上。

浙公网安备 33010602011771号