JS的面向对象

对象是什么

对象是一种复合数据类型,它们将多个数据值集中在一个单元内,而且允许使用名字来存取这些值。对象的另一种解释是:它是一个无序的属性的集合,每个属性都有自己的名字和值。存储在对象中已命名的值既可以是数字和字符串这样的原始值,也可以是对象。

对象的创建

常用的有三种方式:
一、直接创建法:
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}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值