JS面向对象

JS中的对象

一切皆对象

1,在JavaScript中,一切都是对象;
2,在JavaScript中,包括两种类型,一种是基本类型,一种是引用类型;

1,相同点:两种类型都可以使用属性和调用方法;
2,不同点:
    1,基本类型是直接通过赋值得到的,引用类型是通过new关键字创建的;;
    2,基本类型使用typeof可以得到对应的基本类型,而对象通过typeof得到的都是object;
    3,引用类型可以自己添加额外的属性和方法,但是基本类型不行;

JS中对象的基本操作

对象的创建方式

1,使用new关键字创建一个js对象:
var obj=new Object();
2,使用json的方式创建一个js对象;
var obj={};

注意,我们这里两种方式创建出来的对象都应该算java中的对象实例;

给对象添加属性

1,obj.attr=value;
2,obj['attrName']=value;
注意,第二种方式可以使用变量,第二种方式也可以添加一些特殊名字的属性;

给对象添加方法属性:

obj.someMethod=function(){
    return this.attrName;
}

var attrName='attr';
obj[attrName]=value;//==obj['attr']=value;

访问对象属性

1,obj.attrName;
2,obj['attrName'];
同样,第二种也支持变量引用的方式访问属性;

调用对象的方法:
obj.someMethod();

删除对象的属性

1,obj.attr=undefined;obj['attr']=undefined;
注意,这种方式可以达到删除属性的目的,只是不是真正的删除属性;

2,使用delete关键字:
delete obj.attr;删除obj的attr属性;
同样,也可以使用delete obj['attr'];

对象的克隆

1,对象克隆就是创建一个新的对象,需要从一个目标对象中拷贝所有的属性;
2,在Js中,对象的本质是一堆属性的集合,可以使用for..in..关键字来遍历并拷贝属性值:

function clone(obj){
    var newObject=new Object();
    for(var prop in obj){
        newObject[prop]=obj[prop];
    }
}

JS中的Function

function基础

1,把function作为函数:

function msg(msg){
    alert(msg);
}

2,把function作为方法:

var obj=new Object();
obj.showMsg=msg;
obj.showMsg("haha");

3,把function作为对象:

var fn=function(name){};
console.debug(fn.length);
fn.call(window,"haha");

this和作用域

变量作用域

1,全局变量:在script中直接使用var声明的变量;所有的全局变量都是声明在window对象上的;
2,局部变量:在一个函数体内声明的变量;
3,变量的使用遵循就近原则;

this关键字

this关键字的使用

1,this关键字可以明确的指定作用域;
2,this关键字代表的是一个作用范围,谁调用这个函数,this指代的作用域就是谁;
3,所有不加前缀的函数调用,作用域都是window;

var msg="msg1";
function showMsg(){
    var msg="msg2";
    console.debug(msg+","+this.msg);
}
showMsg();

var msg="msg";
var obj={
  msg:"msg1",
  showMsg:function(){
    var msg="msg2";
    console.debug(msg+","+this.msg);
  }
}
obj.showMsg();

call和apply

call和apply都可以改变函数执行时候的this指向谁;

1,call(thisObject/scope,methodArguments);
2,apply(thisObject/scope,methodArgArray);
两个方法都可以临时的把一个方法的调用指派到指定的对象上,即把这个方法定义中所有的this指向thisObject;
两个方法的区别:call方法第二个参数是变参,代表方法调用的实参;apply方法第二个参数必须是实参的数组;

var msg="msg1";
function showMsg(){
    var msg="msg2";
    console.debug(msg+","+this.msg);
}

var obj={msg:"msg3"};
showMsg.call(obj);
//showMsg.apply(obj);

JS中的类

使用function创建一个类

1,使用function创建一个类(JS中使用函数对象来代表一个类);

function Persion(){};
var p=new Persion();

2,声明类的这个function同时也可以作为这个类的构造方法:

function Persion(name,age){
    this.name=name;
    this.age=age;
}
var p=new Person("name",18);

3,为类添加方法:

1,最简单的添加方式:
    function Person(){
           this.showTime=function(){
             alert("showTime");
           }
    }
问题:每一个Person实例都对应一个新的showTime function对象,容易造成内存泄露;
2,只创建一个方法实例:
    function showTime(){
        alert("showTime");
    }

    function Person(){
        this.showTime=showTime;
    }

问题:破坏了类的封装特性;

使用prototype

ptototype的基本使用

1,使用prototype为类添加方法:

    function Person(){
    }
    Person.prototype.showTime=function(){
        alert("showTime");
    }

2,prototype是function上的一个特殊属性,在对象上没有,所以不可能使用this.prototype.showTime来为类添加方法;
3,prototype一般是用来给类添加统一的方法和属性的;

JS中对象的内部结构

1,__proto__:这个属性是Js对象上的隐藏属性,这个属性指向的是该对象对应类型的prototype对象;
2,js中对象分为两部分,

一部分是原生部分,原生部分是在构造函数中定义的,或者是直接通过对象.属性=value赋值的;
一部分是扩展部分,扩展部分的内容是通过类.prototype.属性=value赋值的;

3,对于原生部分,直接使用obj.属性(方法)访问;

 对于扩展部分,可以通过obj.__proto__.属性(方法)访问;

4,对于js的对象来说,在查询方法或者属性的时候,会沿着prototype链,按照就近原则访问,所以obj.__proto__.属性(方法)也可以直接通过obj.属性(方法)访问;
5,

    function Person(){
        this.toString=function(){return "[Person]"};
    }
    Person.prototype.toString=function(){return "person [Person]";}

JS中类的继承

简单继承

function User(name,age){
    this.name=name;
    this.age=age;
}

function Person(name,age,tel){
}

1,完成原生部分的继承;

function Person(name,age,tel){
    User.apply(this,arguments);
    this.tel=tel;
}

2,完成扩展部分的继承;

function Person(name,age,tel){
    User.apply(this,arguments);
    this.tel=tel;
}
for(var p in User.prototype){
    Person.prototype[p]=User.prototype[p];
}

原型链继承

1,简单继承的问题:
使用简单继承,子类的实例使用instanceof不能判定为父类的类型;
2,instanceof的判定原理:就是判定该对象的原型链中是否有对象属于指定类型;
3,基于原型链的继承:

function User(name,age){
    this.name=name;
    this.age=age;
}
User.prototype.show=function(){
    alert(name+","+age);
}

function Employee(name,age,email){
    User.apply(this,arguments);
    this.email=email;
}
Employee.prototype=new User();

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注