1. 什么是原型
在javascript中,原型是一个prototype对象,表示类型之间的关系。
其用途是为每个实例对象添加或者公有的属性和方法,它只是一个普通对象
在javascript中,每个对象都有prototype属性,可以看到如下数组对象
在这个例子中可以看到 array 对象的原型,其内容包括数组的所有属性和方法,如:pop、push、length等。
2.什么是原型链
在Javascript中,有句话叫万物皆对象。当然null和undefinde就不是对象,除了这两个其他都是对象。
而对象与对象之间都有其联系,并不是孤立存在的。
对象之间的继承关系,在javascript是通过prototype对象指向父类对象,直到指向了Object为止,这种关系就叫做原型链。
在下面例子中,创建了一个名"myObj"的构造函数,且在这个构造函数的原型中新增了一个方法 并且有两个test对象分别是 test1和test2,是myObj构造函数创建出来的
let myObj = function(name){
this.name = name
}
myObj.prototype.getName = function(){
return this.name
}
let test1 = new myObj('ywpb')
let test2 = new myObj('juejin')
myObj.prototype === test1.__proto__ //true
myObj.prototype === test2.__proto__ //true
typeof myObj.prototype === 'object' //true
可以看到,在这个例子中,test1和test2实例都继承了myObj的原型,都有一个自定义的原型对象方法 getName()
总结:
构造函数的prototype属性值就是对象的原型
构造函数的prototype属性类型是 object类型 (typeof myObj.prototype === 'object')
对象的原型链终点为null (Object.prototype.__proto__ === null)
对象的__proto__的属性值就是对象的原型(Object.prototype === test1.__proto__)
3.[[prototype]]
在上面的例子中每个对象都有一个特殊的[[prototype]]的内置属性,这个内置属性其实就是对其他对象的引用
但是它的工作方式或者说这个[[prototype]]引用有什么用呢?
let myObject = {
a:2
}
myObject.a //2
在上面这个例子中,创建一个myObject对象,设置对象的属性,并且对属性进行引用 在对象中,当试图引用一个属性,都会触发一个[[Get]]操作。 比如myObject.a,对于javascript中对象的[[Get]]默认方法的第一步是检查自身有没有这个属性,如果有就使用
let newObj = {
a:2
}
//让myObj关联到newObj对象
let myObj = Object.create(newObj)
myObj.a //2
在这个新例子中,创建了一个名为newObj的对象,并让myObj关联到newObj对象上。 在myObj对象中,尽管属性a并不存在,但是还是成功返回了a的值。
这是因为对于[[Get]]来说,当对象自身不存在属性并且[[prototype]]原型链不为空时,会继续查找下去,知道找到这个被引用的属性,或者没有找到这个属性同时返回undefinde