Js | 原型链
先插播一段代码:怎样去判断是数组?
// 判断数组
let num = []
console.log(typeof num); //Object typeof 无法判断数组
console.log(num instanceof Array); //true
instanceof
// 创建对象的方式主要有以下几种:
// 第一种: 字面量
var Obj1 = {
name: 'o1'
};
var Obj2 = new Object({
name: 'o2'
});
// 第二种: 构造函数
var M = function (name) {
this.name = name
};
var Obj3 = new M('o3');
// 第三种: Object.create
var p = {
name: 'o4'
}
var Obj4 = Object.create(p);
console.log(Obj1)
console.log(Obj2)
console.log(Obj3)
console.log(Obj4)
注意第四个( _proto _ )!!!
原型链是实现继承的主要方法,要理解就要明白原型对象、构造函数、实例,三者之间的关系!!!
构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,实力也有一个指向原型对象的内部指针。
当这个原型对象是另一个类型的实例,那么这个原型对象就有一个内部指针指向另一个原型,以此类推就构成了一条原型链。原型链的根就是Object.prototype
//图片来自网络
在来一段简单的代码吧!!!
如上面列举的创建对象方式的第二种方式,M 就是一个构造函数,那么 M 就应该有一个 原型对象,可以通过 prototype 找到!而 M 的原型对象存在 constructor,按照上图所示, M 的 原型对象的 constructor 指向的就是 M 本身;实践看结果:
var Function_eat = function (name, age) {
this.name = name;
this.age = age;
}
Function_eat.prototype.eat = function () {
console.log('看看我这一行代码,它能让我成为最帅的人');
}
var Xiaochen = new Function_eat('小陈', 20)
Xiaochen.eat() //看看我这一行代码,它能让我成为最帅的人
//构造函数的隐式原型指向谁?
console.log(Xiaochen.__proto__ == Function_eat.prototype); //true
console.log(Function_eat.prototype.constructor == Function_eat); //true
console.log(Function_eat.prototype.__proto__ == Object.prototype); //true
//注意
console.log(Object.prototype.__proto__); //null
//扩展
console.log(Function_eat.prototype.__proto__);
console.log(Function_eat.prototype.constructor);
console.log(Xiaochen.__proto__);
关于上面推荐大家看下面一篇文章《JavaScript原生链》
从一个实例对象向上找有一个构造实例的原型对象,这个原型对象又有构造它的上一级原型对象,如此一级一级的关系链,就构成了原型链。原型链的最顶端就是Object.prototype ;
原型链最重要的作用就是继承,实例来继承上一级的属性或方法。此外,如果有多个实例,而多个实例存在共同方法,或共同属性,我们不想每一个实例都创建一份这些属性或方法,就可以将这些属性存在原型对象上,实例一样可以使用这些属性或方法;
类似于作用域链,实例在调用方法时,如果在本身没有找到,就会在原型对象上查找,如果也没有找到,就会再向上一级原型对象查找,一直找到Object.prototype ;如果中间找到会停止查找返回该方法。如果一直没找到会返回未定义;