JavaScript 学习笔记5

第六章 面向对象的程序设计html

1.属性类型数组

a.数据属性app

[[configurable]]:可否删除函数

[[enumerable]]:可否枚举this

[[Writable]]:可否修改prototype

[[Value]]:包含这个属性的数据值设计

修改默认的属性:Object.defineProperty()指针

b.访问器属性htm

[[configurable]]:可否删除对象

[[enumerable]]:可否枚举

[[Get]]:在读取属性时调用的函数

[[Set]]:在写入属性时调用的函数

访问器属性不能直接定义,必须调用Object.defineProperty(对象,属性名,修改内容)

注:可同时定义多个属性,

读取属性的方法:Object.getOwnPropertyDescriptor(对象,属性名),返回一个对象

2.建立对象

a.工厂模式——用函数来封装以特定接口建立对象的细节

function createPerson(name,age,job)

{

var o=new Object();

o.age=age;

o.name=name;

o.job=job;

o.sayname=function(){

alert(this.name);

};

return o;

}

b.构造函数模式——用构造函数来穿件特定类型的对象

function Person(name,age,job)

{

this.name=name;

this.age=age;

this.job=job;

this.sayName=function(){

alert(this.name);

};

}

构造函数和普通函数区别:调用方式不一样,经过new操做符调用

构造函数的问题:每一个方法都要在每一个实例上从新建立一次,可经过把函数定义到构造函数外部来解决

c.原型模式

1).原型对象: 

当建立一个新函数,就会为该函数建立一个prototype属性,指向函数的原型对象。全部原型对象自动得到一个constructor属性,这个属性包含一个指向prototype所在函数的指针。

Person.prototype.constructor=Person

当调用构造函数建立实例后,实例的内部包含一个[[Prototype]]指针,指向构造函数的原型对象。

链接是存在于实例与构造函数的原型对象之间的。

方法:alert(Person.prototype.isPrototypeOf(person1));  //true  ,肯定是不是传入对象的原型对象

   alert(Object.getPrototypeOf(person1)==person.prototype);//true,能够方便的取得一个对象的原型

alert(person1.hasOwnProperty.("name"));//true,检测属性在原型仍是实例中

只能经过实例访问原型对象中的值,不能重写原型对象的值,只能够覆盖

 

2).语法——用一个包含全部属性和方法的对象字面量重写原型对象

function Person(){}

Person.prototype ={

constructor:Person,//注:由于彻底重写了默认的prototype对象,constructor属性再也不指向Person,因此这句有必要

name:"aqssfdgrf",

age:28,

job:"student",

sayName:function(){alert("this.name");}

};

 

3).in与for in

in:经过对象能访问到给定属性时返回true,不管在实例仍是原型中

 for-in:返回的是全部可以经过对象访问的,枚举的属性

keys():取得对象上全部可枚举的实例属性,接受一个对象做为参数,返回一个包含全部可枚举属性的字符串数组。

Object.getOwnPropertyName():取得全部实例属性,不管可否枚举

原型的动态性:

实力与原型间是松散连接的关系,实例与原型之间的链接只不过是一个指针,重写原型对象切断了现有原型与任何以前已经存在的实例之间的联系

原型的缺点:因其共享的本质,对包含引用类型值的属性来讲有很大问题

 

d.混合模式——构造函数模式与原型模式结合

构造函数定义实例属性,原型模式共享方法和共享的属性

e.动态原型模式

把全部的信息都封装在构造函数中,经过在构造函数中初始化原型(仅在必要的状况下),又保持了同时使用构造函数和原型的优势。

function Person(name,age,job)

{

this.name=name,

this.age=age,

this.job=job,

//方法,这段代码只有在初次调用构造函数时才会执行

if(typeof sayName!= "function")

{

Person.prototype.sayName=function(){

alert(this.name);

};

}

}

 

原型模式优势

  1. 减小内存消耗,系统资源占用少,全部实例共享同一方法,不会建立多个

  2.  原型对象继承时,子类在重写父类原型方法时很方便,能够很方便 调父类房法,再扩展。

原型模式缺点

  1. 优势1既是最大的优势,也一样带来一个严重问题,若是共享的对象是引用对象(如array)则也会形成多个实例共享同一个array,极可能会相互影响

构造函数缺点

1. 每一次实例化,该对象内部函数都会被建立一遍。

2. 对象继承并须要在子类中调用父类的方法是不可能的,只能够覆盖或者使用。

优势:

每一个实例的公共对象都是不一样的,不会相互影响。

 3.实现继承——依靠原型链继承实际的方法 

a.原型链

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

本质是重写原型对象,代之以一个新类型的实例

肯定原型和实例的关系:a)instanceof    b)isPrototypeOf()

注:给原型添加方法必定要放在替换原型的语句以后

主要问题:a)来自包含引用类型值的原型   b)建立子类型的实例时,不能向超类型的构造函数中传递参数

b.借用构造函数——在子类型函数的内部调用超类型构造函数

call()和apply()——见收藏

优势:能够在子类型构造函数中向超类型构造函数传递参数

缺点:超类型中原型定义的方法对子类型不可见

c.组合继承——最经常使用

有关继承:http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html