构造函数和原型对象

2018-03-22  本文已影响0人  milletmi

javascript使用构造函数和原型对象来进行面向对象编程

构造函数

在 JavaScript 中,构造器其实就是一个普通的函数。当使用 new 操作符 来作用这个函数时,它就可以被称为构造方法(构造函数)。

{
function Person(){
    this.name ='millet'
}
let person1 =new Person();
console.log(person1.name)//millet
}
{
function Person(){
    this.name ='millet'
}
let person1 =new Person;
console.log(person1.name)//millet
}
{
function Person(){
    this.name ='millet'
}
let person1 =Person;
console.log(person1.name)//Uncaught TypeError: Cannot read property 'name' of undefined
}

{
function Person(){
    this.name ='millet'
}
let person1 =new Person();
console.log(person1)//
**
Person {
name:"millet"
__proto__:
constructor:ƒ Person()
arguments:null
caller:null
length:0
name:"Person"
prototype:{constructor: ƒ}
__proto__:ƒ ()
[[FunctionLocation]]:VM206:3
[[Scopes]]:Scopes[1]
__proto__:Object
}
**
console.log(person1.constructor === Person)//true
console.log(person1.__proto__.constructor === Person)//true
}
{
function Person(){
    this.name ='millet'
    return;
}
let person1 =new Person;
console.log(person1)//{name:"millet"}
}
{
function Person(){
    this.name ='millet'
}
let person1 =new Person;
console.log(person1 instanceof Person)//true
}
** 优化构造函数写法 **
{
function Person(){
   if(!(this instanceof Person)){
          return new Person()
    }
    this.name ='millet'
}
let person1 =Person;
console.log(person1.name)//millet
let person2 =new Person;
console.log(person1.name)//millet

}


原型对象

为了解决构造函数的属性和方法无法被对象实例所共享的问题,我们可以把需要共享的属性和方法放在原型(prototype)对象上。原型对象上的所有属性和方法,都会被对象实例所共享。对于构造函数来说,prototype是作为构造函数的属性;对于对象实例来说,prototype是对象实例的原型对象。所以prototype即是属性,又是对象。

{
function Person(){
    this.name ='millet'
}
let person1 =Person;
原型对象和实例对象的关系:
console.log(person.prototype=== Person1.__proto__ )//true
原型对象和构造函数的关系 :
console.log(Person.prototype.constructor === Person)//true
而实例对象和构造函数则没有直接关系,间接关系是实例对象可以继承原型对象的constructor属性:
console.log(person1.constructor === Person)//true
}

constructor属性是原型对象上的一个属性,可以被所有实例对象所共享。要注意的是,prototype是构造函数的属性,而constructor则是构造函数的prototype属性所指向的那个对象,也就是原型对象的属性。由于constructor属性是一种原型对象和构造函数的关系,所以在修改原型对象的时候,一定要注意constructor的指向问题

构造函数和原型组合模式

{
function Person(){
    this.name ='millet'
}
Person.prototype ={
constructor:Person,//重点,不写这一句的话console.log(person1.constructor === Person);//false
say: function(){
cosole.log(this.name )
}
}
let person1 =new Person;
console.log(person1.name)//millet
}

原型链的特点有

a:读取对象的某个属性时,JavaScript引擎先寻找对象本身的属性,如果找不到,就到它的原型去找,如果还是找不到,就到原型的原型去找。如果直到最顶层的Object.prototype还是找不到,则返回undefined。

b:如果对象自身和它的原型,都定义了一个同名属性,那么优先读取对象自身的属性,这叫做“覆盖”(overiding)。

c:一级级向上在原型链寻找某个属性,对性能是有影响的。所寻找的属性在越上层的原型对象,对性能的影响越大。如果寻找某个不存在的属性,将会遍历整个原型链。

上一篇下一篇

猜你喜欢

热点阅读