JavaScript的历史
一、JavaScript的诞生
1994年,网景公司(Netscape)发布了Navigator浏览器0.9版。这是历史上第一个比较成熟的网络浏览器
特点:只能用来浏览,不具备与访问者互动的能力,一切都需要服务器端进行判断
需求:需要一种网页脚本语言,使得浏览器可以与网页互动
时代:1.1994年正是面向对象编程最兴盛的时期,Brendan Eich受到影响,使JavaScript里面所有的数据类型都是对象,同时他考虑是否要设计“继承”机制
2.1995年Sun公司将Oak语言改名为Java,正式向市场推出,并大肆宣传,看上去很可能成为未来的主宰;网景公司动心,决定与Sun公司结盟,当时的形势就是,网景公司的整个管理层,都是Java语言的信徒,Sun公司完全介入网页脚本语言的决策。因此,Javascript后来就是网景和Sun两家公司一起携手推向市场的,这种语言被命名为"Java+script"并不是偶然的。
3.1995年5月,网景公司做出决策,未来的网页脚本语言必须"看上去与Java足够相似",但是比Java简单,使得非专业的网页作者也能很快上手。Brendan Eich被指定为这种"简化版Java语言"的设计师。
二、Brendan Eich的选择
考虑到JavaScript里面都是对象,必须有一种机制,将所有对象联系起来,所以,他最后还是设计了“继承”。
为了减少初学者入门难读,他并未引入“类”的概念。
考虑到C++和Java语言都是用new命令,生成实例,于是他就把new命令引入了JavaScript,用来从原型对象生成一个实例对象。
ClassName *object = new ClassName(param);
// C++
Foo foo = new Foo();
// Java
但是,JavaScript并没有“类”,如何表示原型对象呢?
此时,他想到C++和Java使用new命令时,都会调用“类”的构造函数,因此他做了一个简化的设计,在JavaScript语言中,new命令后面跟的不是类,而是构造函数。
function DOG(name) { // DOG构造函数,表示狗对象的原型
this.name = name;
}
var dogA = new DOG('大毛'); // new 构造函数,生成一个狗对象的实例
alert(dogA.name); // 大毛
三、new运算符的缺点
用构造函数生成实例对象,有一个缺点:无法共享属性和方法。
function DOG(name) {
this.name = name; this.species = '犬科';
}
var dogA = new DOG('大毛');
var dogB = new DOG('二毛');
dogA.species = '猫科';
alert(dogB.species); // 犬科
我们在DOG对象的构造函数中设置了共有属性species,当修改实例对象中的一个,另一个并不会受到影响,每一个实例对象都有着自己的属性和方法的副本。
这样就无法做到数据共享,造成了资源的浪费。
❣构造函数中的this代表了新创建的实例对象
四、prototype属性的引入
因此,Brendan Eich决定为构造函数设置一个prototype属性。
这个属性包含一个对象,所有实例对象需要共享的属性和方法,都放在这个对象里面,而不需要共享的属性和方法,就放在构造函数里面。
实例对象一旦创建,将自动引用prototype对象的属性和方法,即,实例对象的属性和方法分为两种:本地+引用
function DOG(name) {
this.name = name;
}
DOG.prototype = { species:'犬科' };
var dogA = new DOG('大毛');
var dogB = new DOG('二毛');
alert(dogA.species); // 犬科
alert(dogB.species); // 犬科
DOG.prototype.species = '猫科';
alert(dogA.species); // 猫科
alert(dogB.species); // 猫科
两个实例对象共享prototype对象中的属性,只要修改了prototype对象,就会同时影响到两个实例对象。
由于所有的实例对象共享同一个prototype对象,则prototype对象就好像是实例对象的原型,而实例对象则好像是“继承”了prototype对象一样。
五、JavaScript的10个设计缺陷
-前言:为什么有设计缺陷?
1.设计阶段过于仓促(仅仅10天,设计师仅为了交差,本人并不愿意这样设计;且设计初衷就是为了解决一些简单的网页互动,并没有考虑复杂应用的需要)
2.没有先例可以参考(JavaScript同时结合了函数式编程和面向对象编程的特点,这可能是历史上的第一例,直至目前,JavaScript仍是世界上唯一使用prototype继承模型的主要语言)
3.过早的标准化(JavaScript退出一年半之后,国际标准就问世了。设计缺陷还没有充分暴露就成了标准)
-10个设计缺陷
1.不适合开发大型程序
JavaScript咩有名称空间,很难模块化???
没有如何将代码分布在多个文件的规范
允许同名函数的重复定义,后面的定义可以覆盖前面的定义,很不利于模块化加载
2.非常小的标准库
标准函数库非常小,只能完成一些基本操作,很多功能并不具备
3.null和undefined
null属于对象的一种,意思为该对象为空;
undefined是一种数据类型,表示未定义;
typeof null; // object
typeof undefined; //undefined
var foo;
foo == null ; // true
foo == undefined; // true
foo === null; // false
foo === undefined; // true
4.全局变量难以控制
JavaScript的全局变量,在所有模块中都是可见的;
任何一个函数内部都可以生成全局变量,这大大加剧了程序的复杂性;
5.自动插入行尾分号
JavaScript的所有语句,都必须以分号结尾,但是如果忘记加,编译器也不会报错,而是自动为你加上,这使得一些错误很难发现
6.加号运算符
+有两个含义
数字与数字的和 1+1 // 2
字符与字符的连接 "1"+"10" // 110 1+"10" // 110
7.NaN
NaN是一种数字,表示超出了解释器的极限,有一些奇怪的特性
NaN === NaN; // false
NaN !== NaN; // true
console.log(1+NaN); // NaN
8.数字和对象的区分
由于JavaScript的数组也属于对象,所以要区分一个对象到底是不是数组,相当麻烦
if ( arr && typeof arr === 'object' && typeof arr.length === 'number' && !arr.propertyIsEnumerable('length')){
alert("arr is an array");
}
9.和=、
==用来判断两个值是否相等,当两个值的类型不同时,会发生自动转换
=== 需要两个值和类型都相同
10.基本类型的包装对象
JavaScript有三种基本数据类型:字符串、数字和布尔值;他们都有相应的构建函数,可以生成字符串对象、数字对象和布尔值对象
new Boolean(false);
new Number(1234);
new String("Hello World");
alert( typeof 1234); // number
alert( typeof new Number(1234)); // object
参考
4.《JavaScript高级程序设计》(第四版)
作者:米娅小栈
链接:https://www.jianshu.com/p/66d861703013
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。