JavaScript学习总结--建立对象(3_原型)

 当咱们建立一个函数时,这个函数都会有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,这个对象包含了特定类型的全部实例共享的属性和方法前端

就象这样数组

仔细观察咱们能够发现,数组对象Array的prototype属性指向一个对象,而这个对象包含了不少属性和方法,其中就有咱们常见的length属性,以及pop()、push()、shift()等方法函数

那么也就是说,这些属性和方法被定义在Array的prototype上,为全部的实例对象(数组)共享this

因此咱们在定义数组以后就可使用这些属性和方法,且每个数组都引用自这个原型上的属性和方法,在原型上的属性是共享的,因此实例化一个新数组只会隐含指向这个原型对象的指针(__proto__)而不是彻底复制一份spa

因此咱们得知prototype

var aArr=new Array();
console.log(aArr.__proto__==Array.prototype);

在JavaScript内置对象Array上有一个prototype属性,指向了包含对全部数组共享属性和方法的一个对象,而经过Array实例化一个新数组,这个数组也有一个__proto__属性,也指向这个对象,这个对象在JavaScript中就叫作原型设计

那么一样的,Date对象也会有一个prototype属性,指向了包含对全部日期对象共享属性和方法的一个对象,经过Date对象实例化的一个日期对象也会有一个__proto__属性指向他们的原型指针

前面咱们说到,构造函数封装对象的本质就是模仿JavaScript的内置对象,那么既然内置对象共享的属性和方法都存放在这个prototype上,咱们本身建立的对象也能够吗?code

上一节咱们有一段代码是这样的对象

person_01.sayName==person_02.sayName;    //false

那么咱们使用原型来建立对象看看会不会有什么不一样

function Person(name,age,job){
  this.name=name;
  this.age=age;
  this.job=job;
}
Person.prototype.sayName=function(){
  //这样能够把方法写在原型上
  console.log(this.name);
}

//书上会绕一大个弯先把全部属性和方法都写在原型上,再讲某些属性不能共享之类的,这里跳过

var person_01=new Person("Sakura",22,"前端开发");
var person_02=new Person("Misaka",20,"网页设计");

这时咱们再来看看两个实例化对象的sayName方法是否是相等

person_01.sayName==person_02.sayName;    //true
//同时能够得知
person_01.__proto__==Person.prototype;    //true
person_01.__proto__==person_02.__proto__;    //true

同时在prototype对象上也有一个可有可无的属性constructor属性,这个属性指向原型所属的构造函数(能够认为是指向它所属的类型)

console.log(Person.prototype.constructor);
/*
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
}
*/
//由于实例化对象的__proto__属性也指向原型对象,那么
console.log(person_01.__proto__.constructor==Person.prototype.constructor);        //true

JavaScript实例化对象在调用属性时,首先会在构造函数内部查找属性,若是有则用这个属性,若是没有则在原型上查找

咱们知道person_01的constructor属性实际实在它的原型上,构造函数内部找不到constructor属性,因此它会继续往上在原型中查找,因此

console.log(person_01.constructor==Person.prototype.constructor);  

如何判断一个属性或方法在原型仍是在构造函数内部(实例属性)呢?

咱们使用hasOwnProperty方法

console.log(person_01.hasOwnProperty("name"));    //true

hasOwnProperty方法其实是判断属性是否在构造函数内,若是在构造函数内则返回true;若是在原型中则返回false

同时有一个in操做符,能够判断某个对象是否包含某一个属性,不管在原型仍是在构造函数中

console.log("name" in person_01);        //true

因此咱们能够结合这两个方法的结果来判断某个属性是否在原型中

待续

...

相关文章
相关标签/搜索