JS原型、原型链、继承、new运算符、Object.create

这篇文章可能较长,因为想要讲清楚JS原型和原型链,不得不讲讲原型和原型链产生的历史因素,他们到底是为什么而设计出来的?如果你希望对原型和原型链有比较深刻理解而不是每一次看完一篇文章下次遇到又忘了的话,请耐心一些听我细细道来。 文章中历史因素部分大多来源阮大神的博客

历史因素

JS诞生之初,是因为网景公司需要一种脚本语言,使得用户可以与网页互动。1994年当时最新发布的浏览器Navigator0.9只能用来浏览,不能用来交互,那么到底采用什么语言呢,当时网景公司有两个选择,一个是采用现有的语言,比如Perl、Python、Tcl、Scheme等等,允许它们直接嵌入网页;另一个是发明一种全新的语言。就在这时,1995年,Sun公司将Oak语言改名为Java,正式向市场推出。Sun公司大肆宣传,许诺这种语言可以"一次编写,到处运行"(Write Once, Run Anywhere),它看上去很可能成为未来的主宰。

网景公司决定与SUN公司结盟,它不仅允许Java程序以applet(小程序)的形式,直接在浏览器中运行;甚至还考虑直接将Java作为脚本语言嵌入网页,只是因为这样会使HTML网页过于复杂,后来才不得不放弃。

总之,当时的形势就是,网景公司的整个管理层,都是Java语言的信徒,Sun公司完全介入网页脚本语言的决策。因此,Javascript后来就是网景和Sun两家公司一起携手推向市场的,这种语言被命名为"Java+script"并不是偶然的。

此时,34岁的系统程序员Brendan Eich登场了。1995年4月,网景公司录用了他。

Brendan Eich的主要方向和兴趣是函数式编程,网景公司招聘他的目的,是研究将Scheme语言作为网页脚本语言的可能性。Brendan Eich本人也是这样想的,以为进入新公司后,会主要与Scheme语言打交道。

仅仅一个月之后,1995年5月,网景公司做出决策,未来的网页脚本语言必须"看上去与Java足够相似",但是比Java简单,使得非专业的网页作者也能很快上手。这个决策实际上将Perl、Python、Tcl、Scheme等非面向对象编程的语言都排除在外了。

Brendan Eich被指定为这种"简化版Java语言"的设计师。

总的来说,他的设计思路是这样的:

(1)借鉴C语言的基本语法;
(2)借鉴Java语言的数据类型和内存管理;
(3)借鉴Scheme语言,将函数提升到"第一等公民"(first class)的地位;
(4)借鉴Self语言,使用基于原型(prototype)的继承机制。

所以,Javascript语言实际上是两种语言风格的混合产物----(简化的)函数式编程+(简化的)面向对象编程。这是由Brendan Eich(函数式编程)与网景公司(面向对象编程)共同决定的。

Javascript继承机制的设计思想

一、面向对象思想

当时C++是最流行的语言,而Java刚刚诞生,他们都是面向对象编程(OOP)语言,熟知面向对象的人都知道,面向对象的三个基本特征:封装、继承、多态。Brendan Eich无疑受到了影响,Javascript里面所有的所有数据类型都是对象,或者说能当作对象使用更为准确(除了null和undefinded),这一点与Java非常相似。但是,他随即就遇到了一个难题,到底要不要设计"继承"机制呢?

如果真的是一种简易的脚本语言,其实不需要有"继承"机制。但是,Javascript里面都是对象,必须有一种机制,将所有对象联系起来。所以,Brendan Eich最后还是设计了"继承"。

但是,他不打算引入"类"(class)的概念,因为一旦有了"类",Javascript就是一种完整的面向对象编程语言了,这好像有点太正式了,而且增加了初学者的入门难度。

他考虑到,C++和Java语言都使用new命令,生成实例。
C++:

CTest*  pTest = new  CTest();

Java

Foo foo = new Foo();

于是,他就把new命令引入Javascript,用来从原型对象,生成一个实例对象,但是Javascript没有“类”,怎么来表示原型对象呢,他想到C++和Java调用new命令时,都会调用“类”的构造函数(constructor),于是Javascript中就作了一个简化设计,new后面跟的不是类,而是构造函数,举例说:

function Person(name) {
   
  this.name = name;   // 这就是javascript中的构造函数,
}

所以直接对这个构造函数使用new,就会生成一个人对象的实例

var p1 = new Person('张三');
console.log(p1.name); // 张三

注意构造函数中的this关键字,它就代表了新创建的实例对象。

但是,用构造函数生成实例对象,有一个缺点,那就是无法共享属性和方法。

比如,在Girl对象的构造函数中,设置一个实例对象的共有属性gender。

function Girl(name) {
   
  this.name = name   // 这就是javascript中的构造函数,
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值