前端基本知识(二):JS的原型链的理解
? ? ? 之前一直对于前端的基本知识不是了解很详细,基本功不扎实,但是前端开发中的基本知识才是以后职业发展的根基,虽然自己总是以一种实践是检验真理的唯一标准,写代码实践项目才是唯一,但是经常遇到知道怎么去解决这个问题,但是不知道使用的是什么一种方法,方法的原理是什么,现在觉得大学里学习的基本知识还是很重要的,一定有自己的理解才能走的更远。 无论以后自己的学习新的技术,但是万变不离其宗,基本扎实,学习效率高。 废话这么多,开始了今天理解的四部分部分。 一、JS的原型链理解方式 二、原型理解 三、规则 四、js常见的创建对象的各种方法 一、原始链理解方式 每一次原型链理解起来很费劲,而且经常容易出错,或者解释的不到位。 1、什么是对象实例,什么是原型(对象)? 2、什么是构造函数? 3、通过原型对象找到构造函数 4、原型的唯一性 5、原型链 6、原型链最终指向为null 7、继承 8、原型链的继承 9、原型链的向上搜索 10、对象的属性可以自定义 11、对象实例不能改动原型属性 12、原型属性的共享 13、原型的动态性 14、原型的重写 我去,这也太多了,不想看了,我已经蒙圈了。等等,学习本身就是一个痛苦的过程,但是当你通过自己的理解的东西,这样运行机制就更容易理解。 你可以这样理解: 1、”人是人生的,妖是妖生的。“人和妖都是对象实例,人他妈和妖他妈都是原型,也叫原型对象。 2、“人出生和妖出生”都是构造一个函数,从无到有的过程 3、“人可以通过人他妈找到人他爸是谁”,也就是通过原型找到构造函数。 4、“人他妈可以生很多小宝宝,但是这些宝宝只有一个妈妈”,这就是原型的唯一性。 5、“人他妈的妈妈,和人他妈的妈妈的妈妈,。。。。”,这就是原型链 6、原型链并不是无限长,通过继承可以不断的往上找,最终原型链指向null 7、“人继承了人他妈的属性,妖继承了妖他妈的属性。” 8、“人继承了人他妈的肤色等等,人他妈继承人他妈他妈的肤色等等。。。”这就是原型继承。 9、“你没有家,你家指的就是你妈家;你妈没有家,那你家指向的就是你妈妈的妈妈的家“,这就是原型链的向上搜索。 10、“你会继承你妈的样子,但是你可以染发剪头发等等”,也就是说对象的属性可以的自定义。 11、"虽然你改变了自己的头发颜色等等,但是你不能改变你妈的样子",这就是对象实例不能改变原型的属性。 12、“你家玩火被你说了话,那就是说你家,你妈家,你弟弟们家,都被少了,这就是原型共享” 13、“你妈外号叫"小翠",邻居都叫你“小翠儿”,但是你妈做了一个帅气的发型,外号改成了“金毛狮王”,邻居都叫你,“金毛狮王子””,这就是原型的动态性。 14、“你妈爱美,整容了,没有人认识,然后又整回去了”,这就是叫原型的整体重写。 ? 在用代码说明原型链的之前,我们先弄清楚,函数和function有什么关系,构造函数,原型,实例之间有什么关系? 答:1、所有的函数都是 Function 的实例。 2、在构造函数上都有一个原型属性 prototype,该属性也是一个对象; 3、那么在原型对象上有一个 constructor 属性,该属性指向的就是构造函数; 4、而实例对象上有一个 _proto_ 属性,该属性也指向原型对象,并且该属性不是标准属性,不可以用在编程中,该属性用于浏览器内部使用。 person(name){.name=<span style="color: #0000ff;">function<span style="color: #000000;"> mother(){}
mother.prototype ={<span style="color: #008000;">//<span style="color: #008000;">mother原型自带属性prototypeage:20<span style="color: #000000;">,home:['Beijing','Shanghai'<span style="color: #000000;">] }; person.prototype=<span style="color: #0000ff;">new mother(); <span style="color: #008000;">//<span style="color: #008000;">person的原型为mother <span style="color: #0000ff;">var p1=<span style="color: #0000ff;">new person('Tom'); <span style="color: #008000;">//<span style="color: #008000;">p1:'Tom';proto:20,['Beijing','Shanghai'] <span style="color: #0000ff;">delete<span style="color: #000000;"> p1.age; person.prototype=<span style="color: #0000ff;">new mother(); <span style="color: #008000;">//<span style="color: #008000;">再次绑定 p1.proto.proto.proto.proto <span style="color: #008000;">//<span style="color: #008000;">null,原始链终点是null 二、原型理解 javascript中,原型也是一个对象,通过原型可以实现对象的属性继承,javascript的对象中都包含了一个protype内部属性,这个属性对应的就是该对象的原型。javascript的原型对象中还包含一个constructor属性,这个属性对应创建所有指向该原型的实例的构造函数。 注意:protype作为对象的内部属性是不可以直接访问的,但是谷歌浏览器提供了一个_proto_这个非标准的访问器。 三、规则 javascript中,每一个函数都有一个prototype属性,当一个函数被用作构造函数来创建实例,这个prototype属性值会被作为原型赋值给所有的对象实例(也就是所有实例设置“_proto_”属性)。 对象:prototype属性 原型对象:protype属性,construction属性 对象实例:_proto_属性 new的过程分为三步: var p=new person('张三',20); 1、var p={};初始化一个对象p 2、p._proto_=person.prototype;将对象p的_proto_属性设置为person.prototype 3、person.call('张三',20);调用构造函数person来初始化p。 原型链继承的主要问题在于属性的共享。原型继承的改良方法: (1)组合继承 .age=.hobby=['running','football'=<span style="color: #0000ff;">function<span style="color: #000000;"> person(name,age){
mother.call(<span style="color: #0000ff;">this,age); <span style="color: #008000;">//<span style="color: #008000;">第二次执行 <span style="color: #0000ff;">this.name=<span style="color: #000000;">name; } person.prototype=<span style="color: #0000ff;">new mother(); <span style="color: #008000;">//<span style="color: #008000;">第一次执行 person.protype.constructor=<span style="color: #000000;">person; person.prototype.showName=<span style="color: #0000ff;">function<span style="color: #000000;">(){ console.log(<span style="color: #0000ff;">this<span style="color: #000000;">.name); } <span style="color: #0000ff;">var p1=<span style="color: #0000ff;">new person('jack',20<span style="color: #000000;">); p1.hobby.push('basketball'); <span style="color: #008000;">//<span style="color: #008000;">p1:'jack';proto:20,['running','football'] <span style="color: #0000ff;">var p2=<span style="color: #0000ff;">new person('mark',18); <span style="color: #008000;">//<span style="color: #008000;">p2:'mark';proto:18,'football'] 执行结果如图所示: ? 四、js常见的创建对象的各种方法 (1)原始模式
person='Jack'18(){alert(
person=='Jack'=18=(){alert(.name);};
代码重用量大,所以产生了工厂模式。 (2)工厂模式
temp====(){alert(
工厂模式就是批量成产,效率 (3)构造函数
.name=.age=.sayName=(){alert( p1= person('Jack',18);
person('Jack',18);
构造函数与c++,、java构造函数类似,易于理解。 (4)原型方式
='Jack'=18=(){alert(<span style="color: #008000;">//<span style="color: #008000;">4、原型模式,字面量定义的方式
<span style="color: #0000ff;">function<span style="color: #000000;"> person(){ person.prototype=<span style="color: #000000;">{ name:'Jack'<span style="color: #000000;">,sayName:<span style="color: #0000ff;">function(){alert(<span style="color: #0000ff;">this<span style="color: #000000;">.name);} }; <span style="color: #0000ff;">var p1=<span style="color: #0000ff;">new person(); <span style="color: #008000;">//<span style="color: #008000;">name='Jack' <span style="color: #0000ff;">var p2=<span style="color: #0000ff;">new person(); <span style="color: #008000;">//<span style="color: #008000;">name='Jack' } 这里需要注意的是原型属性和方法的共享,即所有实例中都只是引用原型中的属性方法,任何一个地方差生的改动都会引起其他实例的变化。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |