手机版

Javascript基础回顾(3) js面向对象

时间:2021-09-06 来源:互联网 编辑:宝哥软件园 浏览:

本来打算把系列表情的最后一篇文章由浅入深的继续下去,但是最近,团队突然忙起来了,从来没有过!不过喜欢表情的朋友可以放心,写了:)在他们的工作中,我们发现Javascript的一些基本原理普遍存在于这里或那里,所以我们决定花一些时间整理这些基本知识,与大家分享。培训用PPT稍后会附上。刚开始打算写一篇文章,后来写的时候发现越来越多,于是决定写一个系列。本系列的所有内容都与Javascript基础知识有关,但没有什么时髦的东西,但我相信这些基础知识会帮助你理解那些有趣的东西。

Javascript基础回顾(1)类型的Javascript基础回顾(2)范围的Javascript基础回顾(3)面向对象这是Javascript系列的第三部分,你必须知道。我们主要看Javascript是如何用面向对象编程的。主要涉及以下内容:

Javascript中的对象什么是对象遍历属性创建对象工厂模式构造器模式在函数、对象方法、构造器、调用和应用、绑定、dom元素事件处理程序中对此进行解释解释原型什么是原型和原型链通过原型链实现原型链中的继承问题

什么是物体

我们可以把Javascript中的对象理解为一组无序的键值对,就像Dictionarystring,C#中的Object一样。键是属性的名称,值可以是以下三种类型:

基本值(字符串、数字、布尔值、空值、未定义)对象函数var o=new Object();o[' name ']=' Jesse ';//基本值作为对象属性o['location']={//对象作为对象属性' city' :' Shanghai ',' district' : '闵行' };//函数作为对象属性o[' say hello ']=function(){ alert(' hello,我是' this.location.city '的' this . name ');} o . SayHello();遍历属性

在C#中,我们可以使用foreach来遍历Dictionarystring,Object。如果一个对象是Javascript中的一组键值对,我们如何遍历它?

for(var p in o){ alert(' name : ' p ' type : ' type of o[p]);}//name : name type : string//name : location type 3360 object//name : say hello type :函数。这个遍历将包括原型中的属性。我们将讨论什么是原型,以及如何区分原型和实例之间的属性。

事实上,我们已经在上面创建了一个对象,我们使用了以下两种方法来创建一个对象。

使用新建创建对象的实例。字面上,上面的O是以第一种方式创建的,而O中的位置属性是以字面上的方式创建的。事实上,第一个方法也有一个名为构造函数的模式,因为对象实际上是一个构造函数,它给了我们一个对象的实例。如果您仍然不清楚构造函数,请转到我的第一篇文章,类型基础对象和对象。

除了以上两种方法,我们还有一些创建对象的方法。让我们一起来看看它们:

工厂模式

函数createPerson(姓名、年龄、职务){ var o=new Object();o.name=nameo.age=年龄;o.job=jobo . SayName=function(){ alert(this . name);};返回o;} var person 1=createPerson(' Jesse ',29岁,'软件工程师');var person2=createPerson('Carol ',27,' Designer ');这种模式创建的对象的一个问题是,它在函数内部为我创建了一个对象的实例,这与我们的构造函数createPerson无关。

因为我用新的对象()在内部创建了这个对象,所以它是对象的一个实例。因此,如果我们想知道它是哪个函数实例,那是不可能的。

构造函数模式

工厂模式没有解决对象识别的问题,但是我们可以考虑一下。Object()实际上是一个函数,但是当我在它前面放一个new时,它就变成了一个构造函数,为我们生成Object的一个实例。然后我还可以在其他函数前面添加new,从而生成这个函数的一个实例,这个实例叫做构造函数模式。

