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...

相关推荐
开心工作室_kaic10 分钟前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿29 分钟前
webWorker基本用法
前端·javascript·vue.js
cy玩具1 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
清灵xmf1 小时前
TypeScript 类型进阶指南
javascript·typescript·泛型·t·infer
小白学大数据1 小时前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
qq_390161772 小时前
防抖函数--应用场景及示例
前端·javascript
334554322 小时前
element动态表头合并表格
开发语言·javascript·ecmascript
John.liu_Test2 小时前
js下载excel示例demo
前端·javascript·excel
Yaml42 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事2 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro