JavaScript面向对象
一、面向对象
0x1 基本概念
对代码的一种抽象,对外统一提供调用接口的编程思想,基于原型的面向对象方式中,对象(object)则是依靠构造器(constructor)利用 原型(prototype)构造出来的。
1、面向对象的名词解释
- 方法:事物的功能
- 属性:事物的特性
- 对象:事物的一个实例
- 原型: Js函数中由prototype属性引用了一个对象,即原型对象(原型)
1 2 3 4 5 6 |
//构造函数对象:函数构造器 创建函数对象 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.让局部变量一直存在在内存中
优点:有利于封装。可以访问局部变量
缺点:内存占用浪费,内存泄漏
变量与作用域
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
//函数内部可以读取全局变量: 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、字面式声明
1 2 3 4 5 6 7 |
Var obj = { 属性名称:属性值, 属性名称:属性值, 方法名称:function() { } , 方法名称:function() { } } |
2、构造函数声明
1 2 3 4 |
var obj = new Object(); obj.属性 = 属性值; obj.方法 = function (str){ body }; |
3、构造方法声明对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
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对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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 定义-些属性及方法。
让所有实例化的对象都拥有它包含的属性及方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
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、混合模式
构造模式 + 原型模式
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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 对象的遍历
如果是构造函数,必须实例化之后才可以遍历对象。
1 2 3 4 5 6 |
//i是属性或方法名称 //取得的是属性的值 或者是方法的定义代码 for (var i in obj){ obj[i]; } |
对象的数据存储方式
0x4 封装
封装(Encapsulation):把对象内部数据和操作细节进行隐藏
大多面向对象的语言都支持封装的特性,提供了 private 关键字来隐藏某些属性或方法,用来限制被封装的数据或者内容的访问,只对外提供一个对象的专门访问的接口。
JavaScript中可以通过闭包实现封装,函数内部声明的变量外部是访问不到的。
公有与私有内容的区别是:能否在对象外部被访问,类似于作用域。