- 可以用prototype访问的只有function类型其他类型只能使用getPrototypeOf或者_proto_,其他类型也都是通过function生成的(String,Number…涉及到隐式创建对象)
- 对象的原型只有一个引用 指向另外一个对象 对象原型之间的嵌套组成了原型链,原型链的作用是维护访问对象属性的查询 确定访问权限
用法
若存在A和B两个函数 让A的原型指向B
- 1.setPrototypeOf
Object.setPrototypeOf(A.prototype,B.prototype)
- 2.Create
A.prototype = Object.create(B.prototype)
两者都可以达到设置对象原型的功能,但是具体表现上有一些区别
比较
假设有Animal和 Plants两个函数用于生成对象 并在原型上具备一些方法 然后我们让Animal的原型指向Plants
初始代码如下
function Animal(name,sound){
this.name = name
this.sound = sound
}
Animal.prototype.shout = function(){
console.log(this.name + this.sound)
}
let dog = new Animal(pipi,'wangwang')
//定义Plants
function Plants(name){
this.name = name
this.sound = null
}
//函数接收参数用于区分
Plants.prototype.shout = function(xsss){
console.log(this.name + this.sound + 'plants tag')
}
Plants.prototype.genO2 = function(){
console.log(this.name + "生成氧气")
}
使用create
Animal.prototype = Object.create(Plants.prototype)
console.log(Animal.prototype)
/*
Plants {}
__proto__:
shout: ƒ (xssss)
genO2: ƒ ()
constructor: ƒ Plants()
__proto__: Object
*/
let cat = new Animal("mimi",'miaomiao')
dog.shout()//pipi wangwang
cat.shout //mimi miomiao plants tag
使用setPrototypeOf
Object.setPrototypeOf(Animal.prototype,Plants.prototype)
console.log(Animal.prototype)
/*
Plants {shout: ƒ, constructor: ƒ}
shout: ƒ (xssss)
constructor: ƒ Animal(name,sound)
__proto__:
shout: ƒ ()
genO2: ƒ ()
constructor: ƒ Plants()
__proto__: Object
*/
dog.shout()//pipi wangwang
cat.shout()//mimi mioamiao
cat.genO2() //mimi 生成氧气
总结
- 使用Object.create,Animal.prototype将会指向一个空对象,空对象的原型属性指向Plants的prototype,所以我们不能访问Animal的原有prototype中的属性。Object.create的使用方式也凸显了直接重新赋值
- 使用Object.setPrototypeOf则会将Animal.prototype 指向原有的prototyper 然后这个prototype的prototype指向Plants的prototype.所以我们优先访问的Animal,然后再是plants
- 在进行两个原型之间的委托时使用setPrototype更好,Object.create更适宜直接对一个无原生原型的对象快速进行委托
prototype与_proto_的区别
-
prototype是函数才有的属性
-
_proto_是每个对象都有的属性 (不推荐使用),推荐使用Object.getPrototypeOf/Reflect.getPrototypeOf和Object.setPrototypeOf/Reflect.setPrototypeOf
proto_可以理解为构造器的原型 即_proto === constructor.prototype
但是通过Object.create()创建的对象有可能不是
Object.create() 方法创建一个新对象,使用现有的对象来提供新创建的对象那个的_proto_
_proto_指向
字面量方式
2、构造器
从结果可以看出,大多数情况下 proto__可以理解为构造器的原型
及__proto===constructor.prototype,但是通过Object.create()创建的对象有可能不是 Object.create方法创建一个新对象 使用现有的对象来提供新创建的对象的__proto_