js面向对象编程

==什么是对象?==
就是无序属性的集合,经过属性或者方法名与值的一一映射。
==对象的属性类型==
对象中还定义了一些js中不能直接访问的属性,是为了实现js引擎用的。有数据属性访问器属性两种。
1.数据属性
数据属性包含一个数据值的位置。在这个位置能够读取和写入值。数据属性有 4 个描述其行为的
特性。app

把新值保存在这个位置。这个特性的默认值为 undefined。函数

要修改属性默认的特性,必须使用 ECMAScript 5 的 Object.defineProperty()方法。this

clipboard.png
注意:
1》 configurable 设置为 false,表示不能从对象中删除属性。若是对这个属性调用 delete,则 在非严格模式下什么也不会发生,而在严格模式下会致使错误。并且,一旦把属性定义为不可配置的, 就不能再把它变回可配置。
2》在调用 Object.defineProperty()方法时,若是不指定,configurable、enumerable 和 writable 特性的默认值都是 false。
2.访问器属性
访问器属性不包含数据值;包含一对儿 getter 和 setter 函数(不过,这两个函数都不是必需的)。 在读取访问器属性时,会调用 getter 函数,这个函数负责返回有效的值;在写入访问器属性时,会调用 setter 函数并传入新值,这个函数负责决定如何处理数据。访问器属性有以下 4 个特性。spa

 [[Get]]:在读取属性时调用的函数。默认值为 undefined。
 [[Set]]:在写入属性时调用的函数。默认值为 undefined。
访问器属性不能直接定义,必须使用 Object.defineProperty()来定义。prototype

clipboard.png

能够经过Object.definePro- perties()定义多个属性;
使用 ECMAScript 5 的 Object.getOwnPropertyDescriptor()方法,能够取得给定属性的描述符。code

==建立对象的方式==
经过字面量的方式能够建立对象,可是建立有相似属性的对象时会产生大量重复代码。
1.工厂模式
用函数来封装以特定接口建立对象。对象

clipboard.png
缺点就是没法知道一个对象的类型。
2.构造函数模式继承

clipboard.png
经过构造函数建立的对象能够经过constructor标识对象类型,经过instanceof检测对象类型。
构造函数模式与工厂模式对比:
1》没有显式地建立对象;
2》直接将属性和方法赋给了 this 对象;
3》 没有 return 语句。
经过new操做符调用构造函数会经历4个步骤:
(1) 建立一个新对象;
(2) 将构造函数的做用域赋给新对象(所以 this 就指向了这个新对象);
(3) 执行构造函数中的代码(为这个新对象添加属性);
(4) 返回新对象。接口

clipboard.png
构造函数也可做为普通函数调用
Person("Greg", 27, "Doctor"); // 添加到window window.sayName(); //"Greg"
也能够在另外一个对象的做用域中调用
var o = new Object();
Person.call(o, "Kristen", 25, "Nurse"); o.sayName(); //"Kristen"ip

构造函数模式的缺点就是每一个方法都要在每一个实例上从新建立一遍

function Person(name, age, job){

this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = new Function("alert(this.name)"); 
    // 与声明函数在逻辑上是等价的

}
alert(person1.sayName == person2.sayName); //false
3.原型模式

clipboard.png
经过prototype为对象添加属性和方法。这样实例就能共享原型的属性和方法。
1》原型具备动态性。在实例化后定义的原型方法,实例也能调用。

clipboard.png

2》原型的简单写法。

clipboard.png

能够将原型简写如上,可是这种写法其实是从新写了原型,新原型的constructor已经改变,指向object。因此能够从新设置constructor。
并且若是在实例化后重写原型,则已经实例的对象依旧访问原来原型对象,不能访问新原型的方法和属性。

clipboard.png

组合使用构造函数模式和原型模式

clipboard.png

===继承===

继承:利用原型让一个引用类型继承另外一个引用类型的属性和方法。

1.原型链继承

包含引用类型值的原型属性会被全部实例共享;而 这也正是为何要在构造函数中,而不是在原型对象中定义属性的缘由。在经过原型来实现继承时,原型实际上会变成另外一个类型的实例。因而,原先的实例属性也就瓜熟蒂落地变成了如今的原型属性了。
原型链的问题是:因为原型中包含引用类型值所带来的问题。和在建立子类型的实例时,不能向超类型的构造函数中传递参数。实际上,应该说是没有办法在不影响全部对象实例的状况下,给超类型的构造函数传递参数。实践中不多会单独使用原型链。

2.构造函数继承

借用构造函数:别忘了,函数只不过是在特定环境中执行代码的对象, 所以经过使用 apply()和 call()方法也能够在(未来)新建立的对象上执行构造函数。

clipboard.png

借用构造函数的问题
若是仅仅是借用构造函数,那么也将没法避免构造函数模式存在的问题——方法都在构造函数中定 义,所以函数复用就无从谈起了。并且,在超类型的原型中定义的方法,对子类型而言也是不可见的,结 果全部类型都只能使用构造函数模式。考虑到这些问题,借用构造函数的技术也是不多单独使用的。

组合继承

clipboard.png

组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优势,成为 JavaScript 中最经常使用的继 承模式。

相关文章
相关标签/搜索