手机版

JavaScript中原型的完整解析

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

要理解JS中的原型,首先要理解以下概念:1。JS中的一切都是一个对象。

2.JS中的一切都是从Object派生出来的,即一切的原型链的终点都指向Object.prototype

//['构造函数',' toString ',' toLocaleString ',' valueOf ',' hasOwnProperty ',' isPrototypeOf ',/' properties isenumerable ',' __defineGetter_ ',' __lookupGetter_ ',' __defineSetter_ ',//' _ _ lookupundeter _ ']console . log(object . getown property names(object . prototype));3.JS中构造函数和实例(对象)之间微妙的关系。构造函数通过定义原型来规定其实例的规格,然后通过new来构造实例。它们的功能是生产物品。构造函数(方法)本身就是函数的实例,所以也可以找到它们的__proto__(原型链)。

Object/function F() {}是构造函数,一个是JS原生API提供的,一个是用户自定义的new Object()/new F(),是实例。实例只能“查看_ _ prototype _ _以了解它所基于的原型,但不能”重新定义实例的原型以尝试创建实例。

只有用自己的双手观察/思考,才能真正理解:

//我们来看看构造函数是什么//function empty(){ } function empty(){ } console . log(函数。原型,功能。_ _ proto _ _);//对象{}函数Empty(){ } console . log(Object . prototype,Object。_ _ proto _ _);函数F() {} //F {}函数Empty(){ } console . log(F . prototype,F . _ _ proto _ _);你可能晕倒了。让我们把它分解。

原型原型输出格式是:构造函数名称原型首先看看Object.prototype输出的是什么。Object { }-前者Object是构造函数的名称,后者代表原型。这里是一个{},也就是一个对象的实例(一个空对象),所以我们可以理解F {}是什么意思。f是构造函数的名称,原型也是一个空对象。

//我们来看看构造函数var o=new Object()构造的例子;//var o={ };//undefined Object { } console . log(o . prototype,o . _ _ proto _ _);函数F(){ } var I=new F();//未定义的F {} console.log(i.prototype,I . _ _ proto _ _);让我们更深入地定义f的原型,看看会发生什么。

function F(){ } F . prototype . a=function(){ };var i=新F();//未定义的F { a : function } console . log(I . prototype,I . _ _ proto _ _);这样我们就可以清楚的看到我是f构造的,原型是{a: function},也就是原来的空对象原型加了一个a方法。

换个说法吧。如果我们完全覆盖F的原型呢?

函数F(){ } F . prototype={ a : function(){ } };var i=新F();//undefined Object { a : function } console . log(I . prototype,I . _ _ proto _ _);咦~为什么这里显示我是被Object构造的?错了!因为我们完全覆盖了f的原型,它实际上将原型指定为对象{a: function},但这将导致原始构造函数信息丢失,变成对象{a: function}指定的构造函数。对象{a:函数}的构造函数是什么?因为对象{a:函数}实际上是相对于。

O={a:function () {}}//new有一个Object,所以o的构造函数当然是Object。

让我们纠正这个错误。

F(){ } F . prototype={ a : function(){ } }//再次指定正确的构造函数F . prototype . constructor=F;var i=新F();//未定义的F {a:函数,constructor:函数} console.log(i.prototype,I . _ _ proto _ _);现在我们又可以得到正确的原型信息了~

原型链

那我们来看看什么是原型链。简单地说,它与面向对象程序设计中的继承关系(链)一样,一层一层地查找,直到最终的对象原型

2016510172352211.jpg  (560248)

最重要的是找出JS中哪些对象是(实例)对象。这很简单。JS中的一切都是对象!说清楚,每个物体都有原型!

那我们来证明:

