一、面向对象
0x1 基本概念
对代码的一种抽象,对外统一提供调用接口的编程思想,基于原型的面向对象方式中,对象(object)则是依靠构造器(constructor)利用 原型(prototype)构造出来的。
1、面向对象的名词解释
- 方法:事物的功能
- 属性:事物的特性
- 对象:事物的一个实例
- 原型: Js函数中由prototype属性引用了一个对象,即原型对象(原型)
//构造函数对象:函数构造器 创建函数对象
Var obj = new function (varl,var2,...,functionBody ());
var1, var2 正常变量 functionBody()自定函数
注意:构造器构造的对象,效率低:var1 var2 顺序在functionBody 中不能变
var obj = new Function ("a","b","return a + b");
2、闭包
闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数)
作用:1.读取函数内部变量。2.让局部变量一直存在在内存中
优点:有利于封装。可以访问局部变量
缺点:内存占用浪费,内存泄漏
变量与作用域
//函数内部可以读取全局变量:
var n = 999;
function f1() {
alert(n);
}
f1(); // 999
//外部无法读取函数内声明的变量
function f1() {
var n = 999;
//函数内省略var就是一个全局变量,外部可访问
}
alert(n);
//全局变量在函数内部可以访问
//语法特征:函数b是在a内嵌套的,函数a需要返回函数b
function a() {
var i = 0;
function b() {
alert(++i);//++i返回的则是自增后的值
}
return b;
}
var c = a(); //调用function b
c(); //执行function b 得到闭包里的变量i+1
//变量内存始终保存在内存中
function f1() {
var n = 999;
nAdd = function () { n += 1 }
function f2() {
alert(n);
}
return f2;
}
var result = f1();
result(); // 999
nAdd();
result(); // 1000
0x2 对象声明的方式
1、字面式声明
Var obj = {
属性名称:属性值,
属性名称:属性值,
方法名称:function() { } ,
方法名称:function() { }
}
2、构造函数声明
var obj = new Object();
obj.属性 = 属性值;
obj.方法 = function (str){ body };
3、构造方法声明对象
function test([参数列表]){
this.属性 = 属性值;
this.方法 = function (){ body }
}
var obj = new test(参数列表);
function Cperson(name, sex, age) {//注意这里 构造函数首字母大写
this.name = name; //习惯上属性名和参数名一致
this.sex = sex;
this.age = age;
this.show = function () {
console.log(this.name, this.age, this.sex);
}
}
var p1 = new Cperson('zhangsan', '男', '100');
p1.show();
var p2 = new Cperson('lisi', '女', '14');
p2.show();
//this代表当前对象,p1,p2两者之间是独立的,函数内部只能用this访问属性和方法
4、工厂方式声明对象
构造方式不会显示创建对象将属性赋值给 this 不要 return 对象
工厂方式在方法内部创建 object 对象返回 object 对象,属性和方法都是赋给object对象
function createObject(name, age) { //集中实例化的函数
var obj = new Object();
obj.name = name;
obj.age = age;
obj.run = function () {
return this.name + this.age + '运行中...';
};
return obj; //必须要return obj
}
var box1 = createObject('Lee', 100); //第一个实例
var box2 = createObject('Jack', 200); //第二个实例
alert(box1.run());
alert(box2.run()); //保持独立
5、原型模式声明对象
原理:函数本身声明为空内容,利用 prototype 定义-些属性及方法。
让所有实例化的对象都拥有它包含的属性及方法。
function Car() {
}
Car.prototype.color = "red";
Car.prototype.doors = 4;
Car.prototype.showColor = function () {
alert(this.color);
}
var car1 = new Car();
alert(car1.doors)
var car2 = new Car();
car1.showColor();
//还可以以json数据定义属性和方法
Car.prototype = {
color : "red",
doors : 4,
showColor : function () {
alert(this.color);
}
}
6、混合模式
构造模式 + 原型模式
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("zhangsan", "http://www.baidu.com/", ["aaa", "bbb", "ccc", "ddd"]);
var blog2 = new Blog("lisi", "http://www.sina.com/", ["aaa", "bbb", "ccc", "ddd"]);
blog.alertInfo();
blog2.alertInfo();
0x3 对象的遍历
如果是构造函数,必须实例化之后才可以遍历对象。
//i是属性或方法名称
//取得的是属性的值 或者是方法的定义代码
for (var i in obj){
obj[i];
}
对象的数据存储方式
0x4 封装
封装(Encapsulation):把对象内部数据和操作细节进行隐藏
大多面向对象的语言都支持封装的特性,提供了 private 关键字来隐藏某些属性或方法,用来限制被封装的数据或者内容的访问,只对外提供一个对象的专门访问的接口。
JavaScript中可以通过闭包实现封装,函数内部声明的变量外部是访问不到的。
公有与私有内容的区别是:能否在对象外部被访问,类似于作用域。