原型
通过原型来添加方法,解决数据共享,节省内存空间
需要数据共享,节省内存空间时使用
类名.prototype.方法名=function(){}
//为内置对象添加原型方法 /* var arr = new Array(10,20,30,40,50); arr.join("|"); console.log(arr); var str = new String("哦!guoguo"); str.indexOf("g"); console.log(str); var dt = new Date(); dt.getFullYear(); console.dir(dt);*/ //实例中的方法如果没有,去创建该实例对象的构造函数的原型对象中找 //为系统的对象的原型中添加方法,相当于在改源码 String.prototype.myreverse=function(){ for(var i=this.length;i>=0;i--){ //this为调用这个方法的实例对象 console.log(this[i]); } } var str = "guoguo123"; str.myreverse(); //为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=[33,3,1,22,100]; arr.mySort(); console.log(arr); String.prototype.sayHi=function(){ console.log(this+"哈哈我瘦了"); } var hi = "guoguo"; hi.sayHi();
//什么样的数据是需要写在原型中的? //需要共享的数据就可以写在原型中 //原型的作用之一:数据共享 //属性需要共享,方法也需要共享 //不需要共享的数据写在构造函数中,需要共享的写在原型中 function Student(name,age,sex){ this.name=name; this.age=age; this.sex=sex; } //所有学生的身高都是188,体重都是55 //所有学生每天都写写500行代码 //所有学生每天都要吃西瓜 Student.prototype.height="188"; Student.prototype.weight="55KG"; Student.prototype.study=function(){ console.log("学习写500行代码"); }; Student.prototype.eat=function(){ console.log("吃西瓜"); }; //实例化对象并初始化 var stu = new Student("果果",20,"男"); console.dir(Student); console.dir(stu); // stu.eat(); // stu.study();
总结:
构造函数可以实例化对象
构造函数中有一个属性叫prototype,是构造函数的原型对象
构造函数的原型对象(prototype)中有一个constructor构造器,这个构造器指向的是自己所在的原型对象所在的构造函数
实例对象的原型对象(__proto__)指向的是该构造函数的原型对象
构造函数的原型对象(prototype)中的方法是可以被实例对象直接访问的
//构造函数 function Person(sex,age){ this.sex=sex; this.age=age; } //通过原型添加方法 Person.prototype.sayHi=function(){ console.log("你好"); } var per = new Person("男",20); console.dir(per); //实例对象 console.log(per.__proto__); //IE浏览器为undefined console.dir(Person); //构造函数 //实例对象中有两个属性(这两个属性是通过构造函数获得的),__proto__这个属性,浏览器使用的 //构造函数中并没有sex和age这两个属性 /* 实例对象中有两个属性,__proto__,也是对象,叫原型,不是标准的属性 构造函数中有一个属性,prototype,也是对象,叫原型,标准属性,程序员使用的 原型--> __proto__或者是prototype都是原型 作用:共享数据,节省内存空间 */
//使用对象 --->使用对象中的属性和对象中的方法,使用对象先要有构造函数 //构造函数 function Person(name,age){ //属性 this.name = name; this.age = age; //在构造函数中的方法 this.eat = function(){ console.log("吃榴莲"); }; /* this.sayHi = function(){ console.log("guoguo"); }; */ }; //添加共享的属性 Person.prototype.sex="男"; //添加共享的方法 Person.prototype.sayHi = function(){ console.log("guoguo"); }; //实例化对象,并初始化 var per = new Person("小明",20); per.sayHi(); //实例对象可以直接访问原型对象的属性或方法 /*如果想使用一些属性和方法,并且属性的值在每个对象中都是一样的,方法在每个对象中的操作都是一样的, 那么为了共享数据,节省内存空间,是可以把属性和方法通过原型的方式进行赋值*/ console.dir(per); //实例对象的结构 console.dir(Person); //构造函数的结构 //实例对象的原型__proto__和构造函数的原型prototype指向市相同的 //实例对象中的__proto__原型指向的市构造函数的原型prototype console.log(per.__proto__ == Person.prototype); //实例对象中__proto__是原型 //构造函数中的prototype是原型 //原型链:是一种关系,实例对象和原型对象之间的关系,关系是通过原型(__proto__)来联系的
原型链指向改变:
//构造函数中的this就是实例对象 //原型对象中的方法中的this就是实例对象 /* function Person(age){ this.age = age; console.log(this); }; Person.prototype.eat = function(){ console.log("上面是构造函数中的this"); console.log(this); console.log("这是原型方法中的this"); }; var per = new Person(10); per.eat(); console.log(per); */ /* function Student(){}; Student.prototype.study = function(){ console.log("加油努力学习"); }; Student.prototype = { eat:function(){console.log("我没报错");} }; var stu = new Student(); // stu.study(); 报错了 stu.eat(); */ //人的构造函数 function Person(age){ this.age = 10; }; //原型对象的方法 Person.prototype.eat = function(){ console.log("我想吃饭"); }; //学生的构造函数 function Student(){}; //学生的原型方法 Student.prototype.study = function(){ console.log("你好,努力学习哦"); }; //学生的原型方法指向了一个人的实例对象 Student.prototype = new Person(10); var stu = new Student(); stu.eat(); //我想吃饭 //stu.study(); 报错了、 //原型指向可以改变 //原实例对象的原型__proto__指向的是该对象所在构造函数的原型对象 //构造函数的原型对象(prototype)指向如果发生改变了,实例对象的原型(__proto__)指向也会发生改变 //原型的指向是可以改变的 //实例对象和原型对象之间的关系是通过__proto__原型来联系的,这个关系就是原型链 </script>
原型的指向是可以改变的
实例对象和原型对象之间的关系是通过__proto__原型来联系的,这个关系就是原型链
原型的最终指向:
function Person(){ }; Person.prototype.eat=function(){ console.log("吃东西"); }; var per = new Person(); console.dir(per); console.dir(Person); //实例对象中有__proto__原型 //构造函数中有prototype原型 //prototype是对象 //prototype中也有__proto__ //实例对象中的__proto__指向的是构造函数的prototype //所以,prototype这个对象中的__proto__指向的应该是某个构造函数的prototype //Person中的prototype中的__proto__ console.log(Person.prototype.__proto__); //实例对象__proto__指向的是构造函数的原型对象 //原型对象的__proto__指向Object的prototype //Object的Prototype的__proto__指向的是null console.log(per.__proto__ == Person.prototype); //true console.log(per.__proto__.__proto__ == Person.prototype.__proto__); //true console.log(Person.prototype.__proto__ == Object.prototype); console.log(Object.prototype.__proto__);
个人总结:
构造函数创建实例对象
构造函数的原型对象的构造器指向构造函数
实例对象及__proto__指向构造函数的原型
原型对象的prototype中的__proto__属性指向的是Object的prototype
而Object的prototype的__proto__指向的数null
原文:https://www.cnblogs.com/guoguolt/p/12577322.html