【JS】原型和原型链

一、原型概念

  1. 任何对象都有一个原型,该对象可以使用原型上的属性
  2. 原型也是一个对象

二、如何获取对象的原型

  • 从对象的角度(隐式原型)

    对象.__proto__
    
  • 从构造函数的角度(显示原型)

    构造函数.prototype
    

    注意: 通过该方式获取的不是构造函数的原型,是构造函数实例的原型。

所有的对象都具有 __ proto__ 属性,可以获取到对象自己的原型
函数类型的对象具有 __ proto__ 属性获取自己的原型和 prototype获取实例的原型两个属性

三、对象、构造函数、原型之间的关系

1. 对象和构造函数

  1. 对象是构造函数的实例,构造函数是对象的抽象(描述)
  2. 一个对象只能对应一个构造函数,一个构造函数可以对应多个对象

2. 对象和原型

  1. 对象可以使用(继承)原型上的属性(方法)
  2. 一个对象只能有一个原型,原型可以作为多个对象的原型

3. 构造函数和原型

  1. 使用构造函数的prototype属性获取它实例的原型
  2. 构造函数相同的对象,原型也一样

在这里插入图片描述

四、自定义构造函数时原型的应用

// 定义构造函数
function User(name, age) {
  // 设置属性
  this.name = name;
  this.age = age;
}
// 将方法添加到原型上
User.prototype.getInfo = function () {
  console.log(this.name + '今年' + this.age + '岁了');
};
// 实例化 user
var u = new User('xx', 98);
u.getInfo();
// 实例化
var u1 = new User('yy', 16);
u1.getInfo()

五、判断属性是否属于对象本身

对象.hasOwnProperty('属性名')
// 自定义构造函数
function Person(name, age) {
  //设置对象的属性
  this.name = name;
  this.age = age;
}
// 给原型添加方法
// 把方法定义到原型上,可以节省内存
Person.prototype.say = function () {
  console.log(this); //谁调用了this,this就指向谁。
  console.log('我是' + this.name + ',我今年' + this.age + '岁了');
};
//实例化对象
var p1 = new Person('曹操', 18);
console.log(p1.hasOwnProperty('name')); // true 自身的属性
console.log(p1.hasOwnProperty('age')); // true 自身的属性
console.log(p1.hasOwnProperty('say')); // false 原型上的属性
console.log(p1.hasOwnProperty('constructor')); // false 原型上的属性
console.log(p1.hasOwnProperty('grade')); // false 自身和原型都没有的属性

六、原型链

1. 概念

  1. 每个对象都有原型,原型也是对象,原型也有原型,形成了原型链
  2. 原型链的终点是一个顶层原型对象 Object.prototype

在这里插入图片描述

2. 原型链的作用

  1. 当使用对象中某个属性的时候,先查看对象自身有无该属性
  2. 如果对象本身没有该属性,查找对象的原型,如果没有继续查找原型的原型
  3. 一直到顶层原型对象,如果还未查找到,自动得到undefined

3. 原型链和构造函数

  1. 每个对象都有原型,每个对象都有构造函数,对象只会从原型上继承属性

  2. Array、Object、Number等都是Function的实例,原型都是Function.prototype

    Function.prototype的构造函数是Object的,Object的原型是Function.prototype

  3. Function的构造函数是自己,所以 Function.__ proto __ ===Function.prototype

在这里插入图片描述

4. instanceof和原型链

  1. 该运算符判断一个对象是否是某个构造函数的实例
  2. 如果是对象自己的构造函数成立,如果是原型链上某个对象的构造函数也成立
[] instanceof Array; //true
[] instanceof Object; //true

5. constructor属性

对象自身所设置的constructor并不指向自己的构造函数,指向以他为原型的对象的构造函数

七、面向对象继承

1. 规则

class 父类 {}

class 子类 extends 父类 {}

2. 原型继承特点

  1. JS 对象依靠原型链实现继承
  2. 多个对象可以以同一个对象为原型; 一个对象的原型只能有一个。
  3. 同构构造函数的 prototype 可以获取到对象的原型

3. 实现JS中构造函数和构造函数之间继承

// 定义父类
function User(name, address) {
    // 属性添加到实例本身上
    this.name = name;
    this.address = address;
};
// 方法添加到实例的原型上
User.prototype.addShopCart = function(product) {
    console.log(this.name + '将' + product +  '商品加入购物车')
}

// 定义子类 普通用户
function NormalUser(name, address, adTime) {
    this.adTime = adTime;
    // 将父类上定义的属性加到 NormalUser的实例上
    User.call(this, name, address);
}
// 设置NormalUser的实例的原型是User的一个实例
NormalUser.prototype = new User();
// 给NormalUser的实例的原型添加 constructor 属性,指向 NormalUser(该行不会改变任何原型结构)
NormalUser.prototype.constructor = NormalUser;

// 添加方法
NormalUser.prototype.buyVip = function() {
    console.log('我要购买vip');
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值