JavaScript原型

1. 原型

  1. JavaScript中,一切皆对象

  2. 对于基本数据类型,也有包装类型把它们包装成一个对象来使用

  3. 只要是对象,那么就一定有属性和方法

对于函数,也是对象,那么他也有属性和方法

那有什么属性呢?

函数一旦声明成功,那么每个函数对象都有一个属性prototype

这个prototype指向的就是函数的原型对象

而原型对象中也有一个属性constructor指向的是该函数

浏览器对于构造函数new出来的对象,也可以通过一个隐藏的属性__proto__来找到构造函数的原型对象

注意:对于普通函数来说,原型没有用处,所以只关心构造函数的原型

如图:

JavaScript原型

那么我们在创建一个构造函数时:

function Person(name,age,sex){
    this.name=name;
    this.age.=age;
    this.sex=sex;
    this.speak=function(){
        console.log("我的名字是"+this.name);
    }
}
var p1=new Person("张三",18,"男");
var p2=new Person("李四",28,"男");

如图:对于每个由new Person出来的对象都会拥有自己一个独有的speak()方法,那么就会占据大量的内存

JavaScript原型

既然原型存储是一些公共的东西,那么我们可以将方法存入原型中,自己的属性还是存储在对象中

function Person(name,age,sex){
    this.name=name;
    this.age.=age;
    this.sex=sex;
}
Person.proto.speak=function(){
    console.log("我的名字是:"+this.name);   //this  哪个对象调用这个方法,this就是谁
}
var p1=new Person("张三",18,"男");
var p2=new Person("李四",28,"男");

在对象中找到了要的属性或方法,则会直接使用,如果找不到的属性或方法,浏览器会自动去他的构造函数的原型中找

如图:

JavaScript原型

p1.speak();

调用speak方法时,现在自身找有没有speak方法,如果有直接使用,没有则顺着图中的红色线找向构造函数的原型对象中,找到了speak方法就使用原型中的speak方法

注意:

function Person(name,age) {
        this.name = name;
        this.age = age;
    }
    Person.prototype.speak = function () {
        console.log("我的名字是:"+this.name);
    };
    Person.prototype.name="哈哈哈";
    var p1 = new Person("张三",29);
    var p2 = new Person("李四",18);
    p1.__proto__.speak();

如上所示,原型中有一个name属性,属性值为哈哈哈

那么使用p1.__proto__.speak();会输出张三还是哈哈哈呢???

答案应该是哈哈哈

因为p1.__proto__.speak();中是p1.__proto__在调用speak,那么this指向的就是p1.__proto__

那么this.name就会先去p1.__proto__中找name.

另外:

function Person(name,age) {
        this.name = name;
        this.age = age;
    }
    //自己创建一个原型对象,替换默认的原型对象,这样就具有了封装性,不然一个一个方法添加到原型中就不具有封装性
    Person.prototype={
        constructor:Person,  //将constructor指向自己
        speak : function () {
            console.log("我的名字是"+this.name);
        },
        eat : function () {
            console.log("吃吃吃");
        }
    }
    var p1 = new Person("张三",19);  //一定要先将原型对象替换好后才去创建一个对象,不然在之前的话就还是指向的默认的原型
    var p2 = new Person("李四",28);
    p1.speak();
    p2["eat"]();

如图:

JavaScript原型