原型与原型链

原型 & 原型链

  • 所有对象都是通过new 函数创建
  • 所有的函数也是对象
    • 函数可以有属性和方法
  • 所有对象都是引用类型

原型 prototype

原型: 任何一个JS对象创建时会关联的一个对象 任何根据原型的构造函数创建出来的对象,都会继承原型上的属性

  • 所有函数都有一个prototype属性
  • 默认情况下,prototype属性是一个普通的Object对象
  • 默认情况下,prototype对象有一个属性constructor,它也是一个对象,指向构造函数本身

隐式原型__proto__

  • 所有的对象都有一个__proto__属性,称为隐式原型
  • 默认情况下,隐式原型指向创建该对象的函数的原型
javascript 复制代码
function test() {}
var obj = new test();
obj.__proto__ === test.prototype // true
javascript 复制代码
function create() {
    if (Math.random() < 0.5) {
        return {}
    } else {
        return []
    }
}
var obj = create();
// 得到创建obj的构造函数名称
console.log(obj.__proto__.constructor.name)

当访问一个对象的成员时:

  1. 看该对象自身是否有该成员,如果有直接使用
  2. 在原型链中依次查找是否有该成员,如果有直接使用

原型链

原型链: 原型链是一个对象到另一个对象的链接,它是由__proto__属性连接起来的一系列对象,直到到达null(即对象查找属性的过程) 特殊点:

  1. Function的__proto__指向自身的prototype
  2. Object的prototype__proto__指向null

图解原型链

面试题

javascript 复制代码
// 面试题一
var F = function() {};
Object.prototype.a = function () {}
Function.prototype.b = function () {}
var f = new F();

console.log(f.a, f.b, F,a, F.b)
// function () {} undefined function() {} function() {}
javascript 复制代码
// 面试题二
function A() {}
function B(a) {
    this.a = a;
}
function C(a) {
    if (a) {
        this.a = a;
    }
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;

console.log(new A().a) // 1
console.log(new B().a) // undefined
console.log(new C(2).a) // 2
javascript 复制代码
// 面试题三
function User() {}
User.prototype.sayHello = function() {}

var u1 = new User();
var u2 = new User();

console.log(u1.sayHello === u2.sayHello); //true
console.log(User.prototype.constructor); //User Function
console.log(User.prototype === Function.prototype); // false
console.log(User.__proto__ === Function.prototype); // true
console.log(User.__proto__ === Function.__proto__); // true
console.log(u1.__proto__ === u2.__proto__);  // true
console.log(u1.__proto__ === User.__proto__); // false
console.log(Function.__proto__ === Object.__proto__); // true
console.log(Function.prototype.__proto__ === Object.prototype.__proto__); // false
console.log(Function.prototype.__proto__ === Object.prototype); // true

原型链的应用

基础方法

Object.getPrototypeOf(对象) 获取对象的原型 Object.prototype.isPrototypeOf(对象) 判断当前对象(this)是否在指定对象的原型链上 对象 instanceof 函数 判断函数的原型是否在对象的原型链上 Object.create(原型对象,属性对象) 创建一个对象,其隐式原型指向指定的对象 Object.prototype.hasOwnProperty(属性名) 判断一个对象自身是否拥有某个属性

应用

类数组转换为真数组

javascript 复制代码
Array.prototype.slice.call(arguments); // arguments为类数组

实现继承 默认情况下,所有构造函数的父类都是Object

javascript 复制代码
// 实现继承
function inhreit(Son, Father) {
  // 第一种方案
  // Son.prototype = Father.prototype; // 容易造成原型链污染
  // 第二种方案
  // Son.prototype = Object.create(Father.prototype); // 创建一个对象,其隐式原型指向父类的原型对象prototype
  // 第三种方案
  var F = function () {
  };
  F.prototype = Father.prototype;
  Son.prototype = new F();
  Son.prototype.constructor = Son; // 修正构造函数指向
  // Son.prototype.uper = Father; // 增加父类引用
  Son.prototype.uper = Father.prototype; // 增加父类原型对象引用
}

function User(firstName, lastName, age) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
  this.fullName = firstName + " " + lastName;
}

User.prototype.sayHello = function () {
  console.log(`大家好,我是${this.fullName},今年${this.age}岁了!`)
}

function VipUser(firstName, lastName, age, money) {
  User.call(this, firstName, lastName, age)
  this.money = money;
}

inhreit(VipUser, User)
VipUser.prototype.upgrade = function () {
  console.log(`使用${this.money}元,升级VIP会员!`)
}
const vUser = new VipUser('Tom', 'Hanks', 25, 10000)
相关推荐
东东51616 小时前
智能社区管理系统的设计与实现ssm+vue
前端·javascript·vue.js·毕业设计·毕设
catino16 小时前
图片、文件的预览
前端·javascript
2501_9209317018 小时前
React Native鸿蒙跨平台实现推箱子游戏,完成玩家移动与箱子推动,当所有箱子都被推到目标位置时,玩家获胜
javascript·react native·react.js·游戏·ecmascript·harmonyos
AI老李18 小时前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
方也_arkling19 小时前
Element Plus主题色定制
javascript·sass
2601_9498095919 小时前
flutter_for_openharmony家庭相册app实战+我的Tab实现
java·javascript·flutter
Up九五小庞19 小时前
开源埋点分析平台 ClkLog 本地部署 + Web JS 埋点测试实战--九五小庞
前端·javascript·开源
摘星编程19 小时前
React Native + OpenHarmony:UniversalLink通用链接
javascript·react native·react.js
qq_1777673720 小时前
React Native鸿蒙跨平台数据使用监控应用技术,通过setInterval每5秒更新一次数据使用情况和套餐使用情况,模拟了真实应用中的数据监控场景
开发语言·前端·javascript·react native·react.js·ecmascript·harmonyos
烬头882120 小时前
React Native鸿蒙跨平台应用实现了onCategoryPress等核心函数,用于处理用户交互和状态更新,通过计算已支出和剩余预算
前端·javascript·react native·react.js·ecmascript·交互·harmonyos