原型链
在讲解原型链之前我们先来看看在你创建对象时发生了什么,接下来我们试着分析一下,下面的这段代码到底做了什么事。
new Date();
这段代码干的事情如下
1、创建了一个新的对象
2、将这个对象接入原型链
3、绑定this
4、返回这个对象
ok,我们开始解释原型链。。。那么什么是原型链呢。
我们都知道每个对象都有自己的 [[proto]]属性,这个proto指向该对象的构造函数的原型对象例如
var date = new Date()
console.log(date.__proto__ == Date.prototype) // true
关键的来了,原型对象也是一个对象所以它也有[[proto]]属性,那么它的proto属性会指向Object.prototype
console.log(Date.prototype.__proto__ == Object.prototype) // true
当你访问date上没有的属性或方法时,date本身可能没有该属性或方法,那么会去到它的原型对象上去找,也没有的话回去原型的原型上去找直到查找到Object.prototype.proto = null(由于编辑器原因所以没写下划线)为止。这就是原型链。
继承
讲完原型我们来看看js如何实现继承,
第一种:对象冒充,缺点:无法继承原型上的属性
function Parent(params){
this.name = params||'父亲';
this.run = function run(){
console.log(`${
this.name}:在跑`)
}
}
Parent.prototype.eat = function(){
console.log('吃饭');
}
function Child(){
Parent.call(this,"儿子")
}
var child =new Child();
child.run()
child.eat()
第二种:原型继承,传递参数比较困难,无法通过子对象的属性改变父对象的属性
function Parent(params){
this.name = params||'父亲';
this.run = function run(){
console.log(`${
this.name}:在跑`)
}
}
Parent.prototype.eat = function(){
console.log('吃饭');
}
function Child(){
this.age = 20;
}
Child.prototype = new Parent;
var child = new Child();
child.run()
child.eat()
第三种:对象冒充+原型继承 推荐结合了前两种弥补了前两种的缺陷
function Parent(params){
this.name = params||'父亲';
this.run = function run(){
console.log(`${
this.name}:在跑`)
}
}
Parent.prototype.eat = function(){
console.log('吃饭');
}
function Child(){
this.age = 20;
Parent.call(this,'儿子');
}
Child.prototype = new Parent;
var child = new Child();
child.run()
child.eat()
我们再看看es6的继承,本质上还是上面的继承,不过是语法糖而已
class Parent{
constructor(name){
this.name = name
console.log('父亲:'+this.name);
}
}
class Child extends Parent{
constructor(name,age){
super(name);
this.age = age;
console.log('儿子:'+this.age);
}
}
var child = new Child('zs',20)
到此原型链及继承基本就掌握了,接下来是干货了
面试题:1、解释一下什么是原型链
2、es5继承如何实现
ok,原型链就记录到此,如果觉得我写的不对或者不理解可以私信或评论。如果觉得我记录的原型链有帮你理解到的话,请点个赞,蟹蟹。