原型
前面我们在 实例化 和 实例共享方法 时,都提到了原型。那么现在聊聊这个神秘的原型到底是什么?
1 什么是原型?
Father.prototype 就是原型,它是一个对象,我们也称它为原型对象。
2 原型的作用是什么?
原型的作用,就是共享方法。
我们通过 Father.prototype.method
可以共享方法,不会反应开辟空间存储方法。
3 原型中this的指向是什么?
原型中this的指向是实例。
原型链
1 什么是原型链?
原型与原型层层相链接的过程即为原型链。
2 原型链应用
对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在
每个对象都有__proto__原型的存在
function Star(name,age) {
this.name = name;
this.age = age;
}
Star.prototype.dance = function(){
console.log('我在跳舞',this.name);
};
let obj = new Star('张萌',18);
console.log(obj.__proto__ === Star.prototype);//true
复制代码
3 原型链图
4.4 原型查找方式
例如:查找obj的dance方法
function Star(name) {
this.name = name;
(1)首先看obj对象身上是否有dance方法,如果有,则执行对象身上的方法
this.dance = function () {
console.log(this.name + '1');
}
}
(2)如果没有dance方法,就去构造函数原型对象prototype身上去查找dance这个方法。
Star.prototype.dance = function () {
console.log(this.name + '2');
};
(3)如果再没有dance方法,就去Object原型对象prototype身上去查找dance这个方法。
Object.prototype.dance = function () {
console.log(this.name + '3');
};
(4)如果再没有,则会报错。
let obj = new Star('小红');
obj.dance();
复制代码
(1)首先看obj对象身上是否有dance方法,如果有,则执行对象身上的方法。
(2)如果没有dance方法,就去构造函数原型对象prototype身上去查找dance这个方法。
(3)如果再没有dance方法,就去Object原型对象prototype身上去查找dance这个方法。
(4)如果再没有,则会报错。
4.5 原型的构造器
原型的构造器指向构造函数。
function Star(name) {
this.name = name;
}
let obj = new Star('小红');
console.log(Star.prototype.constructor === Star);//true
console.log(obj.__proto__.constructor === Star); //true
复制代码
4.5.1 在原型上添加方法需要注意的地方
方法1:构造函数.prototype.方法
在原型对象上直接添加方法,此时的原型对象是有constructor
构造器的,构造器指向构造函数本身
function Star(name) {
this.name = name;
}
Star.prototype.dance = function () {
console.log(this.name);
};
let obj = new Star('小红');
console.log(obj.__proto__); //{dance: ƒ, constructor: ƒ}
console.log(obj.__proto__.constructor); // Star
复制代码
方法2:Star.prototype = {}
给原型重新赋值,此时会丢失构造器,我们需要手动定义构造器,指回构造函数本身
function Star(name) {
this.name = name;
}
Star.prototype = {
dance: function () {
console.log(this.name);
}
};
let obj = new Star('小红');
console.log(obj.__proto__); //{dance: ƒ}
console.log(obj.__proto__.constructor); // ƒ Object() { [native code] }
Star.prototype.constructor = Star;
复制代码
4.5.2 一般不允许直接改变原型prototype
指向
改变原型指向,会使原生的方法都没了,所以Array、String这些内置的方法是不允许改变原型指向的。如果改变了,就会报错。
Array.prototype.getSum = function (arr) {
let sum = 0;
for (let i = 0; i < this.length; ++i) {
sum += this[i];
}
return sum;
};
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(arr.getSum());//45
复制代码
如果改变prototype指向,会报错!
Array.prototype = {
getSum: function (arr) {
let sum = 0;
for (let i = 0; i < this.length; ++i) {
sum += this[i];
}
return sum;
}
};
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(arr.getSum());//45
复制代码