原型

103 阅读2分钟

原型

什么是原型?

每个函数都会自带一个属性prototype(原型),这个属性是一个对象

原型的作用

  • 可以让同一个构造函数创建的所有对象共享属性和方法
  • 降低了内存的开销
  • 缺点:当一个对象修改属性的时候,其他对象的属性也会被修改,所以把属性放在构造函数的内部,方法放在原型对象中
  • 同名的属性和方法在构造函数中优先于原型上的属性和方法
function Person(){
    this.name = "刘德华";
}
Person.prototype.name = "蔡徐坤";

var p = new Person();
console.log(p.name);//刘德华
//相同的属性和方法名称,在构造函数中会优先于构造函数的原型

什么是原型链?

访问某个属性或是方法,首先在对象自身的属性和方法中查找,当自身没有该属性和方法,就会去构造函数的原型中查找,当它也没有的时候,就会去它的上一层的原型中查找,这个查找的过程,就叫做原型链

标准写法

<script>
    //属性放在构造函数中
    function Person(name,age,sex){
        this.name= name ;
        this.age = age;
        this.sex = sex;
    }

    console.log(Person.prototype);  //值, 是一个对象

    //方法放在构造函数的原型中
    //单个单个添加方法
    // Person.prototype.eat = function(){}
    // Person.prototype.run = function(){}
    // Person.prototype.sleep = function(){}

    //批量添加方法
    Person.prototype = {
        constructor:Person,//让构造器强行指回构造函数
        eat(){},
        run(){},
        sleep(){}
    }
    console.log(Person.prototype);
</script>

原型中的一些细节

hasOwnProperty( )判断实例对象中是否存在该属性和方法

  • 构造函数中存在这个属性或是方法,就为true,否则就为false
function Person(){
    this.name = "刘德华";
}
Person.prototype.name = "蔡徐坤";
var p = new Person();
//构造函数存在 name 就为true,构造函数中没有 name就为false
console.log(p.hasOwnProperty("name")); //true

in 在原型中,会判断是否有这个属性或方法

  • 构造函数或是原型中存在这个属性或是方法,就为true,否则都不存在就为false
function Person(){
    this.name = "刘德华";
}
Person.prototype.name = "蔡徐坤";
var p = new Person();
console.log("name" in p);//true
console.log("sex" in p);//false

通过上面两个知识点可以封装一个用来判断是否存在于原型中的属性或方法的函数

function Person(){
    //this.name = "刘德华";
}
Person.prototype.name = "蔡徐坤";

var p = new Person();

//判断原型是否存在
function isPrototype(o,attr){
    //属性或方法存在就为true 且 构造函数中不存在attr就为false(取反为true)
    //同时满足两个条件,就可以判断属性和方法是不是属于原型上的
    return attr in o && !o.hasOwnProperty(attr);
}

console.log(isPrototype(p,"name"));//true