当前位置: 首页 > Web前端 > JavaScript

学习笔记-JS原型与原型链的理解

时间:2023-03-26 20:21:21 JavaScript

上周一面试了腾讯。面试问题很基础。我自以为我的底子还不错,可是……好像不是。让我们来看看这个问题[].__proto__===?[].__proto__.__proto__===?[].__proto__.__proto__.__proto__===?平时最关心原型链的就是函数,从来没想过数组原型链,看到了自己基础上的漏洞。说原型链,先从原型说起。下面是我学习了原型和原型链后对这块的理解。如有错误,请指正~1.Prototype每个函数都会创建一个prototype属性,prototype属性是一个对象,包含了应该被特定引用类型的实例共享的属性和方法。其实这个对象就是调用构造函数创建的对象的原型。--《Javascript高级程序设计》上面这句话可以得到三个信息:当我们创建一个函数的时候,我们会创建一个prototype属性,它是一个js对象。(同时原型对象会得到一个constructor属性,该属性也是一个对象,指向相关的构造函数本身,例如:Person.prototype.constructor===Person;)原型的使用是:原型上的方法和属性可以被实例共享使用。例如,如果你想为一个数组定义一个方法,供所有创建的数组使用,你可以在Array.prototype上定义它;对象实例的__proto__指向构造函数的原型。至此,我对原型有了一个大概的了解。但是还是没明白一个问题,不是说“每个函数都会创建一个原型属性”吗?Array是数组对象,为什么会有原型属性。关于这个问题,我看了一下MDN,如图:Array构造函数会根据给定的元素创建一个JavaScript数组,除非只有一个参数,而且是一个数字。我们在创建数组的时候,可以直接用[]来创建,也可以用newArray()来创建。也就是说,关于Array(),是我的误解。它不是一个数组,而是一个构造函数,所以不难理解它有原型属性。2.原型链在这里,我们引用书上的话来解释一下原型链。重新审视构造函数、原型和实例之间的关系:每个构造函数都有一个原型对象,原型有一个指向构造函数的属性,实例有一个指向原型的内部指针。如果原型是另一种类型的实例怎么办?这意味着原型本身有一个指向另一个原型的内部指针,而这个原型又有一个指向另一个构造函数的指针。这在实例和原型之间构造了一个原型链。这就是原型链的基本思想。--也就是说,构造函数创建的每一个实例对象都有一个隐式原型__proto__,指向构造函数的prototype原型,而这个原型也有一个__proto__属性,所以一直往上直到endnull。至此,面试题的答案已经出来了。我将上面的内容总结为whose__proto__指向实例对象的原型。特例是:Function的__proto__指向自己的原型,Object的原型的__proto__指向null。按照我的结论看面试题:[].__proto__===?[].__proto__.__proto__===?[].__proto__.__proto__.__proto__===?答案应该是Array.prototype,Object。prototype,null第一个应该很容易理解,[]是由newArray()创建的,所以[].__proto__指向Array的prototype原型;第二个可以由第一个转换为Array.prototype。__proto__,在prototype部分,说prototype是一个js对象,也可以转化为Object.__proto__,最后是Object.prototype。第三个是Object.prototype.__proto__,为null。当时不知道这道题的时候,跟面试官说我不太懂数组的原型,函数和对象还行,然后又问了我一道题,我也不会....({}).__proto__===?现在很明显是Object.prototype。为什么要使用括号来防止错误。