JS中prototype属性的理解
来源:互联网 发布:淘宝店设计多少钱 编辑:程序博客网 时间:2024/04/26 09:05
1.prototype属性在js中模拟了父类的角色,在js中体现面向对象的思想
首先让我们来看两个demo:
demo1:
function Person(name,sex){this.name=name;this.sex=sex;}Person.prototype.age=12;Person.prototype.print=function(){alert(this.name+"_"+this.sex+"_"+this.age);};var p1 = new Person("name1","male");var p2=new Person("name2","male");p1.print();//name1_male_12p2.print();//name2_male_12Person.prototype.age=18;p1.print();//name1_male_18p2.print();//name2_male_18
demo2:
function Person(name,sex){this.name=name;this.sex=sex;}Person.prototype.age=12;Person.ptototype.print=function(){alert(this.name+"_"+this.sex+"_"+this.age);}var p1=new Person("name1","male"); //p1的age属性继承了Person类的父类(即prototype对象)var p2=new Person("name2","male");p1.print();//name1_male_12p2.print();//name2_male_12 p1.age=34 //改变p1实例的age属性p1.print();//name1_male_34p2.print();//name2_male_12Person.prototype.age=22;//改变Person类的超类的age属性p1.print();//name1_male_34(p1的age属性没有随着prototype属性的改变而改变)p2.print();//name2_male_22(p2的age属性发生了改变)p1.print()=function(){alert("i am p1")};p1.print();//I am p1(p1的方法发生了改变)p2.print();//name2_male_22(p2的方法并没有改变) Person.prototype.print=function(){alert("new print method")};//改变超类的方法p1.print();//I am p1(p1的print方法仍旧是自己的方法 )p2.print();//newprint method(p2的print方法随着超类的方法改变而改变)
js中对象的prototype属性相当于java中的static变量,可以被这个类下的所有对象公用。
从基础上来分析:
1.普通函数与构造函数
调用构造函数:new function_name();
调用普通函数:function_name();
在函数中有一个this对象,this始终代表该函数的调用者。
如果是构造函数,this就是构造出来的新对象。
如果是普通函数,this就是 window 对象。
如果使用new 关键字调用,那么函数的 return 语句不再起作用,因为这时还回的是 this 对象。
function Boo(name){ this.name=name; this.whatAreYou=function(){ return 'I am a '+ this.name; }; } var obj = new Boo("obj"); Boo.name = "Boo"; alert(obj.name + "\n" + Boo.name);
用构造函数定义对象的成员属性属性,用原型方式定义对象的成员方法。
这样的好处是:每个对象都共享一个方法,并且都具有自己独立的属性实例。
function Car(sColor,iDoors,iMpg) { this.color = sColor; this.doors = iDoors; this.mpg = iMpg; this.drivers = new Array("Mike","John"); } Car.prototype.showColor = function() { alert(this.color); }; var oCar1 = new Car("red",4,23); var oCar2 = new Car("blue",3,25); oCar1.drivers.push("Bill"); alert(oCar1.drivers); //输出 "Mike,John,Bill" alert(oCar2.drivers); //输出 "Mike,John"
js中的this的用法:
1、全局变量用法,纯粹函数调用。
function test() { this.x = 1; alert(x);}test();
var x = 1;function test() { alert(this.x);}test();//1var x = 1;function test() { this.x = 0;}test();alert(x);//0
2.作为方法调用,那么this就是指这个上级对象。
function test() { alert(this.x);}var o = {};o.x = 1;o.m = test;o.m(); //1
3、作为构造函数调用。所谓构造函数,就是生成一个新的对象。这时,这个this就是指这个对象。
function test() { this.x = 1;}var o = new test();alert(o.x);//1
4、apply调用
this指向的是apply中的第一个参数。
var x = 0;function test() { alert(this.x);}var o = {};o.x = 1;o.m = test;o.m.apply(); //0o.m.apply(o);//1
当apply没有参数时,表示为全局对象。所以值为0。
------this指针代表的是执行当前代码的对象的所有者。
js原型链和prototype的深入理解:
说到prototype,就不得不先说下new的过程。
<script type="text/javascript">var Person = function () { };var p = new Person();</script>
我们可以把new的过程拆分成以下三步:
<1> var p={}; 也就是说,初始化一个对象p。
<2> p.__proto__=Person.prototype;
<3> Person.call(p);也就是说构造p,也可以称之为初始化p。
关键在于第二步,我们来证明一下:<script type="text/javascript">2var Person = function () { };3var p = new Person();4alert(p.__proto__ === Person.prototype);5</script>
这段代码会返回true。说明我们步骤2的正确。
那么__proto__是什么?我们在这里简单地说下。每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样 一直找下去,也就是我们平时所说的原型链的概念。
按照标准,__proto__是不对外公开的,也就是说是个私有属性,但是Firefox的引擎将他暴露了出来成为了一个共有的属性,我们可以对外访问和设置。
<script type="text/javascript">2var Person = function () { };3Person.prototype.Say = function () {4alert("Person say");5}6var p = new Person();7p.Say();8</script>
那就让我们看下为什么p可以访问Person的Say。
首先var p=new Person();可以得出p.__proto__=Person.prototype。那么当我们调用p.Say()时,首先p中没有Say这个属性, 于是,他就需要到他的__proto__中去找,也就是Person.prototype,而我们在上面定义了 Person.prototype.Say=function(){}; 于是,就找到了这个方法。
<script type="text/javascript">02var Person = function () { };03Person.prototype.Say = function () {04alert("Person say");05}06Person.prototype.Salary = 50000; 07var Programmer = function () { };08Programmer.prototype = new Person();09Programmer.prototype.WriteCode = function () {10alert("programmer writes code");11}; 12Programmer.prototype.Salary = 500; 13var p = new Programmer();14p.Say();15p.WriteCode();16alert(p.Salary);17</script>
好,算清楚了之后我们来看上面的结果,p.Say()。由于p没有Say这个属性,于是去p.__proto__,也就是 Programmer.prototype,也就是p1中去找,由于p1中也没有Say,那就去p.__proto__.__proto__,也就是 Person.prototype中去找,于是就找到了alert(“Person say”)的方法。
其余的也都是同样的道理。
这也就是原型链的实现原理。
最后,其实prototype只是一个假象,他在实现原型链中只是起到了一个辅助作用,换句话说,他只是在new的时候有着一定的价值,而原型链的本质,其实在于__proto__!- JS中prototype属性的理解
- js中prototype的理解
- 简单理解js的prototype属性
- 简单理解js的prototype属性
- 简单理解js的prototype属性
- 简单理解js的prototype属性
- 简单理解js的prototype属性
- 对js中new、prototype的理解
- 关于js中prototype的理解
- js中prototype的理解摘录
- 关于JS中prototype的理解
- js的prototype属性
- js的Prototype属性
- js prototype的理解
- js中关于prototype属性
- JS的prototype属性小结
- 关于js的prototype属性
- js的Prototype属性详解
- 找一份andorid工作都需要具备哪些技术
- golang并发socket runtime实现
- hdu 1025
- 开始以为这是真的
- How to eat more Banana
- JS中prototype属性的理解
- Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度
- mybatis查询时间段sql语句
- Android SDL2.0 编译 --- ffplay android 移植过程
- 史蒂芬森地方
- php ?:
- sed常用方法与命令
- 很好用的工具网站
- listview item复用会造成显示不正确