面向对象
面向对象的三大特点:封装、继承、多态
javascript语言本身拥有对象,实现了对属性,方法的封装(也只是封装了一半,并没有实现对属性和方法的访问控制),却并没有实现继承和多态,但却利用语言的其他特性实现(具体哪些特性,有待研究)了(曲线救国)了继承和多态。所以个人认为javascript”算是“面向象对象语言(重点于写代码的人有没有面向对象的思想)。
- 利用javascript函数的”闭包“特征,可以实现”封装“特点——对属性的公有和私有控制
function List(){ //利用闭包实现私有属性 var m_elements = []; m_elements = Array.apply(m_elements, arguments); //公有属性 this.length = { valueOf:function(){ return m_elements.length; }, toString:function(){ return m_elements.length; } } //公有方法 this.toString = function(){ return m_elements.toString(); } this.add = function(){ m_elements.push.apply(m_elements,arguments); } } var alist = new List(1,2,3); alert(alist); //相当于 alist.toString(); alert(alist.length)//相当于 alist.length.toString();
在javascript里,对象的属性和方法支持4种不同的的类型:
- 私有属性
- 动态公有属性
- 静态公有属性(原型属性)
- 类属性
function myClass(){
//私有变量
var p = 100;
//动态公有变量
this.x = 10;
}
//静态公有变量(原型属性),一旦改动,将影响所有对象,所有对象都可以访问
myClass.prototype.y = 20;
//类变量
myClass.z = 30;
var a = new myClass();
a.p // undefined 因为是私有变量所以该问不到
a.x = 20; // 改变动态公有变量
a.y = 40; // 给单个实例a添加动态公有变量,与原型属性重复时,将覆盖原型属性
delete(a.x); //删除动态公有变量x
delete(a.y); //删除动态公有变量y
a.x // undefined a没了,自然没法访问
a.y // 20 原型属性又还原了,哈哈
myClass.z //30,没啥好说的
匿名函数最有趣的用途是用来创建闭包。闭包(closure)是一个受到保护的变量空间,由内嵌函数生成。Javascript具有函数级的作用域。这意味着定义在函数内部的变量在函数外部不能被访问。Javascript的作用域又是词法性质(lexicallly scoped)。这意味着函数运行在定义它的作用域中,而不是在调用它的作用域中。把两个因素结合起来,就能通过把变量包裹在匿名函数中而对其加以保护。
---《javascript设计模式》
对象的易变性:可以动态的修改类或对象。
对象的内省性:即反射机制(reflection)。
JS在模仿传统的面向对象特性的技术都依赖于对象的易变性和反射机制。
对象易变性的缺点:随时都可以修改一个类或对象,这使得一个对象/类的特征不稳定,进行类型检查很困难,所以这是JS缺少类型检查的原因之一。
继承:JS的继承是基于对象的(原型式)继承,它可以用来模仿基于类(类式)继承。这两种继承方式的性能也会不同,根据手头任务的实际情况,有时其中的某种会更适合一些。