当前位置: 首页 > 科技观察

前端高级基础:JS原型、原型链、对象

时间:2023-03-17 19:18:22 科技观察

1.普通对象和函数对象在JavaScript中,一切皆对象!但对象也不同。分为普通对象和函数对象,Object和Function是JS自带的函数对象。以下示例说明:varo1={};varo2=newObject();varo3=newf1();functionf1(){};varf2=function(){};varf3=newFunction('str','console.log(str)');console.log(typeofObject);//functionconsole.log(typeofFunction);//functionconsole.log(typeoff1);//functionconsole.log(typeoff2);//functionconsole.log(typeoff3);//functionconsole.log(typeoff3);//functionconsole.log(typeoff1);log(typeofo1);//objectconsole.log(typeofo2);//objectconsole.log(typeofo3);//object上面例子中o1o2o3是普通对象,f1f2f3是函数对象。如何区分其实很简单。通过newFunction()创建的对象都是函数对象,其他都是普通对象。归根结底,f1和f2都是通过newFunction()创建的。函数对象也是通过NewFunction()创建的。2.构造函数先来回顾一下构造函数的知识:functionPerson(name,age,job){this.name=name;this.age=age;this.job=job;this.sayName=function(){alert(this.name)}}varperson1=newPerson('Zaxlct',28,'SoftwareEngineer');varperson2=newPerson('Mick',23,'Doctor');在上面的例子中,person1和person2都是Person的实例。这两个实例都有一个构造函数(constructor)属性,它(这是一个指针)指向Person。即:console.log(person1.constructor==Person);//trueconsole.log(person2.constructor==Person);//true我们需要记住两个概念(constructor,instance):person1和person2都是一个InstanceofconstructorPerson一个公式:实例的constructor属性(constructor)指向构造函数。3.原型对象在JavaScript中,只要定义了一个对象(函数也是对象),该对象就会包含一些预定义的属性。每个函数对象都有一个原型属性,指向函数的原型对象。functionPerson(){}Person.prototype.name='Zaxlct';Person.prototype.age=28;Person.prototype.job='SoftwareEngineer';Person.prototype.sayName=function(){alert(this.name);}varperson1=newPerson();person1.sayName();//'Zaxlct'varperson2=newPerson();person2.sayName();//'Zaxlct'console.log(person1.sayName==person2.sayName);//true我们得到了本文的第一条“定律”:1.每个对象都有一个名为__proto__的属性;2.每一个构造函数(构造函数标准都是大写开头的,比如Function(),Object()等,JS自带的构造函数,还有自己创建的构造函数)都有一个名为prototype的方法(注意:既然是方法,它是一个对象(JS中的函数也是对象),所以prototype也有__proto__属性);3、每个对象的__proto__属性指向自己构造函数的原型;4.每个对象都有__proto__属性,但只有函数对象才有原型属性4.原型链的原型对象其实就是一个普通对象。几乎所有的对象都可能是原型对象或实例对象,也可能同时是原型对象和实例对象。这样的对象就是构成原型链的一个节点。所以,理解了原型之后,原型链就不是那么复杂的概念了。我们知道所有的函数都有一个叫做toString的方法。那么这个方法具体在哪里呢?先随便声明一个函数:functionadd(){}那么我们可以用下图来表示这个函数的原型链。原型链,其中add是Function对象的一个??实例。Function的原型对象也是Object原型的一个实例。这样就形成了一个原型链。原型链的访问其实和作用域链非常相似。它们都是单向搜索过程。因此,实例对象可以通过原型链访问原型链上对象的所有属性和方法。这就是foo最终可以访问Object原型对象上的toString方法的原因。基于原型链的特点,我们可以很容易的实现继承。了解了具体的基础知识之后,我们来分析下图:***首先从实例add()来分析实例add()。实例add()是Function的实例,所以add()的__proto__指向其构造函数的原型,即Function.prototypevaradd=function(){}add.__proto__===Function.prototype//truePay特别注意构造函数Funciton的__proto__指向自己的Function.prototypeFunction.__proto__===Function.prototype//true所以构造函数Function和Prototype的__proto__都指向Function.prototype其次,因为Function和Object都是js和Object的内置函数也是通过newFunctiontypeofFunction"function"typeofObject"function创建的,所以Object的__proto__指向Function的原型对象,也就是Function.prototypeObject.__proto__===Function.prototypetrue所以Object的原型和Function.prototype的__proto__都指向Object.prototype第三个Object.prototype被称为原型链的E端,因为它的__proto__为null