谈谈JavaScript里对象的创建和继承(一)

来源:互联网 发布:海关数据编码查询 编辑:程序博客网 时间:2024/05/16 15:52

        我是JavaScript小菜一枚,最近在苦学JavaScript,其中有关面向对象的程序设计这块,发现创建对象与继承是最重点也是最难点,所以写下这篇博客记录一下我对这两件事情的理解,希望对我自己以后的学习有帮助。第一次写博客,新手哈~

一、 理解对象。

        对象对JavaScript就好比类对C++。面向对象的程序语言设计都会有类这个概念,而在JavaScript里,对应的就是对象了。我对对象的理解是这样的,对象是一个有属性有方法的东西。它叫做object,其属性就是其内部定义的一些数据,类型可以是基本类型number、string等,也可以是引用类型Array、Object等,这些数据是可以拿来用的;其方法就是一些行为,一般都是一个function,alert一些东西啊,return个什么啊,或者搞一些需要的行为,即兴来个算法表演也是可以的。对象就带着这些东西闯天下。下面我们就来写一个对象看看吧。

var person = new Object;person.name = "SHE";person.age = "18";person.color = [pink, orange, green];person.sayName = function(){   alert(this.name);};
        这里就定义了一个对象,添加了三个属性(name、age、color),其中前两个是基本类型的,后一个是引用类型的,以及添加了一个sayName方法,这个方法就是把person下的name给alert出来的动作。而使用对象字面量语法还可以这样写:
var person = {  name: "SHE",  age: 18,  color: [pink, orange, green],  sayName: function(){    alert(this.name);  }};

二、 创建对象

        其实以上就列举了两种创建对象的方法,先new一个object然后使用.(点)符号来给属性和方法赋值,或者直接使用对象字面量的方法来创建。但是如果你学过C++,你就会知道创建对象还有更厉害的方式(为了区分上述对象中的方法,所以这里都使用方式一词),这些方式的产生,都是由于我们不可能只遇到小儿科的对象。对象一复杂起来,那可不得了了,需要我们学习更多新的更有效率的方式来创建对象。先来个高能小预警,列举一下我们要学习到的这几种方式:①工厂模式②构造函数模式③原型模式④组合使用构造函数和原型模式⑤动态原型模式⑥寄生构造函数模式⑦稳妥构造函数模式。

        好吧看着好多好晕啊。就是因为将来你遇到的对象要多复杂就有多复杂,所以才需要那么多形式的创建方式,来针对不同的对象,写最有效的代码。别嫌烦,一个个看,有重点地仔细看。


2.1 工厂模式

        直接上例子是不是更简单快捷。先看:

function createPerson(name, age, job){  var obj = new Object();  obj.name = name;  obj.age = age;  obj.job = job;  obj.sayName = function(){    alert(this.name);  };  return obj;}var person1 = createPerson("SHE", 18, "singer");var person2 = createPerson("Lingo", 18, "rocker");

        上面的函数createPerson()能够根据接受的参数来构建一个包含所有必要信息的Person对象,其实它只是把我们在第一节里new的对象封装进了一个函数里,好处就是我们可以一直调用它来给我们创建多个具有相同属性和方法的对象,不用一个个new了。不过缺点是我们不知道这个对象的类型,就是说我们识别不了它,不知道它是哪来的,也不知道它爸爸是谁,它儿子是谁云云。


2.2 构造函数模式

        学过C++的同学应该很熟悉这个吧。不过在JavaScript里,构造函数还和C++不太一样,它长得有点儿像工厂模式,但是删减了一些东西,例子如下:

function Person(name, age, job){  this.name = name;  this.age = age;  this.job = job;  this.sayName = function(){    alert(this.name);  };  return obj;}var person1 = new Person("SHE", 18, "singer");var person2 = new Person("Lingo", 18, "rocker");
        工厂模式和构造函数模式的区别在于:

①Person()中没有显式地创建对象;

②直接将属性和方法赋给了this对象;

③没有return语句;

④创建对象的新实例时,必须使用new操作符。

  
        在用构造函数创建对象的时候,有一个不成文的规定,就是将函数名以大写开头(非构造函数以小写字母开头)。这个做法能为我们区分其他函数与构造函数,在new对象的时候能够保持一致性,也更具有可读性了。因为你知道,构造函数也是普通函数,只是能够创建对象而已。

        我们在用new创建了Person的新实例以后,在我们看不见的后台,其实是经历以下四个步骤:

①创建一个新对象;

②将构造函数的作用域赋给新对象(因此this就指向了这个新对象);

③执行构造函数中的代码(为这个新对象添加属性和方法);

④返回新对象。

       我们对应着上面的区别可以知道,构造函数在创建新实例的时候,已经使用new操作符在后台做了工厂模式内部做的事情了,所以它们是异曲同工的。但是我们在这里要提到构造函数的好处,那就是它既可以用new来创建新实例,也可以当做普通函数来用,不仅如此,新实例们还各自拥有一个constructor(构造函数)属性,这个属性指向Person。也就是说,我们可以用constructor来识别对象类型,这点比工厂模式强。而且我们也可以通过instanceof操作符来识别对象类型。用法如下:

alert(person1.constructor == Person);  //truealert(person2.constructor == Person);  //true
alert(person1 instanceof Object);  //truealert(person1 instanceof Person);  //truealert(person2 instanceof Object);  //truealert(person2 instanceof Person);  //true

        在这里,person1和person2也同时是Object的实例,因为所有对象都继承自Object。

        不过构造函数有一个缺点,就是在创建新实例时,内部的方法在每次创建时都会重新创建一次,就是说每个实例里的方法都是不共享的,各干各的。如果我们需要的这个方法在每个实例中完成的事情都是一样的,这种创建方式就比较没有必要,效率也会比较差,这时最好是能找到一种可以共享方法的方式。


2.3 原型模式

        其实我们创建的每个函数都有一个叫prototype(原型)属性,这个属性是一个指针,指向一个对象。指向的这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。也就是说,我现在要创建一个对象,它带着这样一个东西,里面存的是共享的属性和方法,以后创建的每一个实例,都自带这个东西,而且都长得一样,自己想改的话就另外讨论。好我们先看例子吧:

function Person(){}Person.prototype.name = "SHE";Person.prototype.age = "18";Person.prototype.job = "singer";Person.prototype.sayName = function(){  alert(this.name);};var person1 = new Person();person1.sayName();  //"SHE"var person2 = new Person();person2.sayName();  //"SHE"alert(person1.sayName == person2.sayName);  //true


0 0
原创粉丝点击