Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript 原型与原型链 #3

Open
cxk0222 opened this issue Jul 4, 2020 · 0 comments
Open

JavaScript 原型与原型链 #3

cxk0222 opened this issue Jul 4, 2020 · 0 comments

Comments

@cxk0222
Copy link
Owner

cxk0222 commented Jul 4, 2020

1. 为什么要有原型

先看下面一段代码:

var person1 = { name: 'Allen' }
person1.hello = () => { console.log(`Hello, ${this.name}`) }

var person2 = { name: 'Bill' }
person1.hello = () => { console.log(`Hello, ${this.name}`) }

var person3 = { name: 'Selby' }
person1.hello = () => { console.log(`Hello, ${this.name}`) }

我们想要创建 3 个对象,分别都有 hello 这个方法,最原始的方法就是给每一个对象分别添加一个 hello 方法。但是这样显然不符合 DRY 原则,那么在 JavaScript 中有没有方法解决这个问题呢,答案是肯定的,那就是原型系统!我们用原型系统重写上述代码:

var Person= function(name) {
  this.name = name
}

Person.prototype.hello = function() {
  console.log(`Hello, ${this.name}`)
}

var p1 = new Person('Allen')
p1.hello() // 'Hello Allen'

var p2 = new Person('Bill')
p2.hello() // 'Hello Bill'

var p3 = new Person('Selby')
p3.hello() // 'Hello Selby'

2. 什么是原型

原型其实就是一个对象,JavaScript 解释器在初始化的时候就会开辟一些内存,专门存储原型对象。看如下代码:

var obj = {}
obj.toString() // "[object Object]"

obj 自身没有 toString 这个方法,那么 toString 方法是从哪里来的?其实就是从原型对象拿来的,我们可以通过 __proto__ 这个特殊的属性访问对象的原型对象。JavaScript 的原型系统非常简单,一句话就是:在访问一个对象的 属性/方法 的时候,先在自身找,没有的话就向原型对象上找,一直找到 window.Object.prototype。注意:实例对象可以通过 __proto__ 这个属性访问其原型对象,它等于其构造函数的 prototype 属性。

function Person(name) {
  this.name = name
}

var person = new Person('Yuriuh')

person.__proto__ === Person.prototype // true

Person.__proto__ === window.Function.prototype

3. 原型链的数据结构

原型链是一个树形的结构,下面列举一些常见的原型对象,并通过树形结构表示它们的层级:

  • null
    • window.Object.prototype
      • window.Function.prototype
      • window.Array.prototype
      • window.Number.prototype
      • window.String.prototype
      • window.Boolean.prototype
      • window.Date.prototype
      • window.Symbol.prototype
      • ...

我们可以用如下代码证明:

var obj = {}

obj.__proto__ === window.Object.prototype // true

obj.__proto__.__proto__ === null // true

var fn = () => {}

fn.__proto__ === window.Function.prototype // true

fn.__proto__.__proto__ === window.Object.prototype // true

var arr = []

arr.__proto__ === window.Array.prototype

var str = ''

str.__proto__ === window.String.prototype

var bool = true

bool.__proto__ === window.Boolean.prototype

var num = 2

num.__proto__ === window.Number.prototype

var date = new Date()

date.__proto__ === window.Date.prototype

var reg = /reg/

reg.__proto__ === window.RegExp.prototype

var symbol = Symbol()

symbol.__proto__ === window.Symbol.prototype
@cxk0222 cxk0222 changed the title JavaScript 原型链 JavaScript 原型与原型链 Jul 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant