您的位置 >>> 星想互联 >>> 编程技术 >>> JQUERY+JS
JS的面向对象深入了解
点击数:1448  发布时间2018-07-14 20:17:27
对象是一种复合数据类型,它们将多个数据值集中在一个单元内,而且允许使用名字来存取这些值。对象的另一种解释是:它是一个无序的属性的集合,每个属性都有自己的名字和值。存储在对象中已命名的值既可以是数字和字符串这样的原始值,也可以是对象。

对象的创建
常用的有三种方式: 
一、直接创建法: 
var empty = {}; 
var point = {x:0,y:0};

二、new 运算符可以创建具体的一类对象。在 new 的后面跟着调用一个构造函数,它用来初始化对象的属性。 
var a = new Array(); 
var d = new Date(); 
var r = new RegExp(“javascript”,”i”); 
//Array(),Date(),RegExp()构造函数是核心

三、 
Object()构造函数创建一个空对象。

对象的属性
访问:var x = 对象名.属性名; 
设置:对象名.属性名 = x;

var book = {};//直接创建法
book.title = "JavaScript:The Definitive Guide";
book.chapter1 = new Object();//Object()构造函数创建一个空对象
book.chapter1.title = "Introducation to JavaScript";
book.chapter1.page = 11;
book.chapter2 = {title:"Lexical Structure", pages:6};
book;

/*for/in循环提供了一种遍历对象属性的方法,它可以枚举出对象的所有属性名*/
function displayPropertyNames(){
    var names = '';
    for(var name in book){
      names += name +":"+book[name]+'\n';
    }
   return names;
}
displayPropertyNames();


属性的删除
var book = {}; 
book.chapter2 = “fewklfe”; 
delete book.chapter2; 
删除属性并不仅仅把属性值设为undefined,它实际上是从对象中移除了属性,在删除之后,for/in不会再枚举该属性。

作为关联数组的对象
object.property < = > object[“property”] 
前者的属性名是标识符,后者的属性值是一个字符串 
因些,采用后一种方式,我们可以为对象动态的添加属性 
var addr = “”; 
for(i=0;i<4;i++){ 
addr += customer[“address”+i]+”\n”; 

//这行代码读取了customer对象的属性address0, //address1,address2和address3,并将它们连起来

无类型对象
用{}创建无类型对象
var user = {
name:"Jerry",
colorArray:["red", "green", "black"],
hello:function(){
    alert("Hello, "+this.name);
}
}
user.name;
user["name"];
user.hello();
user.colorArray[0];

定义类
用定义函数的方式定义类 
function className(){ 
类成员及构造函数的定义, 
}

这里的className是一个函数,也是一个类。作为函数,可以理解为类的构造函数,执行初始化。

//当函数被当成构造函数使用时,使用类的命名规范
function Rectangle(w,h){
    this.width = w;
    this.height = h;
}
var rect1 = new Rectangle(2,4);
var rect2 = new Rectangle(8.5,11);

this的使用
JavaScript中的this 指针是一个动态变化的变量,它表明了当前运行该函数的对象。 
以下是它的4种使用情况:

情况一:纯粹的函数调用 
这是函数的最通常用法,属于全局性调用,因此this就代表全局对象Global。 
请看下面这段代码,它的运行结果是1。 
function test(){ 
this.x = 1; 
alert(this.x); 

test(); // 1,就等价于window.test() 
为了证明this就是全局对象,我对代码做一些改变: 
var x = 1; 
function test(){ 
alert(this.x); 

test(); // 1 
运行结果还是1。再变一下: 
var x = 1; 
function test(){ 
this.x = 0; 

test(); 
alert(x); //0 
 
情况二:作为对象方法的调用 
函数还可以作为某个对象的方法调用,这时this就指这个上级对象。 
function test(){ 
alert(this.x); 

var o = {}; 
o.x = 1; 
o.m = test; 
o.m(); // 1 
 
情况三 :作为构造函数调用 
所谓构造函数,就是通过这个函数生成一个新对象(object)。这时,this就指这个新对象。 
function test(){ 
this.x = 1; 

var o = new test(); 
alert(o.x); // 1 
运行结果为1。为了表明这时this不是全局对象,我对代码做一些改变: 
var x = 2; 
function test(){ 
this.x = 1; 

var o = new test(); 
alert(x); //2 
运行结果为2,表明全局变量x的值根本没变。

情况四 :apply调用 
apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是这第一个参数。 
var x = 0; 
function test(){ 
alert(this.x); 

var o={}; 
o.x = 1; 
o.m = test; 
o.m.apply(); //0 
apply()的参数为空时,默认调用全局对象。因此,这时的运行结果为0,证明this指的是全局对象。 
如果把最后一行代码修改为 
o.m.apply(o); //1 
运行结果就变成了1,证明了这时this代表的是对象o。

实例属性
function Rectangle(w,h){ 
this.width = w; 
}

这里的width为实例属性 
每个对象都拥有它的实例属性的一份单独拷贝。

实例方法
function Rectangle(w,h){ 
this.width = w; 
this.height = h; 
this.area = function(){ 
return this.width*this.height; 


var r = new Rectangle(8.5,11); 
var a = r.area(); 
//这个方法的定义很有效,但不是最优的; 
那么另外的方法是通过prototype属性来完成的

var Person=function(){};
Person.say=function(){
    console.log('I am a Person,I can say.')
};
Person.prototype.getName=function(name){
    console.log('My name is '+name);
}

以上的代码,实际上很简单,首先是定义了一个function,js里面像上面那样定义一个function实际上是定义了一个类,接下来,给这个类添加了一个say的方法,然后接着给这个类的prototype添加了一个getName的方法,所有的类都是会有一个prototype这样的属性,这个属性指向的是object。

Person.say();//I am a Person,I can say.
Person.getName('Carl');//报错
new Person().getName('Tom');//My name is Tom

实际上我们就看出来了,say方法是’ . ‘在类上面的,所以,它实际上是一个静态方法,那么当然是可以直接通过类进行访问的(这里的静态方法都是public的),所以第一段的第一句话是不会抱错的,而getName这个方法实际上是在prototype上面的,只有创建一个实例的情况下,才可以通过实例进行访问。

toString和valueOf
function MyClass(){
    this.id = 100;
    this.valueOf = function(){
      return 1;
  }
    this.toString = function(){
      return 2;
    }
}
var s = new MyClass();
var s1 = s + 10;  //s调用valueOf,返回1
alert(s1);  //11 
alert(s);  //2  调用toString
alert(s+3);//4  调用valueOf

【注意】当涉及到运算的时候,优先调用valueOf,找不到valueOf,才会调用toString,如果没有toString,就会调用父类中的toString方法,alert(s)就会返回[object Object]

Object类
JS中所有对象都继承自Object类 
通用的属性和方法: 
1. constructor属性(对应初始化对象的构造函数) 
var c = new Date(); 
c.constructor == Date; //true 
c.constructor -> 指向Date()函数。 
2. toString(); 
//转换成字符串。许多类重定义了toString()

构造函数返回对象
function Test(){
    this.age = 21;  
    //当返回函数后,this将失去引用,被抛弃,等待垃圾回收
    var id = 0;     //私有变量
    return function(){
        //返回后此处不能再访问this.age,因为this被抛弃
        return id++;
    };
}
var s = new Test(); //s得到的是return返回的函数
s;   //function()
alert(s.age);       //undefined
alert(s());         //调用return的函数

构造函数返回普通值
function Test(){
    this.age = 21;
    var id = 0;       //私有变量
    return this.age;
}
var p = new Test(); //得到Test对象,并不得到return的值.
alert(p.age);  //可以访问,因为本来就是Test对象
alert(Test()); 
//返回值仅在此情况下有用. 把Test()当作函数使用,
//输出返回的值.

原型(prototype)
原型与this定义成员的区别:

function A(){ this.x = 1;}
function B(){}; 
B.prototype.x = 1;//prototype属性为B增加了x属性

var a = new A(); //实例化一个对象
var b = new A();//每一个对象持有一个x

var c = new B();
var d = new B();//所有对象共享x
------------------------------
function A(){ this.x = 1;}
A.prototype.x = 2;
new A().x;  //1

prototype、proto和constructor的三角关系

function Foo(){
  this.b=3;
};
Foo.prototype.a = 1;
var f1 = new Foo;
var f2 = new Foo;
f1.a;//1
f2.a;//1
f1;//返回Foo { b=3,  a=1}
//原型对象有一个constructor属性,指向该原型对象对应的构造函数
Foo.prototype.constructor;//返回构造器Foo()
Foo.prototype.constructor ===Foo;//true
//实例对象有一个proto属性,指向该实例对象对应的原型对象
Foo.prototype == f1.__proto__;//返回原型对象prototype
Foo.prototype;//返回Foo { a=1}
来源:咸宁网站建设