目录
- 1. 原型对象和对象原型
- 2. 原型继承
- 3. 原型链
1. 原型对象和对象原型
- 作用: 以前通过构造函数实例化的对象,每个实例化的对象的属性和方法都是独立的,会造成内存浪费。通过prototype对象原型能实现不同实例化对象共享公用的属性和方法,减少内存的使用
- 定义: 每个构造函数,都自动会有对应的一个prototype原型对象,可以通过prototype原型对象声明公用的属性和方法;而原型对象又有一个constructor属性指向构造函数。prototype原型对象的this都指向实例化的对象
- 使用: 通过构造函数实例化的对象,都会有一个
__proto__
对象原型,__proto__
对象原型也有一个constructor属性指向构造函数;同时__proto__
对象原型指向prototype原型对象(由Javascript底层实现),这样可以直接通过实例化的对象访问prototype原型对象的公用的属性和方法。注意: 有的浏览器不是__proto__
而是[[prototype]]
使用示例1:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// 构造函数
function Star(uname) {
this.uname = uname
}
// 原型对象
Star.prototype.sing = function () {
console.log('唱歌')
}
console.log(Star.prototype.constructor) // ƒ Star(uname) {this.uname = uname}
// 实例化对象
const lily = new Star('lily')
const tom = new Star('tom')
console.log(lily.sing === tom.sing) // true。减少了内存使用
console.log(lily.__proto__.constructor) // ƒ Star(uname) {this.uname = uname}
console.log(lily.__proto__ === Star.prototype) // true
</script>
</body>
</html>
使用示例2。可以声明原型对象prototype为一个对象,同时声明多个共享的属性和方法。但需要通过constructor重新指向构造函数Star,否则指向Object就找不到构造函数Star了
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// 构造函数
function Star(uname) {
this.uname = uname
}
// 原型对象
Star.prototype = {
constructor: Star,
sing: function () {
console.log('唱歌')
}
}
</script>
</body>
</html>
2. 原型继承
可以定义一个父类,然后通过原型继承来继承父类,最后实现子类自有的属性和方法
使用示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
// 父类
function Person() {
this.eyes = 2
this.head = 1
}
// 继承父类。然后添加子类独有的方法
function Woman() {
}
Woman.prototype = new Person()
Woman.prototype.constructor = Woman
Woman.prototype.baby = function () {
console.log('生孩子')
}
</script>
</body>
</html>
3. 原型链
- 构造函数的prototype原型对象也是一个对象,该对象的
__proto__
对象原型指向Object构造函数的prototype原型对象 - Object构造函数的prototype原型对象也是一个对象,该对象的
__proto__
对象原型指向null
原型链的查找规则如下。可以使用instanceof运算符,检测构造函数或实例化对象是否出现在某个实例化对象的原型链上
- 访问一个对象的属性和方法,先查找对象自身
- 在查找对象的prototype原型对象
- 再查找Object构造函数的原型对象
- 如果还查不到,就返回null
示例:
console.log([1, 2, 3] instanceof Array) // true
console.log(Array instanceof Object) // // true