javascript-prototype

1 前言

javascript 是具有基于原型链的面向对象编程语言

oop != class

oop 也不需要基于class

请先抛弃class关键词

2 在javascript中,对象来自于对象Object comes from Object。你可以使用对象来直接构造一个对象

example #1

1
2
3
4
5
6
var food = {
eat:"i eat !"
}

var meal = Object.create(food)
console.log(meal.eat) // "i eat"

现在我来解释下这里发生了什么,首先Object.create(source)方法创建了一个新的空对象,然后将新对象的原型设置为source即你传入对象。

2.1 首先来验证下meal确实是空对象

console.log(meal) // {}

2.2 然后我们来验证meal的原型确实是food

meal.__proto__ === food //true

2.3 你可能会问:等等!__proto__是什么??? 为什么meal.eat 输出了内容???

2.3.1 先回答第一个问题:__proto__是什么?

在javascript中所有的对象中都有一个内置属性__proto__,指向它的原型对象。
在这个例子中meal的原型对象就是food
所有对象的原型指向形成了链式结构,这就是原型链,而原型链的顶端就是Object.prototype

meal.__proto ->food food.__proto->Object.prototype

Object.prototype的原型是null

Object.prototype.__proto__ -> null

知道这个原理之后我们就可以来模拟一下Object.create()

example#2

1
2
3
4
5
6
7
8
9
10
11
function ourNew(source){
var obj = {}
obj.__proto__ = source
return obj
}
var food = {
eat:"i eat"
}

var meal = ourNew(food)
console.log(meal.eat)//"i eat"

太棒了,我们模拟了一个对象的继承

2.3.2 再回答第二个问题:为什么meal.eat 输出了内容

js中对象属性的查找机制,是从对象本身开始查找,如果查找不到,则顺着原型链继续向上查找,直到找到对应属性后返回,否则返回undefined

meal.__proto__.__proto__...

当原型链中存在相同属性时候,最先找到的会被返回,而上层的同名属性会被屏蔽

example #3

1
2
3
4
5
6
7
8
9
var food = {
eat:"i eat !"
}

var meal = Object.create(food)
console.log(meal.eat)//"i eat"
meal.eat = "i don't eat"
console.log(meal.eat)//"i don't eat"
console.log(meal.__proto__.eat)//"i eat" oops! food的eat属性被meal屏蔽了

3 构造函数 new 关键词

在js中我们还可以通过一类特殊的对象 — 函数 来构建对象,也就是我们经常说的构造函数。
任何函数只要前面加上关键词new就会被当作是构造函数

example #4

1
2
3
4
5
6
7
function Point(x,y){
this.x = x
this.y = y
}

var point = new Point(1,2)
console.log(point)//{x:1,y:2}

这其中发生了什么呢?

1 首先一个对象被创建,对象的_proto_Point.prototype即构造函数.prototype

2 将this绑定到这个对象,用参数构造这个对象,即 新创建对象的x 变为传入参数 x,新创建对象的y 变为传入参数的 y

3 如果构造函数没有显式返回一个对象,则返回新创建的对象

example #5

1
2
3
4
5
6
7
8
function Point(x,y){
this.x = x
this.y = y
return {x:100,y:100}//显式返回对象 覆盖新建立的对象
}

var point = new Point(1,2)
console.log(point)//{x:100,y:100}

所以在js中对象直接来自对象,不管你是用object.create() 还是 new function()来创建