原型的作用:数据共享,节省内存空间
在构造函数中定义的属性和方法,当实例化对象的时候,实例对象中的属性和方法都是在自己的空间中存在的,如果是多个对象。这些属性和方法都会在单独的空间中存在,浪费内存空间,所以,为了数据共享,把想要节省空间的属性或者方法写在原型对象中,达到了数据共享,节省了内存空间。

通过原型为内置对象添加原型的属性或者方法

系统的内置对象的属性和方法可能不满足现在需求,所以可以通过原型的方式加入属性或者方法。为内置对象的原型添加属性和方法,这个内置对象的实例对象可以直接使用添加的属性或方法

  1. //为内置对象添加原型方法
  2. //我们在系统的对象的原型中添加方法,相当于在改变源码
  3. //我希望字符串中有一个倒序字符串的方法
  4. String.prototype.myReverse = function() {
  5. for (var i = this.length - 1; i >= 0; i--) {
  6. console.log(this[i]);
  7. }
  8. };
  9. var str = "abcdefg";
  10. str.myReverse();
  11. //为Array内置对象的原型对象中添加方法
  12. Array.prototype.mySort = function() {
  13. for (var i = 0; i < this.length - 1; i++) {
  14. for (var j = 0; j < this.length - 1 - i; j++) {
  15. if (this[j] < this[j + 1]) {
  16. var temp = this[j];
  17. this[j] = this[j + 1];
  18. this[j + 1] = temp;
  19. } //end if
  20. } // end for
  21. } //end for
  22. };
  23. var arr = [100, 3, 56, 78, 23, 10];
  24. arr.mySort();
  25. console.log(arr);
  26. String.prototype.sayHi = function() {
  27. console.log(this + "哈哈,我又变帅了");
  28. };
  29. //字符串就有了打招呼的方法
  30. var str2 = "小杨";
  31. str2.sayHi();

原型链是一种关系,是实例对象和原型对象之间的关系,这种关系是通过原型(proto)来联系的。JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

一,函数对象

一,函数对象
所有引用类型(函数,数组,对象)都拥有proto属性(隐式原型)
所有函数拥有prototype属性(显式原型)(仅限函数)
原型对象:拥有prototype属性的对象,在定义函数时就被创建

二、构造函数

  1. //创建构造函数
  2. function Word(words){
  3. this.words = words;
  4. }
  5. Word.prototype = {
  6. alert(){
  7. alert(this.words);
  8. }
  9. }
  10. //创建实例
  11. var w = new Word("hello world");
  12. w.print = function(){
  13. console.log(this.words);
  14. console.log(this); //Person对象
  15. }
  16. w.print(); //hello world
  17. w.alert(); //hello world
二,构造函数
print()方法是w实例本身具有的方法,所以w.print()打印hello world;
alert()不属于w实例的方法,属于构造函数的方法,w.alert()也会打印hello world,因为实例继承构造函数的方法。
实例w的隐式原型指向它构造函数的显式原型,指向的意思是恒等于
w. proto === Word.prototype
当调用某种方法或查找某种属性时,首先会在自身调用和查找,如果自身并没有该属性或方法,则会去它的proto属性中调用查找,也就是它构造函数的prototype中调用查找。所以很好理解实例继承构造函数的方法和属性
w本身没有alert()方法,所以会去Word()的显式原型中调用alert(),即实例继承构造函数的方法。

三,原型和原型链

  1. Function.prototype.a = "a";
  2. Object.prototype.b = "b";
  3. function Person(){}
  4. console.log(Person); //function Person()
  5. let p = new Person();
  6. console.log(p); //Person {} 对象
  7. console.log(p.a); //undefined
  8. console.log(p.b); //b


想一想p.a打印结果为undefined,p.b结果为b

  1. 解析:
  2. pPerson()的实例,是一个Person对象,它拥有一个属性值__proto__,并且__proto__是一个对象,包含两个属性值constructor__proto__
  3. console.log(p.__proto__.constructor); //function Person(){}
  4. console.log(p.__proto__.__proto__); //对象{},拥有很多属性值
  5. 我们会发现p.__proto__.constructor返回的结果为构造函数本身,p.__proto__.__proto__有很多参数
  1. 我们调用constructor属性,p.___proto__.__proto__.constructor得到拥有多个参数的Object()函数,Person.prototype的隐式原型的constructor指向Object(),即Person.prototype.__proto__.constructor == Object()
  2. p.__proto__.constructor返回的结果为构造函数本身得到Person.prototype.constructor == Person()所以p.___proto__.__proto__== Object.prototype
  3. 所以p.b打印结果为bp没有b属性,会一直通过__proto__向上查找,最后当查找到Object.prototype时找到,最后打印出b,向上查找过程中,得到的是Object.prototype,而不是Function.prototype,找不到a属性,所以结果为undefined,这就是原型链,通过__proto__向上进行查找,最终到null结束
  4. console.log(p.__proto__.__proto__.__proto__); //null
  5. console.log(Object.prototype.__proto__); //null
  6. 大家理解刚才的过程,相信下面这些应该也都明白
  7. //Function
  8. function Function(){}
  9. console.log(Function); //Function()
  10. console.log(Function.prototype.constructor); //Function()
  11. console.log(Function.prototype.__proto__); //Object.prototype
  12. console.log(Function.prototype.__proto__.__proto__); //NULL
  13. console.log(Function.prototype.__proto__.constructor); //Object()
  14. console.log(Function.prototype.__proto__ === Object.prototype); //true
  15. 总结:
  16. 1.查找属性,如果本身没有,则会去__proto__中查找,也就是构造函数的显式原型中查找,如果构造函数中也没有该属性,因为构造函数也是对象,也有__proto__,那么会去它的显式原型中查找,一直到null,如果没有则返回undefined
  17. 2.p.__proto__.constructor == function Person(){}
  18. 3.p.___proto__.__proto__== Object.prototype
  19. 4.p.___proto__.__proto__.__proto__== Object.prototype.__proto__ == null
  20. 5.通过__proto__形成原型链而非protrotype

原型和原型链 - 图1