什么是原型?
打个比方:你想去旅游,但是你没钱,你父母有啊,你可以用你父母的钱去旅游!这个父母就是原型!!
贴段代码:
let arr=["对象在哪"]
console.log(arr.concat("对象在这")) //输出都知道就不看了
为什么arr可以使用concat方法,因为父亲(原型)有啊。父亲是不是还有父亲,所有原型上还有原型,原型上还有院校就形成了原型链。
对象也可以没有原型,这就要用上Object.create()方法创建,new也可以。两者有什么区别呢?
通过Object.create(null) 创建一个干净的对象,也就是没有原型,而 new Object() 创建的对象是 Object的实例,原型永远指向Object.prototype
原型方法和对象方法的优先级:
//自定义一个对象方法
let jx={
show(){
console.log("你真好看")
}
}
//往原型对象上添加一个方法
jx.__proto__.show=function(){
console.log("好好生活")
}
jx.show() //你真好看
结论:对象优先级大于原型优先级,好比旅游,你有钱(这个方法)就不会去找父亲(原型)要钱(上的方法)
函数:函数也是对象。函数有几个原型(prototype和__proto__)
- prototype 是函数(function) 的一个属性, 它指向函数的原型.
- proto 是对象的内部属性, 它指向构造器的原型, 对象依赖它进行原型链查询. 由上, prototype 只有函数才有, 其他(非函数)对象不具有该属性. 而 proto 是对象的内部属性, 任何对象都拥有该属性.
function user(){}
user.prototype.show=function(){
console.log('11');
}
console.dir(user);
let h=new user()
h.show()
console.log(user.prototype==h.__proto__)//true
user既是function 的实例对象,所以有__proto__,但只有函数才有prototype,所以user即是函数又是实例对象
function , Object , boolea,String,REGEXP(正则)的实例对象的__proto__和他们的构造函数的prototype一样
let arr= [] //new Array
console.log(arr.__proto__==Array.prototype) //true
let str ="" //new String
console.log(str.__proto__==String.prototype) //true
let bool = true
console.log(bool.__proto__==Boolean.prototype) //true
let reg=/a/i //new RegExp
console.log(reg.__proto__==RegExp.prototype) //true
let obj={} //new Object
console.log(obj.__proto__==Object.prototype) //true
我们可以自己自定义对象的原型设置:setPrototypeOf()。getPrototypeOf()可以查看原型上的属性和父亲
let jx={name:"jx"}
let xj={}
let parent = {name:"parent",
show(){
console.log("我是parent的方法")
}
}
Object.setPrototypeOf(jx,parent)//第一个为实例对象名,第二个为父亲,之前说过可以使用原型上的方法也就是父亲的方法,也就是一个继承的过程
jx.show(); //我是parent的方法
//console.log(jx.__proto__ == Object.prototype) //true
Object.getPrototypeOf(jx)
1.setPrototypeOf方法:给实例对象设置了一个名字为parent的父亲
2.getPrototypeOf方法:查看jx的原型,看到了他的父亲为parent
原型链:举个例子把:
let a={name:'a'}
let b={name:'b',
show(){
console.log('我是b中的方法'+this.name)
},
hello(){
console.log('我是b,你好呀')
}
}
let c={name:'c'}
Object.setPrototpeOf(a,b) //把a的父亲设置为b,也就是在b的原型链上a 的父亲变成了b,可以使用b的所有属性和方法(前提自己没有的情况下)
Object.setPrototpeOf(c,b)
a.show() //我是b中的方法 a
c.show() //我是b中的方法 c
所以当子集们都有一个公用的方法时,可以把这个方法写到父亲身上,子集上就不需要去一个个添加这个方法。比如:一个造车厂,车长,车宽是不是都固定的,车场就是父亲,每辆车就是儿子。儿子们都要这个方法,就写到父亲身上。