在构造函数中,当有大千个相同属性时,繁琐而又复杂的一遍又一遍Ctrl C和V太过劳累?直接调用构造函数的制造对象的公共祖先——原型,哦,那就倍爽儿!
这里插入一下上次讲解的构造函数:
构造函数 (Constructor) : 构造函数是用来创建对象的函数。当使用 new 关键字来调用一个函数时,它会创建一个新的对象,并且这个新对象的原型会指向构造函数的 prototype 属性所指向的对象。
// Person.prototype 函数的原型 {} 祖先
Person.prototype.say = function() {
console.log('hello');
}
function Person() {
this.name = 'Tom'
}
let p1 = new Person()
p1.say()
在对象中没有的属性中访问出没有的代码say,结果应该是Undefined,看看打印的效果:
最后还是打印出了hello,这就是原型带来的效果,在p1中隐式具有say,为啥是隐式?这里你确实存在,但是在代码中你并没有看到。
原型的作用
Car.prototype.name = 'su7'
Car.prototype.lang = 5000
Car.prototype.height = 1400
function Car(color,owner) {
this.color = color
this.owner = owner
}
let tian = new Car('black','tiantian')
let xuan = new Car('red','xuanxuan')
console.log(tian.name);
这里还是会打印出原本name的属性:su7,所以将定死的属性可以通过原型直接访问,提高了代码的执行效率。
PS D:\zcl_fullstuck_ai-master\zcl_fullstuck_ai-master\zcl_fullstuck_ai-master\JS\原型> node 2.js
su7
原型功能:
- 实例对象可以修改显示继承到的属性,但是无法修改隐式继承到的属性(原型上的)
- 实例对象无法给原型新增属性
- 实例对象无法删除原型上的属性
Car.prototype.product = 'xiaomi'
function Car() {
this.name = 'su7'
}
let car = new Car()
car.name = '保时捷'
car.product = 'huawei'
console.log(car);
这里打印出huawei,在原型product上,它并不是修改xiaomi 这个属性,而是增加了huawei,即 实例对象可以修改显示继承到的属性,但是无法修改隐式继承到的属性(原型上的)。
Car.prototype.nickname = 'xiaohong'
delete Car.prototype.product
通过这两行来进行删除和新增。所以实例对象无法给原型新增属性,实例对象无法删除原型上的属性。
原型对象
对象的隐式原型 === 创建它的构造函数的显示原型。所以js引擎在查找属性时,会先查找对象显示具有的属性,找不到,在查找对象的隐式原型( proto)
<script>
Person.prototype.say = function() {
console.log('hello');
}
function Person() {
}
let p = new Person
console.log(p.say());
</script>
现在对象中知道隐式原型,若是找不到,就在构造函数中找出显示原型,两者是相等的。
function Person() {
}
let p = new Person()
console.log(Person.prototype);
// p._proto_ === Person.prototype
// Person.prototype === Object.prototype
// Object.prototype ===
这里再来理解一下隐式原型和显示原型的关系,知道Object的显示原型封顶。
原型链
js引擎在查找属性时,会顺着对象的隐式原型向上查找,找不到,则查找隐式原型的隐式原型, 一直向上,直到找到null位置,这种查找关系,称之为原型链
所有的对象都有原型?
不 Object.create(null) 没有原型
let a = {
name: 'Tom'
}
let obj = Object.create(null)
console.log(obj);
这里直接创建一个对象,让新对象隐式继承 a 对象的属性。
插入new的执行过程
function Foo() {
// var this = {
// a: 1
// }
// this._proto_ === Foo.prototype
this.a = 1
// return this
}
let f = new Foo()
- new 会在构造函数中创建一个 this 对象
- 执行函数中的逻辑代码 (相当于往this对象上添加属性)
- 让this的隐式原型等于Foo的显示原型
- return this 对象