JavaScript 基础系列之对象原型

什么是对象原型

JavaScript 中所有的对象都有一个内置属性,称为它的 prototype (原型)。它本身是一个对象,故原型对象也会有它自己的原型,逐渐构成了原型链 。原型链终止于拥有 null 作为其原型的对象上。

准确地说,这些属性和方法定义在Object的构造器函数(constructor functions)之上的prototype属性上,而非对象实例本身。

因此可以看出它的优点: 所有对象实例可以共享它包含的属性和方法

看下面例子

javascript 复制代码
function Person() {}
console.log(Person.prototype) // {constructor: ƒ}
Person.prototype.name = '张三'
Person.prototype.age = 18
Person.prototype.getName = function () {
    console.log('name:' + this.name)
}
var p1 = new Person()
p1.getName() // name:张三
var p2 = new Person()
p2.getName() // name:张三

console.log(p1.getName == p2.getName) // true
console.log(p1.name === p2.name) // true
console.log(Person.prototype.constructor) // ƒ Person() {}
console.log(Person.prototype.constructor.prototype) // {name: "张三", age: 18, getName: ƒ, constructor: ƒ}
console.log(p1.prototype) // undefind
console.log(p1.constructor) // ƒ Person() {}
console.log(p1) // Person {}

由上可得:

Person 有个默认的属性prototype函数可以有属性。每个函数都有一个特殊的属性叫作原型(prototype)

p1和p2访问的都是同一个getName()函数,即他们的属性和方法都是共享的

默认情况下所有的函数都有一个constructor(构造函数)属性 。该属性指向了prototype属性所在函数。如:Person.prototype.constructor 指向的是 Person。

打印 p1:

p1有个__proto__ 属性,该属性内还有:Person的实例、constructor、__proto__。以此提供了一个原型链。

prototype 属性:继承成员被定义的地方

prototype 属性的值是一个对象,我们希望被原型链下游的对象继承的属性和方法,都被储存在其中。

Object.prototype.watch()、``Object.prototype.valueOf() 等等成员,适用于任何继承自 Object() 的对象类型,包括使用构造器创建的新的对象实例。

Object.is()Object.keys(),以及其他不在 prototype 对象内的成员,不会被"对象实例"或"继承自 Object() 的对象类型"所继承。这些方法/属性仅能被 Object() 构造器自身使用

yaml 复制代码
console.log(Person.prototype) // {name: "张三", age: 18, getName: ƒ, constructor: ƒ}
console.log(Object.prototype) //{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, ...}

prototype 属性包含(指向)一个对象,你在这个对象中定义需要被继承的属性和方法。

create()

create() 实际做的是从指定原型对象创建一个新的对象。

javascript 复制代码
 function Person(name, age) {
    this.name = name
    this.age = age 
    this.getName = function () {
      console.log('name:' + this.name)
    }
  }
  var p1 = new Person('张三', 18)

  var p3 = Object.create(p1)
  console.log(p3) 
constructor

每个实例对象都从原型中继承了一个constructor属性,该属性指向了用于构造此实例对象的构造函数

arduino 复制代码
// 获得对象实例的构造器的名字
console.log(p1.constructor.name) // Person

修改原型

Person构造器的 prototype 属性添加一个新的方法。

javascript 复制代码
function Person(name, age, sex) {
    this.name = name
    this.age = age
    this.sex = sex
    this.getName = function () {
      console.log('name:' + this.name)
    }
}
var p1 = new Person('张三', 18, '男')

Person.prototype.getSex = function() {
    console.log('sex:' + this.sex);
}
p1.getSex() // sex:男

getSex 方法虽在 p1 实例后定义,但p1也可使用。旧有对象实例的可用功能被自动更新了

这种继承模型下,上游对象的方法不会复制到下游的对象实例中;下游对象本身虽然没有定义这些方法,但浏览器会通过上溯原型链、从上游对象中找到它们。这种继承模型提供了一个强大而可扩展的功能系统。

一种极其常见的对象定义模式是,在构造器(函数体)中定义属性、在 prototype 属性上定义方法。如此,构造器只包含属性定义,而方法则分装在不同的代码块,代码更具可读性。

javascript 复制代码
// 构造器及其属性定义
function Test(a,b,c,d) {
  // 属性定义
};

// 定义第一个方法
Test.prototype.x = function () { ... }

// 定义第二个方法
Test.prototype.y = function () { ... }

继承

例子

javascript 复制代码
function Person(name, age, sex) {
    this.name = name
    this.age = age
    this.sex = sex
    this.getName = function () {
      console.log('name:' + this.name)
    }
}
构造函数继承
csharp 复制代码
var p1 = new Person('张三', 18, 'nan')
p1.getName()
原型式继承

继承的对象函数并不是通过复制而来,而是通过原型链继承(通常被称为 原型式继承 ------ prototypal inheritance)

javascript 复制代码
function Person(name, age, sex) {
    this.name = name
    this.age = age
    this.sex = sex
    this.getName = function () {
      console.log('name:' + this.name)
    }
}

Person.prototype.getSex = function() {
    console.log('sex:' + this.sex);
}

如果一个新的函数要继承上来构造函数的属性和方法,还有增加新的属性和方法:

javascript 复制代码
function Teacher(name, age, sex, profession) {
  Person.call(this, name, age, sex);

  this.profession = profession;
}
var t1 = new Teacher('王二', 30, '男', '老师')
console.log(t1) // Teacher {name: "王二", age: 30, sex: "男", profession: "老师", getName: ƒ}

参考文章:blog.csdn.net/flyingpig20...

相关推荐
多则惑少则明24 分钟前
Vue开发系列——自定义组件开发
前端·javascript·vue.js
用户2506949216131 分钟前
next框架打包.next文件夹部署
前端
程序猿小蒜34 分钟前
基于springboot的校园社团信息管理系统开发与设计
java·前端·spring boot·后端·spring
一叶难遮天34 分钟前
开启RN之旅——前端基础
前端·javascript·promise·js基础·es6/ts·npm/nrm
申阳35 分钟前
Day 4:02. 基于Nuxt开发博客项目-整合 Inspira UI
前端·后端·程序员
程序猿_极客39 分钟前
【期末网页设计作业】HTML+CSS+JavaScript 猫咪主题网站开发(附源码与效果演示)
前端·css·html·课程设计·网页设计作业
IT古董39 分钟前
【前端】从零开始搭建现代前端框架:React 19、Vite、Tailwind CSS、ShadCN UI 完整实战教程-第1章:项目概述与技术栈介绍
前端·react.js·前端框架
有点笨的蛋41 分钟前
从零搭建小程序首页:新手也能看懂的结构解析与实战指南
前端·微信小程序
爱宇阳41 分钟前
Vue3 前端项目 Docker 容器化部署教程
前端·docker·容器
Irene199142 分钟前
前端缓存技术和使用场景
前端·缓存