对象//这是一个函数,函数是函数的实例对象,所以是函数构造的对象。_ _ proto _ _==函数。原型//那么对象的原型,真//就是一个普通的对象。因此,实例函数。原型。_ _原型_ _==对象。属于object的prototype///true//已经在prototype链的顶端,所以最后指向null object。原型。_ _ proto _ _==null///true function/,也是函数,对吧?功能。_ _ proto _ _==函数。prototype//true function a(){ }//这是用户自定义函数,毕竟还是函数,对吧?A. _ _ proto _ _==函数。prototype//任何函数都是函数的实例,那么a的原型是什么呢?a=new a()a . _ _ proto _ _==a . prototype//实例a由构造函数构造。因此,a的原型是a . Prototype . _ _ Prototype _ _==Object.prototype//ordinary对象是对象的示例。prototype和_ _ prototype _ _每个对象都包含一个_ _ prototype _ _,它指向这个对象的“原型”。同样,每个函数都包含一个原型。这个原型对象是做什么的?

让我们看看下面的代码,使用构造函数创建一个对象(上面是以文字形式创建一个对象)。

function Foo(){ };var Foo=new Foo();console.log(foo。_ _ proto _ _);想想看,这个foo对象的__proto__会指向什么?

2016510172448163.png  (16368)

包含构造函数属性的对象?理解不好也没关系,打印出Foo函数的原型属性,对比一下就可以了。

function Foo(){ };var Foo=new Foo();console.log(foo。_ _ proto _ _);console . log(Foo . prototype);console.log(foo。_ _ proto _ _===Foo . prototype);2016510172512274.png  (18369)

最初,新对象foo的__proto__只指向函数Foo的原型。

foo有什么意义。_ _ proto _ _ _-foo。prototypejs?回想一下,在JS的世界中,对象不是根据类(模具)创建的,而是从原型(其他对象)派生的。

当我们通过执行新操作创建一个新对象时,我们一开始并不深入新操作的具体实现,但是有一点我们可以肯定的是,——指向新对象的__proto__的原型对象。

只有这个代码。

function Foo(){ };var Foo=new Foo();谁是福。__proto__指向?为什么不能指向Foo本身?虽然函数也是一个对象,但是这个机会将被详细讨论。但是,怎么Foo。__proto__指向foo是不合适的,因为Foo是一个有很多逻辑代码的函数。作为一个对象,foo继承逻辑处理是没有意义的,但是应该继承“原型对象”的属性。

因此,每个函数将自动生成一个原型对象,并且来自这个函数new的对象的_ _ prototype _ _将指向这个函数的原型。

福。_ _ proto _ _ _-foo。原型已经说了这么多,但我还是觉得不完全清楚,所以不如上一张图片。以前参考其他网友的图片,总觉得没说清楚,就自己画了一张。如果我觉得我的好,请点赞!(我很难画出来。).

2016510172555695.png  (800600)

让我们看看这张图片,记住以下事实:

1.每个对象都有一个_proto_ attribute。

JS世界中没有类(模具)的概念,对象是从另一个对象(原型)派生出来的,所以每个对象都会有一个_proto_ attribute指向它的原型对象。(参考左上角以文字形式定义的object obj,它在内存中打开了一个空间来存储对象本身的属性,同时生成了一个proto _指向它的原型——顶层原型对象。)

2.每个函数都有一个原型属性。

为什么“构造函数”叫构造函数,因为它是构造一个对象。根据上面的第一个事实,构造的新对象的_proto_ attribute指向谁?您不能总是指向构造函数本身。虽然它也是一个对象,但您不希望新对象继承函数的属性和方法。因此,每个构造函数都有一个原型属性,该属性指向一个对象,作为由该构造函数构造的新对象的原型。

3.函数也是对象。

每个函数都有一些常见的属性和方法,例如apply()/call()。但是这些常见的方法是如何继承的呢?这个函数是如何创建的?想想看,一切都是对象,包括函数,函数也是构造函数构造的对象。然后,根据上面的第二个事实,每个函数也将有一个指向其构造函数原型的_proto。这个构造器的函数是Function,JS中的所有函数都是函数构造的。函数的一般属性和方法存储在原型对象Function.prototype上

版权声明:JavaScript中原型的完整解析是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。