面向对象的理解:
面向对象可以把程序中的关键模块视为对象,而模块拥有属性和方法。这样我们一些属性和方法封装起来,日后使用非常方便,也可以避免繁琐重复性的工作。
面向对象的特点:
1.封装
对于一些功能相同或者相似的代码,我们可以放到一个函数中去,多次用到此功能时,我们只需要调用即可,无需多次重写。
2.继承
子类可以继承父类的属性方法。
3.多态(重载和重写)
重载:严格意义上说js中没有重载的功能,不过我们可以通过判断函数的参数的不同来实现不同的功能来模拟重载。
重写:子类可以改写父类的属性和方法。
javaScript中的封装:
1. 工厂模式
工厂模式是软件工程领域中一种广为人知的设计模式,由于ECMAScript无法创建类, 因此用函数封装以特定的接口创建对象.其实现方法非常简单,也就是在函数内创建一个对象,在给对象赋予属性及方法再将对象返回即可.
/**
* 工厂模式
* 优点:解决了创造对象的问题
* 缺点:没有解决对象的识别问题 instanceof -> Object
* */
function createPerson(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
console.log(this.name);
};
return o;
}
var person1 = createPerson("xialiu", 24, "shijiazhuang");
var person2 = createPerson("xiaobei", 22, "hainan");
console.log(person1);
console.log(person2);
2. 构造函数模式
构造函数有一些规范:
1)函数名和实例化构造名相同且大写,(PS:非强制,但这么写有助于区分构造函数和
普通函数);
2)通过构造函数创建对象,必须使用new 运算符。
/**
* 构造函数模式
* 优点:解决对象识别的问题
* 缺点:不同实例上的同名函数是不相等的.有this对象在,没有必要再执行代码前把函数绑定到特定对象上来.
* */
/**
* 构造函数模式
* 优点:解决对象识别的问题
* 缺点:不同实例上的同名函数是不相等的.有this对象在,没有必要再执行代码前把函数绑定到特定对象上来.
* */
function Blog(name,url){
this.name = name;
this.url =url;
this.alerturl = function () {
console.log(alerturl);
}
}
var blog = new Blog("xiaomeng","HTTP://www.baidu.com/");
console.log(blog instanceof Blog);//true, 判断blog是否是Blog的实例,即解决了工厂模式中不能
console.log(blog);
注:
1)构造函数和普通函数的唯一区别,就是他们调用的方式不同。只不过,构造函数也是函数,必须用new 运算符来调用,否则就是普通函数。
2)this就是代表当前作用域对象的引用。如果在全局范围this 就代表window 对象,如果在构造函数体内,就代表当前的构造函数所声明的对象。
这种方法解决了函数识别问题,但消耗内存问题没有解决。同时又带来了一个新的问题,全局中的this 在对象调用的时候是Box 本身,而当作普通函数调用的时候,this 又代表window。即this作用域的问题。
3. 原型模式
我们创建的每个函数都有prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法.使用原型对象的好处就是可以让所有对象实例共享它所包含的属性和方法.
它解决了消耗内存问题。当然它也可以解决this作用域等问题。
/**
* 原型模式
* */
function Blog(){
Blog.prototype.name = "xiaomeiren";
Blog.prototype.url = "http://www.xiaomeiren.com/";
Blog.prototype.friend = ["aaa", "bbb", "ccc", "ddd", "eee"];
Blog.prototype.alertInfo = function () {
console.log(this.name + ' ' + this.url + ' ' + this.friend);
}
}
var blog = new Blog(), blog2 = new Blog();
blog.alertInfo(); //"xiaomeiren http://www.xiaomeiren.com/ aaa,bbb,ccc,ddd,eee"
blog2.alertInfo(); //"xiaomeiren http://www.xiaomeiren.com/ aaa,bbb,ccc,ddd,eee"
blog.name = "xiaomeiyun";
blog.url = "http://www.xiaomeiyun.com/";
blog.friend.pop();
blog2.name = "xiaomeiyun2";
blog2.url = "http://www.xiaomeiyun2.com/";
blog.alertInfo(); //"xiaomeiyun http://www.xiaomeiyun.com/ aaa,bbb,ccc,ddd"
blog2.alertInfo(); //"xiaomeiyun2 http://www.xiaomeiyun2.com/ aaa,bbb,ccc,ddd"
构造函数的声明方式和原型模式的声明方式存储情况如下:
4. 混合模式
/**
* 混合模式 = 原型模式 + 构造函数模式
* */
function Blog(name, url, friend ) {
this.name = name;
this.url = url;
this.friend = friend;
}
Blog.prototype.alertInfo = function () {
console.log('名字:'+this.name + ' 博客:' + this.url + ' 好友:' + this.friend);
}
var blog = new Blog("LiMing","http://www.limingweb.com/",["aaa", "bbb","ccc", "ddd"]),
blog2 = new Blog("LiMingming","http://www.limingmingweb.com/",["aaa", "bbb","ccc", "ddd"]);
blog.friend.pop();//arrayObject.pop();方法用于删除并返回数组的最后一个元素,并且数组长度减1.
blog.alertInfo();//名字:LiMing 博客:http://www.limingweb.com/ 好友:aaa,bbb,ccc
blog2.alertInfo();//名字:LiMingming 博客:http://www.limingmingweb.com/ 好友:aaa,bbb,ccc,ddd
混合模式中构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性. 每个实例都会有自己的一份实例属性,但同时又共享这方法,最大限度的节省了内存.另外这种模式还支持传递初始数据.优点胜多,这种模式使用广泛,认同度最高的一种创建自定义对象的方法.
5.动态原型模式
function Blog(name, url) {
this.name = name;
this.url = url;
if(typeof this.alertInfo != "function"){
//这段代码只执行一次
console.log("haha");
Blog.prototype.alertInfo = function () {
console.log('名字:'+this.name + ' 博客:' + this.url);
}
}
}
var blog = new Blog("LiMing","http://www.limingweb.com/"),
blog2 = new Blog("LiMingming","http://www.limingmingweb.com/");
网友评论