Js进阶11. 原型,原型链和继承

一、原型

在js中,每当定义一个函数数据类型(Object、Function、Arrry、Date等)的时候都会自带一个 prototype 对象,这个对象就是原型

每个对象都有一个 __proto__ 属性,指向创建该对象的函数的 prototype。 

function Person(){
  this.showNam e= function () {
    console.log("zhangsan");
  };
}
let person1 = new Person();
let person2 = new Person();
console.log(person1.showName === person2.showName); // false

很容易就知道输出的是 false,因为两个实例对象指向的不是同一个地方。

那再看下面这个例子:

function Person(name){
  this.name = name;
}
Person.prototype.showName = function () {
  console.log(this.name);
};
let person1 = new Person("zhangsan");
let person2 = new Person("lisi");
console.log(person1.showName === person2.showName) // true

这样输出的结果就是 true 了,因为两个实例对象共享同一个方法。所以就能知道原型的作用就是实现数据的共享

二、原型链

访问一个对象的属性时,先在基本属性中查找,如果没有,再沿着 __proto__这条链向上找,这就是原型链

简单来说就是原型与原型之间层层链式连接的过程称为原型链,原型链是通过 __proto__ 链接起来的,所以为什么实例对象可以使用构造函数的 prototype 原型上的属性和方法,就是因为实例对象有 __proto__ 的存在,例子:

function Person() {}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true

最终输出的就是 true。

三、基于原型链的查找方式 

function Person(){
  this.name = "zhangsan";
}
Person.prototype.name = "lisi";
Object.prototype.name = "wangwu";
let person1=new Person();
console.log(person1.name); // "zhangsan"

(1) 首先 person1 对象会在本身查找,看自己有没有 name 属性,如果有则查找结束;

(2) 如果本身没有就会沿着原型链原型上找,找到了就结束;

(3) 如果原型链上还是没有,就会去 Object 原型对象上去查找;

(4) 如果还没有则会报错。

四、继承

由于所有对象的原型链都会找到 Object.prototype,因此所有对象都会有 Object.prototype 的方法。这就是继承。

function People(name) {
  //属性
  this.name  = name || 'akl';
  //实例方法
  this.sleep = function() {
    console.log(this.name + '正在睡觉');
  };
}
//原型方法
People.prototype.eat = function (food) {
  console.log(this.name + '正在吃:' + food);
};

1.  原型链继承

父类的实例作为子类的原型:
 

function Woman(){ 
}
Woman.prototype = new People();
Woman.prototype.name = 'akl';
let womanObj = new Woman();

优点:简单易于实现;父类新增的实例与属性子类都能访问。

缺点:可以在子类中增加实例属性,如果要新增加原型属性和方法需要在 new 父类构造函数的后面;无法实现多继承;创建子类实例时,不能向父类构造函数中传参数。

2. 借用构造函数继承(伪造对象,经典继承)

复制父类的实例属性给子类: 

function Woman(name) {
  // 继承了People
  People.call(this); // People.call(this,'akl'); 
  this.name = name || 'renbo';
}
let womanObj = new Woman();

优点:解决了子类构造函数向父类构造函数中传递参数;可以实现多继承(call 或者 apply 多个父类)。

缺点:方法都在构造函数中定义,无法复用;不能继承原型属性/方法,只能继承父类的实例属性和方法

3. 实例继承(原型式继承)

function Woman(name) {
  let instance = new People();
  instance.name = name || 'akl';
  return instance;
}
let womanObj = new Woman();

优点:不限制调用方式;简单,易实现;

缺点:不能多继承。

4. 组合式继承

调用父类构造函数,继承父类的属性,通过将父类实例作为子类原型,实现函数复用。

function People(name, age) {
  this.name = name || 'akl';
  this.age = age || 27;
}
People.prototype.eat = function(){
  return this.name + this.age + 'eat sleep';
};

function Woman(name, age){
  People.call(this, name, age);
}
Woman.prototype = new People();
Woman.prototype.constructor = Woman;
let wonmanObj = new Woman("ren", 27);
console.log(wonmanObj.eat()); // ren27eat sleep

优点:函数可以复用;不存在引用属性问题;可以继承属性和方法,并且可以继承原型的属性和方法;

缺点:由于调用了两次父类,所以产生了两份实例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我来回答你的问题。以下是一些JS原型继承原型链的面试题及其答案: 1. 什么是原型继承? 答:原型继承是通过将一个对象的原型作为另一个对象的原型来实现继承。在JS中,每个对象都有一个原型,它可以通过__proto__属性来访问。 2. 什么是原型链? 答:原型链是一种通过原型继承来实现对象间继承关系的机制。当我们访问一个对象的属性时,JS会首先在该对象自身查找,如果没有找到,就会在它的原型对象上查找,如果还没有找到,就会在原型对象的原型对象上查找,一直到Object.prototype对象为止,这个查找的过程就是原型链。 3. 如何实现一个简单的原型继承? 答: ```javascript function Person(name) { this.name = name; } Person.prototype.sayHi = function() { console.log('Hi, my name is ' + this.name); } function Student(name, grade) { Person.call(this, name); this.grade = grade; } Student.prototype = Object.create(Person.prototype); Student.prototype.constructor = Student; Student.prototype.sayGrade = function() { console.log('My grade is ' + this.grade); } var tom = new Student('Tom', 3); tom.sayHi(); tom.sayGrade(); ``` 4. 如何判断一个对象是否是另一个对象的实例? 答:可以使用instanceof运算符来判断,例如: ```javascript var obj = {}; console.log(obj instanceof Object); // true ``` 5. 如何判断一个属性是在对象自身定义的还是继承原型? 答:可以使用JS提供的hasOwnProperty方法来判断,例如: ```javascript var obj = {}; console.log(obj.hasOwnProperty('toString')); // false console.log(Object.prototype.hasOwnProperty('toString')); // true ``` 希望这些问题和答案能够帮助你更好地理解JS原型继承原型链。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晴雪月乔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值