一、原型的作用

1-1 通过原型共享属性和方法

  1. function Person(name,age) {
  2. this.name=name;
  3. this.age=age;
  4. }
  5. //通过原型来添加方法,解决数据共享,节省内存空间
  6. Person.prototype.eat=function () {
  7. console.log("吃凉菜");
  8. };
  9. var p1=new Person("小明",20);
  10. var p2=new Person("小红",30);
  11. console.log(p1.eat==p2.eat);//true
  12. console.dir(p1);
  13. console.dir(p2);


什么样子的数据是需要写在原型中?

  1. 需要共享的数据就可以写原型中,比如需要共享的属性和方法
  2. 不需要共享的数据写在构造函数中

二、原型: prototype和 proto

实例对象中有__ proto __这个属性,指向函数的原型,是一个对象,这个属性是给浏览器使用,不是标准的属性
构造函数中有prototype这个属性,叫函数的原型,是一个对象,这个属性是给程序员使用,是标准的属性
 function Person(name,age) {
      this.name=name;
      this.age=age;
    }
    //通过原型来添加方法,解决数据共享,节省内存空间
    Person.prototype.eat=function () {
      console.log("吃凉菜");
    };

    var p1=new Person("小明",20);
    var p2=new Person("小红",30);

    console.dir(p1);
    console.dir(p2);
    console.dir(Person);

    console.log(p1.__proto__==Person.prototype); //true
    p1.__proto__.eat();

三、构造函数、实例、原型三者之间的关系aa.jpg

  1. 任何函数都具有一个 prototype 属性,该属性是一个对象。 ```javascript function F () {} console.log(F.prototype) // => object

F.prototype.sayHi = function () { console.log(‘hi!’) }


2. 构造函数的 `  prototype 对象默认都有一个 `constructor` 属性,指向 `prototype对象所在函数。
```javascript
console.log(F.prototype.constructor === F) // => true
  1. 通过构造函数得到的实例对象内部会包含一个指向构造函数的 prototype 对象的指针 __proto__

    var instance = new F()
    console.log(instance.__proto__ === F.prototype) // => true
    console.log(instance.__proto__.constructor==F);
    console.log(instance.__proto__.constructor === F.prototype.constructor) // => true
    
  2. 总结

    1) 任何函数都具有一个 prototype 属性,该属性是一个对象
    2) 构造函数的 prototype 对象默认都有一个 constructor 属性,指向 prototype 对象所在函数
    3) 通过构造函数得到的实例对象内部会包含一个指向构造函数的 prototype 对象的指针 __proto__
    4) 所有实例都直接或间接继承了原型对象的成员
    5) 构造函数的原型对象(prototype)中的属性和方法是可以被实例对象直接访问的
    

四、原型方法的互访问

//原型对象中的方法,可以相互调用
function Animal(name,age) {
    this.name=name;
    this.age=age;
}
//原型中添加方法
Animal.prototype.eat=function () {
    console.log("动物吃东西");
    this.play();
};
Animal.prototype.play=function () {
    console.log("玩球");
    this.sleep();
};
Animal.prototype.sleep=function () {
    console.log("睡觉了");
};

var dog = new Animal("小苏",20);
dog.eat();

五、原生对象的原型

所有函数都有 prototype 属性对象。
1. Object.prototype
2. Function.prototype
3. Array.prototype
4. String.prototype
5. Number.prototype
6. Date.prototype
7. ...
//我们能否为系统的对象的原型中添加方法,相当于在改变源码
//我希望字符串中有一个倒序字符串的方法
String.prototype.myReverse = function () {
    for(var i=this.length-1;i>=0;i--){
        console.log(this[i]);
    }
};
var str = "abcdefg";
str.myReverse();


String.prototype.sayHi=function () {
    console.log(this+"哈哈,我又变帅了");
};

//字符串就有了打招呼的方法
var str2="小杨";
str2.sayHi();
//为Array内置对象的原型对象中添加方法
Array.prototype.mySort=function () {
    for(var i=0;i<this.length-1;i++){
        for(var j=0;j<this.length-1-i;j++){
            if(this[j]<this[j+1]){
                var temp=this[j];
                this[j]=this[j+1];
                this[j+1]=temp;
            }
        }
    }
};

var arr=[100,3,56,78,23,10];
arr.mySort();
console.log(arr);