这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天
前言
在js中,对象的底层实现采用了构造函数的形式。并且在对象的继承方面与其他语言有着巨大的差异,这就涉及到js独有的特性,原型链,从原型链中我们能够了解对象之间的关系。
构造函数
js中的函数本质是个对象, 可以通过与new关键字配合构造实例对象
//构造函数名首字母一般大写与普通函数区分
function Star(name, age) {
this.name = name
this.age = age
}
const ldh = new Star('kun', 2.5)
console.log(ldh)
输出结果
Star {name: 'kun', age: 2.5}
构造函数是在js还未推出class前构建类的解决方案
原型prototype
在js中,每个引用类型(对象、数组、函数)都存在其原型
函数在定义时会自动添加prototype属性
对象和数组在定义时会自动添加__proto__属性
function Star(name, age) {
this.name = name
this.age = age
}
const ldh = new Star('kun', 2.5)
const Star_prototype = Star.prototype
const ldh_prototype = ldh.__proto__
console.log(Star_prototype)
console.log(Star_prototype === ldh_prototype)
输出结果
{constructor: ƒ Star(name, age)}
true
可以得出通过构造函数得到的实例对象,其原型对象即为构造函数原型对象
并且可以发现原型对象上存在constructor属性,能够得到其构造函数
原型prototype的作用
多个实例对象中共用的属性或方法挂载在其原型对象上,避免了内存浪费,调用方法时若实例对象上不存在该属性或方法,则会顺其原型链向上查找直至找到或到达原型链尽头
function Star(name, age) {
this.name = name
this.age = age
this.sing = function() {
that = this
console.log('及你太美')
}
}
Star.prototype.jump = function() {
console.log('跳')
}
const kun1 = new Star('kun', 2.5)
const kun2 = new Star('kun', 2.5)
console.log(kun1.sing == kun2.sing)
console.log(kun1.jump == kun2.jump)
输出结果
false //sing方法未共用,浪费内存
true //jump方法共用
原型链
原型与原型间形成了类似链表的结构,并且实例对象和构造函数有参与,基本关系如下
ldh.proto->Star.prototype->Object.prototype->null
原型对象也与其构造函数和实例对象形成一个环状结构
const obj = new Object({})
console.log(obj.__proto__ == Object.prototype)
输出结果
true
Object实例对象也与Object构造函数、Object原型对象构成环状结构,并且学会了构建对象的新操作