功能人员(姓名、年龄、工作){ this.name=namethis.age=年龄;this.job=jobthis . SayName=function(){ alert(this . name);};}var p1=new Person('Jesse ',18,' coder ');警报(人的p1实例);//true详细解释这一点。这在Javascript中也可以看作是一个神奇的对象。是的,这是一个物体。我们在前面的作用域和作用域链中讨论了变量对象。变量对象确定在当前执行环境中可以访问哪些属性和函数。在某种程度上,我们可以把这个看作这个可变对象。我们之前提到最大的执行环境是全局执行环境,window是全局执行环境中的变量对象,所以这个===window在全局环境中会返回true。

除了全局执行环境,我们还提到了另一个执行环境,那就是函数。每个函数都有一个this对象,但有时它们所代表的值是不同的,这主要是由这个函数的调用者决定的。让我们看看以下场景:

功能

函数f1(){返回这个;} f1()===window;//全局对象因为当前函数运行在一个全局函数中,这个函数中的对象指向全局变量对象,也就是window。此方法在严格模式下返回undefined。

目标方法

var o={ prop: 37,f : function(){ return this . prop;}};console . log(o . f());//log 37在object方法中,这个对象指向当前的实例对象。注意:不管这个函数是在什么地方,什么时候,怎么定义的,只要是一个对象实例的方法,它的这个指向这个对象实例。

var o={ prop : 37 };var prop=15函数无关(){ return this.prop}o.f=独立;console.log(独立());//log 15 console . log(o . f());//log 37 difference :如果直接执行上面的函数无关,并且这指向全局执行环境,那么this.prop指向我们的全局变量prop。但是如果独立被设置为对象0的一个属性,那么这个在独立中指向这个实例,并且这个道具成为对象0的道具属性

构造器

当我们谈到用构造函数创建对象时,我们实际上利用了这个特性。在构造函数中,该对象引用由该构造函数实例化的对象。

功能人员(姓名、年龄、工作){ this.name=namethis.age=年龄;this.job=jobthis . SayName=function(){ alert(this . name);};}var p1=new Person('Jesse ',18,' coder ');var p2=新人(“卡罗尔”,16岁,“设计师”);当我们实例化Person并获得p1时,这指向p1。当我们实例化Person得到p2时,这指向p2。

使用调用和应用

当我们用call和apply来调用某个函数时,这个函数中的这个对象会绑定到我们指定的对象上。调用和应用的主要区别在于应用需要传入一个数组作为参数列表。

函数add(c,d){ return this . a this . b c d;}var o={ a: 1,b : 3 };//第一个参数将绑定到此对象add.call函数add的(o,5,7);//1 3 5 7=16//第二个参数是作为参数传入的方法addadd.apply(o,[10,20]);bind方法中的1 3 10 20=34

bind方法是Function.prototype.bind,它存在于函数的原型中,这意味着所有函数都会有这个方法。但是当我们调用某个方法的bind时,它会产生一个和原来的方法一样的新方法,只是这是指向我们传递的bind的第一个参数。

函数f() {返回this.a} var g=f . bind({ a : ' azerty ' });console . log(g());//azertyvar o={ a: 37,f: f,g :g };console.log(o.f()、o . g());//37,azerty在dom元素事件处理程序中

在事件处理程序中,我们的这个指向触发这个事件的dom元素。

HTML代码

html body div id=' my div ' style=' width :400 px;高度:400 px;' border:1px纯红;'/div脚本类型=' text/JavaScript ' src=' http : essential . js '/script/body/html JavaScript代码

功能点击(e){ alert(this . nodename);} var myDiv=document . getelementbyid(' myDiv ');myDiv.addEventListener('click ',click,false);当我们点击页面上的div时,毫无疑问它会显示DIV。

详细说明prototypeprototype就是prototype,这也是Javascrip中的一个重要概念。在讨论原型之前,我们需要回顾一下前面的构造器模式。当我们使用构造函数来创建对象时,我们主要使用这种特性。

功能人员(姓名、年龄、工作){ this.name=namethis.age=年龄;this.job=jobthis . SayName=function(){ alert(this . name);};}var p1=new Person('Jesse ',18,' coder ');var p2=新人(“卡罗尔”,17岁,“设计师”);上面我们还提到,当p1用Person实例化时,Person中的这个指向p1,当p2实例化时,这个指向p2。也就是说,虽然p1和p2中的sayName起着相同的作用,但它们实际上并不是一个函数。

