JavaScript-原型与继承(一)原型基础


前言

这篇文章是关于原型的基础知识篇章


原型对象

每个对象都有一个原型 prototype 对象, 通过函数创建的对象也拥有这个原型对象,原型是一个指向对象的指针。

  • 可以将原型理解为对象的父亲。对象从原型对象上继承属性
  • 原型就是对象,除了是某个对象的父母外没有什么特别的地方
  • 所有函数的原型是 Object 的实例
  • 使用原型对象为多个对象共享属性或方法
  • 如果对象本身不存在属性或方法将到原型上面去查找
  • 使用原型可以解决通过构建函数创建对象时复制多个函数造成的内存占用问题
  • 原型包含 constructor 属性 指向构造函数
  • 对象包含 __proto__ 指向他的原型对象

eg: 1.使用数组原型对象上的contact方法完成链接操作

const list = ['name'];
console.log(list.contact('sex'));
console.log(list)

2.默认情况下创建的对象都有原型
默认创建的对象都有原型
3.以下user对象和food对象的原型是一样的

let user= {};
let food = {};
console.log(Object.getPrototypeOf(user) == Object.getPrototypeOf(food)); //true

4.可以创建没有原型的对象

const user = {name:'LL'};
console.log(user.hasOwnProperty('name'));
const food = Object.creat(null,{name:'RR'}) ;
console.log(food.hasOwnProperty(name));//Error

5.对象方法的优先级大于原型方法的优先级

const user = {
	show(){console.log('user.show')}
};
user.__proto__.show = function(){console.log('user.__proto__.show')};
user.show();//user.show

6.函数拥有多个原型 prototype 用于实例对象使用 ,__proto__ 用于函数对象使用

function User(){}
User.__proto__.show = function(){console.log('user.__proto__.show')}; 
User.prototype.show = function(){console.log('user.prototype.show')};
const user = new User();
user.show();//user.prototype.show
User.show();//user.__proto__.show
console.log(User.prototype == user.__proto__);//true

Object.prototype.view = function() {
  console.log(Object view method");
};
console.log(User.prototype.__proto__ == User.__proto__.__proto__);//true
console.log(User.prototype.__proto__ == Object.prototype);//true

通过上面的案例可以整理出原型关系如下所示
原型链
7.使用构造函数创建对象的原型分析

  • 构造函数拥有原型
  • 创建对象时构造函数吧原型赋值给对象
function User() {}
let t = new User();
console.log(t.__proto__ == User.prototype);

构造函数创建对象
8.constructor 存在于 prototype 原型中,用于指向构建函数的引用

function T() {
  this.show = function() {
    return "show method";
  };
}
const o = new T(); 
console.log(o instanceof T);//true

const o2 = new o.constructor();
console.log(o2.show()); //show method

9.使用对象的 constructor 创建对象

function User(name, age) {
  this.name = name;
  this.age = age;
}

function createByObject(obj, ...args) {
  const constructor = Object.getPrototypeOf(obj).constructor;
  return new constructor(...args);
}

let xb = new User("xb");
let ami = createByObject(xb, "艾米", 12);
console.log(ami);

原型链

通过引用类型的原型,继承另一个引用类型的属性与方法,这就是实现继承的步骤
原型链
Object.setPrototypeOf 用于置对象的原型
Object.getPrototypeOf 用于获取一个对象的原型

const eh = { name: 'eh' };
const dog = { move: 'move' };
const animal = { food: 'food' };
Object.setPrototypeOf(eh, dog);
Object.setPrototypeOf(dog, animal);
console.log(eh.move);
console.log(Object.getPrototypeOf(dog) == animal);

原型检测

instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上

function A() {}
function B() {}
function C() {}

const c = new C();
B.prototype = c;
const b = new B();
A.prototype = b;
const a = new A();
console.log(a instanceof A); //true
console.log(a instanceof B); //true
console.log(a instanceof C); //true
console.log(b instanceof C); //true
console.log(c instanceof B); //false

原型检测
使用isPrototypeOf检测一个对象是否是另一个对象的原型链中

const a = {};
const b = {};
const c = {};

Object.setPrototypeOf(a, b);
Object.setPrototypeOf(b, c);

console.log(b.isPrototypeOf(a)); //true
console.log(c.isPrototypeOf(a)); //true
console.log(c.isPrototypeOf(b)); //true

属性遍历

使用in检测原型链上是否存在属性,使用 hasOwnProperty 只检测当前对象

let user= { name: "xb" };
let sex = { type: "n" };
Object.setPrototypeOf(sex, user);
console.log("type" in a);
console.log(user.hasOwnProperty("name"));
console.log(user.hasOwnProperty("type"));

使用 for/in 遍历时同时会遍历原型上的属性

let user = { name: "xb" };
let t = Object.create(user, {
  url: {
    value: "csdn",
    enumerable: true
  }
});
for (const key in t) {
  console.log(key);
}

借用原型

使用 callapply 可以借用其他原型方法完成功能

let list = {
  data: [1, 2, 3, 4, 5]
};
console.log(Math.max.apply(null, Object.values(list.data)));

let list2 = {
  lessons: { js: 100, php: 78, node: 78, linux: 125 }
};
console.log(Math.max.apply(null, Object.values(list2.lessons)));

this

this 不受原型继承影响,this 指向调用属性时使用的对象

let user = {
  name: "xb"
};
let car= {
  name: "bmi",
  show() {
    return this.name;
  }
};
user.__proto__ = car;
console.log(user.show()); //xb
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值