看过很多相关文中,有通俗易懂的,也有晦涩难懂的,但是只要不是自己整理的始终都不会消耗成自己的知识储备。建议都用自己的理解去整理,那样思路是自己的,日后就算忘记了,看一眼也马上可以记起来。
1、什么是原型对象prototype?
原型是一个对象,并且只有函数有prototype。
prototype对象中有一个constructor属性,指向了这个函数本身。
function test () {} var fn = new test() // test.prototype就是fn的原型对象,可以理解通过new 将 fn 和 test.prototype建立连接(原型继承) console.log(test.prototype.constructor === test) // true
2、什么是__proto__(隐式原型)?
_proto_实际上是某个实例对象的隐藏属性, 任何对象都有__proto__,指向它所对应的构造函数的原型对象
我到这个地方就有点乱了,什么关系指来指去,为什么定义的字符串/number/true、false变量都有__proto__。一脸懵逼啊!!!到这里就要岔开话题了,先了解下另外一个知识点,
js的三大包装对象Number()、String()、Boolean()
我们知道常用的 基本类型(原始类型):有 number、string、boolean、undefined、null
其中, number、string、boolean这三个类型比较特殊。在调用其某个方法时,JavaScript 引擎会自动将原始类型的值转为包装对象实例,也就是原始类型的“包装对象”。可以调用各种包装对象的属性和方法,在使用后立刻销毁实例。自动转换生成的包装对象是只读的,无法修改。
let str = 'hello word' console.log(str.length)
// 访问length属性,但str本身不是对象,不能调用length属性。
// javascript引擎自动将其转为String包装对象,在这个对象上调用length属性。调用结束后,这个临时对象就会被销毁。
// number、boolean类型等同
复杂类型: array、function、object
复杂类型是由js内置对应的构造器实例而来,Array、Function、Object
回归主题,__proto__指向它所对应的构造函数的原型对象
所以这里,第一步就很清晰了
let str = 'hello word' console.log(str.__proto__ === String.prototype) // true
let num = 1 console.log(num.__proto__ === Number.prototype) // true
let flag = true console.log(flag.__proto__ === Boolean.prototype) // true
function test () {} console.log(test.__proto__ === Function.prototype) // true
let arr = [] console.log(arr.__proto__ === Array.prototype) // true
let obj = {} console.log(obj.__proto__ === Object.prototype) // true
所有的构造器都是Function函数(构造器)的实例,所以以上所有构造器(String、Number、Boolean、Function、Array、Object)的__proto__,均指向Function.prototype
这里是不是感觉更加清晰了一点呢~ 出个题目
// 看看以下__proto__指向什么呢? console.log(Number.prototype.__proto__) let str = 'hello world' console.log(str.__proto__.__proto__)
解题
console.log(Number.prototype.__proto__) // Number.prototype 是个原型对象,故名思意,对象对象,对象是由Object函数构造而来。所以 Number.prototype.__proto__ === Object.prototype let str = 'hello world' console.log(str.__proto__.__proto__) // 第一步:str.__proto__ 指向其构造函数的原型对象,固str.__proto__ === String.prototype // 第二部:String.prototype.__proto__,是不是就是上一题,原型对象,对象由Object函数构造而来,所以 str.__proto__.__proto__ === Object.prototype
特比注意的是,所有 构造函数.prototype.__proto__ 都会指向Object.prototype 。唯独Object.prototype.__proto__ === null 。记不住的话就记住一句话,对象生万物,万物皆对象。
3、什么是原型链?
以上对原型对象和__proto__有了一定的了解,那什么是原型链?
当访问一个对象的某个属性时,会先在这个对象本身的属性上找,如果没有找到,会去这个属性的__proto__属性上找,即这个构造函数的prototype,如果还没找到,就会继续在__proto__上查找,直到最后一层,找不到即为undefined。这样一层一层往上找,彷佛是一条链子串起来,所以叫做原型链。
可以去找一些相关题目做个练习加深对原型和原型链的理解~