前端开发面试之prototype的本质

javascript 前端模块化开发|web前端开发工程师自学

有人说,感觉原型链跟数据结构中的链表很类似。

那么就先说说链表是啥东西?
说存储一批有逻辑顺序的数据,
可以开辟一段连续的物理空间来存储,
比如用数组(我们假设js中数组连续物理地址的,具体是不是这样我也不清楚)。

var arr = [‘A’, ‘B’, ‘C’, ‘D’];
除了顺序结构,还有一种链式结构。每个节点都保存了下一个节点物理地址的引用。
用程序来刻画就是:
[quote]a = {
value: ‘A’,
next: b
};
b = {
value: ‘B’,
next: c
};
c = {
value: ‘C’,
next: d
};
d = {
value: ‘D’,
next: null
};[/quote]
其中a是链表的表头,d是表尾,
也就是说给我表头a,我就能找到所有的节点。
比如我想查找有没有值为D的元素,可以写个contain方法
javascript 代码

var d = {
value: “D”,
next: null
};
var c = {
value: “C”,
next: d
};
var b = {
value: “B”,
next: c
};
var a = {
value: “A”,
next: b
};
var contain = function(link, value) {
while (link!=null) {
if (link.value ==value) {
returntrue;
}
link=link.next;
}
returnfalse;
};
console.log(contain(a, “D”));
console.log(contain(a, “F”));

上面是链表的查找过程,那么原型链查找过程是什么样的呢?
javascript 代码

var d = {
d: “D”
};
var c = {
c: “C”,
__proto__: d
};
var b = {
b: “B”,
__proto__: c
};
var a = {
a: “A”,
__proto__: b
};
console.log(a.d);
console.log(a.f);

与链表的查找方式类似,原型链查找的属性名称,链表查找的是值。
其中proto即原型,es6中不推荐使用的标准属性。
读写原型可以使用如下的方式:
javascript 代码

var o = {};
var proto = { name: “xxx” };
Object.setPrototypeOf(o, proto);
console.log(o.name);
var p = Object.getPrototypeOf(o);
console.log(p);

不过正好看出,对象与原型的关系,
就是天生的“有一个”关系(委托),
而不是“是一个”关系(继承)。
对应设计模式的设计原则,那正是合成复用原则。
复用,有两种方式,一个是继承、一个是委托。
所以我们把原型当成智囊,而不当成亲爹。

上面的链表是写成4个对象的,如果用一个对象来表示的话:
javascript 代码

var a = {
value: “A”,
next: {
value: “B”,
next: {
value: “C”,
next: {
value: “D”,
next: null
}
}
}
};
var contain = function(link, value) {
while (link!=null) {
if (link.value ==value) {
returntrue;
}
link=link.next;
}
returnfalse;
};
console.log(contain(a, “D”));
console.log(contain(a, “F”));

同样的如果把原型链的例子也改成一个对象的话:
javascript 代码

var a = {
a: “A”,
__proto__: {
b: “B”,
__proto__: {
c: “C”,
__proto__: {
d: “D”
}
}
}
};
console.log(a.d);
console.log(a.f);

ok,应该明白了,原型链就是这么回事:
对象都有原型,但原型本身也是个对象,因此原型也有原型。

前端开发 技术|用于web前端开发技术

» 本文来自:前端开发者 » 《前端开发面试之prototype的本质》
» 本文链接地址:https://www.rokub.com/3509.html
» 您也可以订阅本站:https://www.rokub.com
赞(0)
64K

评论 抢沙发

评论前必须登录!