面向对象:
对代码的一种抽象,对外统一提供调用接口的编程思想
基于原型的面向对象
基于原型的面向对象方式中,对象则是依靠构造器利用原型构造出来的
js面向对象的名词解释
属性:事物的特性
方法:事物的功能
对象:事物的一个实例
原型:Js函数中由prototype属性引用了一个对象,即原型对象(原型)
构造函数对象:函数构造器创建函数对象
var obj = new Function(var1,var2,...,functionBody(){});
var1,var2正常变量functionBody()自定义函数体
注意:构造器构造的对象,效率低,var1,var2顺序在functionBody中不能变
例子:
var obj = new Function("a","b","return a+b")
var s = obj
alert(s)
说明:对象===》函数对象(new Function),普通对象(其它)
js中的闭包
闭包:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数)
例子:
function a(){
var i = 0;
function b(){
alert(++i);
}
return b;
}
var c = a();
c();
特点:函数b是在a内嵌套的,函数a需要返回函数b
用途:
1、读取函数内部变量
2、让i变量的值保存在内存中
优点:有利于封装,可以访问局部变量
缺点:内存占用浪费严重,内存泄露
js字面式对象声明对象
var obj = {
属性名称:属性值,
属性名称:属性值,
属性名称:属性值,
...
方法名称:function(){},
方法名称:function(){},
...
}
new操作符后跟Object构造函数
var obj = new Object();
obj.属性 = 属性值;
obj.属性 = 属性值;
obj.方法 = function(str){
方法代码
}
Object是所有对象的基类、根、所有的JavaScript对象都是由Object延伸的
js构造方法声明对象
function test([参数列表]){
this.属性 = 属性值
this.方法 = function(){
方法中的代码
}
}
var obj = new test(参数列表)
注意:实例化出来的对象之间是独立的,之间没有任何关系,this代表当前对象,函数内部只能用this访问属性和方法
工厂模式创建对象
function createObject(){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.run = function(){
return this.name + '----' + this.age;
}
obj.say = function(){
return '今天天气不错'
}
return obj;
}
var box1 = createObject("张三",18);
var box2 = createObject('李四',20);
注意:任何模式下,同种模式中创造出来的对象都是独立存在的
构造方式和工厂模式不同:
1、构造方式不会显示创建对象,将属性赋值给this,不需要return对象
2、工厂模式在方法内部创建object对象,返回object对象,属性和方法都是赋值给object对象
js中原型模式声明对象
function test(){}
test.prototype.属性 = 属性值;
test.prototype.属性 = 属性值;
test.prototype.方法名称 = function(){
执行代码
};
var obj = new test();
任何js方法或者函数,都自带一个prototype属性,且它以对象方式存在
原型模式根本:函数本身声明为空内容,利用prototype定义一些属性和方法。
好处:让所有实例化的对象都拥有它包含的属性及方法
js中混合模式声明对象
function test(v1,v2,v3){
this.v1 = v1;
this.v2 = v2;
this.v3 = v3;
}
test.prototype.方法名称 = function(){
执行代码
}
var obj = new test(v1, v2, v3);
混合模式:构造+原型
遍历对象
遍历对象的属性,对象可以当做数组处理for in
for(var i in ren){renp[i]}
i是属性或者方法名称
ren[i]取得是属性的值或者是方法的定义代码
for in方法可以遍历任何种方式定义的对象
对象在内存中的分布
对象的名称保存在栈内存中,对象的结构写在堆内存中,其中属性的方法代码写在代码段中,栈内存中的名称通过地址段引用堆内存中的对象结构
封装的概念
封装:把对象内部数据和操作细节进行隐藏
大多面向对象的语言都支持封装的特性,提供了private关键字来隐藏某些属性和方法,用来限制被封装的数据或者内容的访问,只对外提供一个对象的专门访问的接口。接口一般为调用的方法。
在JavaScript没有提供专门的封装的关键词,但是可以通过闭包实现封装。函数内部声明的变量,外部是访问不到的。
公有与私有内容的区别是:能否在对象外部被访问。
原型和原型链
原型:是利用prototype添加属性和方法
原型链:JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做_proto_的内置属性,用于指向创建它的函数对象的原型对象prototype
构造函数继承
在子类内部构造父类的对象实现继承,所有的属性和方法,都将传到子对象中。
例子:
function parents(name){
this.name = name;
this.say = function(){
alert("父亲的名字:"+this.name)
}
}
function child(name,age){继承parents
this.obj = parents(); //子对象的参数name传递到父对象中
this.age = age;
this.sayC = function(){
alert("child"+this.name+"----"+"age"+this.age);
}
}
var p = new parents("zhangsan");
p.say();//zahngsan
var c = new child("李四",20)
c.sayC;//李四
对象内置方法中的apply和call都可以用于继承,区别在于传参方式的不同。
call:调用一个对象的一个方法,以另一个对象替换当前对象
apply:应用某一对象的一个方法,用另一个对象替换当前对象
例子:
function person(name,age,len) {
this.name = name;
this.age = age;
this.len = len;
this.say = function(){
alert(this.name+":"this.age+":"+this.len);
}
}
<!-- call继承 -->
function student(name,age) {
person.call(this,name,age);
}
<!-- apply继承 -->
function teacher(name,age,len){
person.apply(this,[name,age,len])
}
var per = new person("张三",25,"170");
per.say();
var stu = new student("李四",18);
stu.say();//李四 18 undefined
var tea = new teacher("王五",20,"280");
tea.say();
js面向对象的关键词
instanceof、delete、call、apply、arguments、callee、this
instanceof 变量是否是对象的实例 所有对象本质上都是继承于Object
delete 删除对象的属性,不能删除对象的方法,不能删除原型链中的属性和变量
call/apply
callee 返回正在执行的function对象,function内容
argument.callee 默认值 正在执行的function对象 callee指代函数本身 在递归的时候使用比较好
对象冒充
将父类的属性和方法一起传给子类作为特权属性和特权方法
例子:
function person(name,age){
this.name = name;
this.age = age;
this.sayHi = function(){
alert("hi");
}
}
person.prototype.walk = function(){
alert("walk......")
}
function student(name,age,grade){
this.newMethod = person;//冒充person对象,传递特权属性和特权方法给子类
this.newMethos(name,age);
this.grade = grade;
}
var s1 = new student("李四",15,5);//s1是student对象,继承person,拥有person所有属性和方法
s1.sayHi();
//注意 s1继承了person中的特权方法和属性,没有继承共有方法和属性