也就是说,它们的内存堆中有多个副本,而不是引用堆栈中地址的副本。不说这个人物不符合面向对象的思想,至少是浪费内存。这个解决方案就是我们将要讨论的原型。

原型是什么

Javascript中的每一个函数都会有一个原型对象,和我们普通的对象没什么区别。仅在默认情况下,有一个指向此函数的构造函数属性。同时,这个函数的所有实例都将引用这个原型对象。如果不清楚,那就看看下图:

这些是构造函数、构造函数原型以及实例之间的关系。以我们的Person构造函数为例,Person (p1,p2)的所有实例都很舒服,一个原型属性指向Person构造函数的原型对象。这样,我们可以在原型上编写方法,然后我们的所有实例都将访问同一个方法。

功能人员(姓名、年龄、工作){ this.name=namethis.age=年龄;this.job=jobperson . prototype . SayName=function(){ alert(this . name);}}var p1=new Person('Jesse ',18,' coder ');var p2=新人(“卡罗尔”,17岁,“设计师”);alert(P1 . SayNAmE==p2 . SayNAmE);//true什么是原型链

你记得范围链吗?如果不记得,请在第二部分(范围和范围链)复习。简单来说,当我们在一个执行环境中访问一个变量的时候,如果这个变量在当前的执行环境中不存在,我们就会在这个执行环境的包含环境中寻找这个变量,也就是它的外层。如果找不到外层,我们会更进一步,直到找到全局执行环境。这是范围链。原型链有点像类型,但是场景被更改为我们的对象实例。如果我在一个实例中寻找某个不存在于这个实例中的属性,我会在它的原型中寻找它。请记住,正如我们上面所说,原型也是一个对象,它也有自己的原型对象,所以它成为一个链。如果实例在其自己的原型中找不到它,请在原型的原型对象中查找它,并将其扩展到对象的原型对象。默认情况下,我们创建的函数的原型对象指向object的原型对象,因此这就是为什么我们可以在自定义构造函数的实例上调用Object (tostring)的方法。

用原型实现继承

其实我们已经讲过继承在Javascript中的实现,主要是依靠原型链。所有实例都是从对象继承的,因为默认情况下,创建函数的所有原型对象的原型都指向对象对象。同样的,我们可以定义自己的继承关系。

功能人员(姓名、年龄、工作){ this.name=namethis.age=年龄;} person . prototype . SayName=function(){ alert(this . name);}函数Coder(语言){ this.language=language} coder . prototype=new Person();//将Coder的原型指向Person实例,以实现personcoder的后继者。语言'开发者,你好世界!');}函数设计器(){ } Designer . prototype=new Person();//将designer的原型指向Person实例,实现为Person designer . prototype . design=function(){ alert('其实我只是一个草绘器。');}var coder=新的Coder(' c# ');coder.name=' Jessecoder . SayName();//Jessecoder . code();//我是C#开发者,你好世界!var Designer=new Designer();设计师。姓名='卡罗尔';designer . SayName();//CarLodesigner . design();//其实我只是一个素描师。原型链中的问题

由于原型对象是通过引用存储的,我们在赋值时应该特别注意。如果我们不小心,我们可能会覆盖以前分配的值。比如在上面的代码中,我们先写原型方法,然后实现继承,那么我们的原型方法就没了。

函数Coder(语言){ this.language=language} coder . prototype . code=function(){ alert('我是‘this . language’开发者,Hello World!');} coder . prototype=new Person();//上面所有的原型属性和方法都会在这里被覆盖:var Coder=new Coder(' c# ');coder.name=' Jessecoder . SayName();coder . code();//这里会报错,找不到代码方法。所以这三篇文章都完成了

版权声明:Javascript基础回顾(3) js面向对象是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。