Appearance
cx
Appearance
本文将从什么是原型,原型是怎么由来的,原型链又是什么,原型与原型链之间的关系,以及和原型相关的一些api的概念解释
原型从字面意思就可以知道是一个事物的根本面目,那么什么才算是事物的根本面目呢
// 构造函数
function F() {}
// 实例
const f = new F()通过这个js代码很容易知道实例就是事物,而构造函数则是实例的本来面目。这也是我们常说的new 一个对象,来创建一个实例。
其实在类型判断的时候也有介绍过,使用constructor则可以知道是由构造器创造出来的(前提是没有故意修改掉这个属性)。
// 构造函数
function F() {}
// 实例
const f = new F()
console.log(f.constructor === F) // true
f.constructor = Object
console.log(f.constructor === F) // false在很多时候,我们new出来的实例可能会重复使用统一功能的函数,这个时候我们可以把方法或者数据存在在原型上,实现共享的功能
F.prototype.sayHello = function () {
console.log('Hello!')
}让实例能找到自己的原型对象
// 构造函数
function F() {}
// 实例
const f = new F()
console.log(f._proto_)当原型或者实例不断的继承时,就会出现一条继承的线路,我们把这样的线路称为原型链
原型链继承 利用prototype。通过下面的代码也可以知道当使用prototype继承的时候实例的constructor是使用的最顶层原型的构造器,因此我们也可以推断出这个constructor是和prototype同级别存放在构造器中的,然后constructor指向本身
function Parent() {
this.name = 'parent'
this.arr = [1, 2, 3]
}
Parent.prototype.getName = function () {
return this.name
}
function Child() {}
Child.prototype = new Parent()
const child1 = new Child()
const child2 = new Child()
child1.arr.push(999)
console.log('child1', child1, child1.arr) // child1 Parent {} [ 1, 2, 3, 999 ]
console.log('child2', child2, child2.arr) // child2 Parent {} [ 1, 2, 3, 999 ]
console.log(child1.constructor) // [Function: Parent]构造函数继承
function Parent() {
this.info = {
name: 'yhd',
age: 19,
}
}
function Child() {
Parent.call(this)
}
let child1 = new Child()
child1.info.gender = '男'
console.log(child1.info) // {name: "yhd", age: 19, gender: "男"};
let child2 = new Child()
console.log(child2.info) // {name: "yhd", age: 19}组合继承(原型链 + 构造函数继承)
function Person(name, age) {
this.name = name
this.age = age
this.friends = ['Yasuo', 'Zed', 'Yi']
}
Person.prototype.running = function () {
console.log('在跑步~')
}
function Student(name, age) {
Person.call(this, name, age)
this.score = 99
}
Student.prototype = new Person()
Student.prototype.goToSchool = function () {
console.log('去上学~')
}
let s1 = new Student('Cyan', 18)
let s2 = new Student('Csy', 22)
console.log(s1.name)
console.log(s2.name)
s1.friends.push('LeeSin')
console.log(s1.friends)
console.log(s2.friends)
console.log(s1.running())寄生式组合继承 Object.create()
function Person(name, age) {
this.name = name
this.age = age
this.friends = ['Yasuo', 'Zed', 'Yi']
}
Person.prototype.running = function () {
console.log('在跑步~')
}
function Student(name, age) {
Person.call(this, name, age)
this.score = 99
}
Student.prototype = Object.create(Person.prototype)
Student.prototype.goToSchool = function () {
console.log('去上学~')
}
let s1 = new Student('Cyan', 18)
let s2 = new Student('Csy', 22)
console.log(s1.name)
console.log(s2.name)
s1.friends.push('LeeSin')
console.log(s1.friends)
console.log(s2.friends)
console.log(s1.running())