JavaScript面向对象

Author:Helene

本文章采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。转载请注明来自Helene的博客


面向对象:

对代码的一种抽象,对外统一提供调用接口的编程思想
基于原型的面向对象

基于原型的面向对象方式中,对象则是依靠构造器利用原型构造出来的
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中的特权方法和属性,没有继承共有方法和属性