javascript面向对象编程笔记
2016-04-22 17:40
489 查看
对象:一切事物皆是对象。对象是一个整体,对外提供一些操作。比如说一个收音机是一个对象,我们不需要知道它的内部结构是什么,只需要会使用外部的按钮就可以使用收音机。
面向对象:面向对象语言的标志是他们都有类的概念,通过类可以创建任意多个具有相同属性的方法的对象。任何对象都是某一类事物的实例,简单的说就是使用对象时,只关注对象提供的功能,不关注其内部细节。
面向对象的特点:封装,继承,多态。
JS中面向对象的组成:1.方法(函数):过程,动态的 2.属性(有所属关系的变量):状态,静态的
对象是无序属性的集合,其属性可以包括基本值、函数、对象。每个属性都会有一个名字,每个名字映射到一个值上
下面是创建一个对象的一些方法
1.工厂模式
使用工厂方式构造对象步骤:
1,原料
2.加工
3.出厂
工厂方式不常用,因为有缺点:1.没有new 2.每个对象都有一套自己的函数,造成资源的浪费
怎么解决这个两个问题呢?那么请看下面
2.构造函数模式
注意:一般将Person称为构造函数,并且构造函数的名字首字母大写,这是编码规范。
this:表示当前的方法属于谁,但是在这里当this碰到New时就会失效。
用造函数模式解决了上面工厂模式没有New的问题
这时就要想一想了在使用new操作符调用构造函数创建一个新实例的过程中发生了什么呢?一个新实例是怎么生成的呢?
这种方式调用构造函数经历以下四个步骤:
1.创建一个新对象
2.将构造函数的作用域赋给新对象(因此this就指向了这个新对象)
3.执行构造函数中的代码(为这个新对象添加属性)
4.返回新对象
面这个例子会看得更加清楚
作为普通函数调用:
全局变量name被修改了
作为构造函数调用:
this指向新对象Name,全局变量name也没有变化
那么问题又来了:
不同实例的showName()函数是不相同的,那么怎么解决这个问题呢?下面是一个解决办法
将showName定义成一个全局方法,这样每个实例共享的都是全局方法showName()。不相等的问题是解决了,可是如果构造函数里有大量的方法,这就造成代码中有大量的全局变量,这样我们自定义的引用类型就没有封装性了,资源还是照样浪费。那么怎么解决这个问题呢?请看原型模式
3.原型模式
prototype(原型)返回对象类型原型的引用。这个属性是一个指针,指向对象。可以让所有对象实例共享它所包含的属性和方法,可以扩展系统对象,节省系统资源,所以这里解决了上面资源浪费问题。
原型的问题:是当一个实例改变属性值时,所有实例对应的属性值也都跟着改变,无法初始化属性值,当为对象实例添加一个属性时,这个属性就会屏蔽原型对象中保存的同名属性,下面是个小例子:
前面几种方法都各有各优缺点,那么把它们综合一下又会怎么样呢?
4.组合使用构造函数模式和原型模式
这种方法是最常用的,结合了两种方法的优点,最大限度地节省了内存
5.动态原型模式
动态原型方法可以通过检查方法是否有效,决定初始化的原型。这种方法堪称为完美,但是不能使用面向字面量重写原型,这样会切断现有实例与新原型之间的联系。
6.寄生构造函数模式
此方法可以和工厂模式对比一下,创建实例方法与构造函数相同,其余与工厂模式相同。如果前面方法都不适用可以考虑一下这种方法,但是这种方法构造函数返回的对象与实例没有关系,也不能依赖instanceof判断对象类型,因此,如果可以使用其他模式这种方法建议还是不要使用。
7.稳妥构造函数模式
所谓稳妥对象,指的是没有公共属性。这种方法适合用于在安全的环境下,因为它不使用new调用构造函数,也不使用this引用实例方法。若想访问其属性,只能通过showname方法来访问其内部私有属性。
面向对象:面向对象语言的标志是他们都有类的概念,通过类可以创建任意多个具有相同属性的方法的对象。任何对象都是某一类事物的实例,简单的说就是使用对象时,只关注对象提供的功能,不关注其内部细节。
面向对象的特点:封装,继承,多态。
JS中面向对象的组成:1.方法(函数):过程,动态的 2.属性(有所属关系的变量):状态,静态的
对象是无序属性的集合,其属性可以包括基本值、函数、对象。每个属性都会有一个名字,每个名字映射到一个值上
下面是创建一个对象的一些方法
1.工厂模式
function createPerson (name,sex) {//工厂方式构造一个对象 //1.原料 var obj=new Object(); //new一个空白对象 //2.加工 obj.name=name; obj.sex=sex; obj.showName=function(){ console.log('我的名字叫:'+this.name) } obj.showSex=function(){ console.log('我是:'+this.sex+'的') } //3.出厂 return obj;//这一步千万不能那下 } var p1=createPerson('木木','女');//每用一次createPerson 就会new一个对象,每个对象都有一套自己的方法 造成资源浪费 var p2=createPerson('扬扬','男'); p1.showName(); p1.showSex(); p2.showName(); p2.showSex();
使用工厂方式构造对象步骤:
1,原料
2.加工
3.出厂
工厂方式不常用,因为有缺点:1.没有new 2.每个对象都有一套自己的函数,造成资源的浪费
怎么解决这个两个问题呢?那么请看下面
2.构造函数模式
function Person (name,sex) {//构造函数 构造一个对象 this.name=name;//this:当前的方法属于谁(在函数前面有new时会失效) this.sex=sex; this.showName=function(){ console.log('我的名字叫:'+this.name); } this.showSex=function(){ console.log('我是:'+this.sex+'的'); } } var p1=new Person('木木','女'); //外面加new后Person函数里面就不用new一个空白对象 var p2=new Person('扬扬','男'); console.log(p1.showName==p2.showName);//fase p1.showName(); p1.showSex(); p2.showName(); p2.showSex();
注意:一般将Person称为构造函数,并且构造函数的名字首字母大写,这是编码规范。
this:表示当前的方法属于谁,但是在这里当this碰到New时就会失效。
用造函数模式解决了上面工厂模式没有New的问题
这时就要想一想了在使用new操作符调用构造函数创建一个新实例的过程中发生了什么呢?一个新实例是怎么生成的呢?
这种方式调用构造函数经历以下四个步骤:
1.创建一个新对象
2.将构造函数的作用域赋给新对象(因此this就指向了这个新对象)
3.执行构造函数中的代码(为这个新对象添加属性)
4.返回新对象
function show(){ alert(this); } show();//弹出window对象(当在全局作用域中调用一个函数时,this对象总指向window对象,全局函数属于window的一个方法) new show();//弹出obj (this会指向)新创建的一个对象
面这个例子会看得更加清楚
作为普通函数调用:
var name = "mumu"; function Person(name){ this.name = name; this.show = function(){ console.log("我是" + this.name); } } Person("javascript"); console.log(name);//结果是javascript
全局变量name被修改了
作为构造函数调用:
var name = "mumu"; function Person(name){ this.name = name; this.show = function(){ console.log("我是" + this.name); } } var Name = new Person("HTML"); console.log(Name.name); console.log(name);
this指向新对象Name,全局变量name也没有变化
那么问题又来了:
console.log(p1.showName==p2.showName);//fase
不同实例的showName()函数是不相同的,那么怎么解决这个问题呢?下面是一个解决办法
function Person (name,sex) {//构造函数 this.name=name;//this:当前的方法属于谁(在函数前面有new时会失效) this.sex=sex; this.showName=showName; } function showName(){ console.log('我的名字叫:'+this.name+'我是:'+this.sex+'的'); } var p1=new Person('木木','女'); //外面加new后Person函数里面就不用new一个空白对象 var p2=new Person('扬扬','男'); console.log(p1.showName==p2.showName);//ture p1.showName(); p2.showName();
将showName定义成一个全局方法,这样每个实例共享的都是全局方法showName()。不相等的问题是解决了,可是如果构造函数里有大量的方法,这就造成代码中有大量的全局变量,这样我们自定义的引用类型就没有封装性了,资源还是照样浪费。那么怎么解决这个问题呢?请看原型模式
3.原型模式
function Person(name,sex) {//原型模式构造函数 Person.prototype.name=name; Person.prototype.sex=sex; Person.prototype.showName=function(){ console.log('我的名字叫:'+this.name+'我是:'+this.sex+'的'); } } var p1=new Person('木木','女'); var p2=new Person('扬扬','男'); console.log(p1.showName==p2.showName);//ture p1.showName(); p2.showName();
prototype(原型)返回对象类型原型的引用。这个属性是一个指针,指向对象。可以让所有对象实例共享它所包含的属性和方法,可以扩展系统对象,节省系统资源,所以这里解决了上面资源浪费问题。
原型的问题:是当一个实例改变属性值时,所有实例对应的属性值也都跟着改变,无法初始化属性值,当为对象实例添加一个属性时,这个属性就会屏蔽原型对象中保存的同名属性,下面是个小例子:
function Person(name,sex) {//原型模式构造函数 Person.prototype.name=name; Person.prototype.sex=sex; Person.prototype.showName=function(){ console.log('我的名字叫:'+this.name+'我是:'+this.sex+'的'); } } var p1=new Person('木木','女'); var p2=new Person('扬扬','男'); p1.name="兮兮"; p1.showName();//兮兮 来自实例 p2.showName();//扬扬 来自原型
前面几种方法都各有各优缺点,那么把它们综合一下又会怎么样呢?
4.组合使用构造函数模式和原型模式
//构造函数模式定义实例属性 function Person (name,sex) { this.name=name; this.sex=sex; } //原型模式共用方法和共享属性 Person.prototype.showName=function(){ console.log('我的名字叫:'+this.name+'我是'+this.sex+'的') } var p1=new Person('木木','女'); p1.showName();
这种方法是最常用的,结合了两种方法的优点,最大限度地节省了内存
5.动态原型模式
function Person(name, age) { this.name = name; this.age = age; //方法 if(typeof this.showName != 'function') { Person.prototype.showname = function() { console.log("我的名字是: " + this.name); } } } var person1 = new Person("mumu", 17); person1.showname();
动态原型方法可以通过检查方法是否有效,决定初始化的原型。这种方法堪称为完美,但是不能使用面向字面量重写原型,这样会切断现有实例与新原型之间的联系。
6.寄生构造函数模式
function createPerson(name, age) { var obj=new Object(); obj.name = name; obj.age = age; obj.showName = function() { console.log("我的名字是:" + this.name); } return obj; } var person = new createPerson("mumu", 17); person.showName();
此方法可以和工厂模式对比一下,创建实例方法与构造函数相同,其余与工厂模式相同。如果前面方法都不适用可以考虑一下这种方法,但是这种方法构造函数返回的对象与实例没有关系,也不能依赖instanceof判断对象类型,因此,如果可以使用其他模式这种方法建议还是不要使用。
7.稳妥构造函数模式
function Person(name, age) { var obj = new Object(); //定义一些私有变量和函数 obj.showName = function() { console.log("我的名字是:" + name); //定义的私有变量等只能通过showName访问 } return obj; } var person1 = Person("兮兮", 17); person1.showName();
所谓稳妥对象,指的是没有公共属性。这种方法适合用于在安全的环境下,因为它不使用new调用构造函数,也不使用this引用实例方法。若想访问其属性,只能通过showname方法来访问其内部私有属性。
相关文章推荐
- JSON和JSONP的区别详解
- js--编写可维护的JavaScript-2.编程实践
- JavaScript检测浏览器类型
- fastjson用法&Gson
- JavaScript扫盲篇
- ES6-Promise
- JavaScript动画篇之缓冲运动
- 举例讲解如何判断JavaScript中对象的类型
- JS缓冲运动与透明渐变
- javascript柯里化及组合函数~
- JavaScript 日期Long to Date 格式
- ES6-Generator与异步操作
- 如何让js不产生冲突,避免全局变量的泛滥,合理运用命名空间
- jsp前台点击下载功能
- fastJson将json数组转list对象
- 高性能web开发:如何加载js,,js的存放位置
- JS正则表达式语法详解
- JS正则表达式语法详解
- 爬楼梯 js算法
- JavaScript标准: ES6和ES5