有关javaScript面向对象和原型笔记


javaScript是一种比较特殊的语言,ECMAScript中没有类的概念,跟其他面向对象的语言有一定的区别,它的对象也与基于类的语言中的对象有所不同,严格来说,javascript对象是一组没有特定顺序的值,对象的每个属性或方法都有一个名字,而每个名字都映射到一个值。每个对象都是基于一个引用类型的创建的。


创建自定义对象的最简单的方式就是创建一个Object的实例,然后再为其添加属性和方法,如:

var box = new Object();        //创建对象
box.name1 = 'Lee';                    //添加属性
box.age = 100;                        //
box.run = function () {
    return this.name1 + this.age       //this表示当前作用域下对象


不足:使用同一个接口创建很多对象,会产生很多重复代码。


工厂模式:

在ECMAScript中无法创建类,开发人员就想出了另外一种方法,用一种函数来封装以特定接口创建对象的细节,如:

 

   function createPerson(name,age,job){
        var o = new Object();
        o.name = name;
        o.age = age;
        o.job = job;
        o.sayName = function(){
            alert(this.name);
        }
        return o;
    }
    var person1 = createPerson('lilei',29,'Software Engineer');
    var person2 = createPerson('Greg',27,'Doctor');
    person1.sayName();
    person2.sayName();
    alert(typeof person1);
    alert(typeof person2);


函数creatPerson()能够根据接受的参数来构建一个包含所有必要信息的Person对象,可以无数次低调用这个函数,而每次它都返回一个包含三个属性的一个方法的对象。工厂模式虽然解决了创建多个类型对象的问题,但却没有解决对象识别的问题。

构造函数模式

function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function(){
            alert(this.name);
        };
    }
    var person1 = new Person('lilei',29,'Software Engineer');
    var person2 =new Person('Greg',27,'Doctor');
    person1.sayName();
    person2.sayName();
    alert( person1 instanceof Object); 
    alert( person2 instanceof Person);
 


在这个例子当中,Person()函数取代了createPerson()函数。同时注意到跟createPerson()函数的区别:

没有显式地创建对象;

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

没有return 语句;

构成方法首个字母大写;

构造函数的的问题也有,就是每个方法都要在每个实例上重新创建一遍,

组合使用构造函数模式和原型模式

创建自定义类型常见的方式是组合使用构造函数模式和原型模式。构造函数模式用于定义实例属性,而原型模式用定义方法和共享属性,从而每个实例都会有 自己的一份实例属性的副本,但同时又共享着对方的方法的引用,

function Person(name,age,job){
    this.name =name;
    this.age = age;
    this.friends = ["Shelpy","Court"];
    }
    Person.prototype = {
    constructor:Person,
    sayName:function(){
    alert(this.name)
    }
    }
    var person1 = new Person('lilei',29,'Software Engineer');
    var person2 = new Person('Greg',27,'Doctor');
    person1.friends.push("Van");
    alert(person1.friends);
    alert(person2.friends);
    alert(person1.friends === person2.friends);
    alert(person1.sayName === person2.sayName);

      在这个例子中,实例属性都是在构造函数中定义的,而由所有实例共享的属性consructor和方法sayName()则是在原型中定义的,当修改了person1.friends时,并不会影响到person2,.friends,因为它们引用了不同的数组。


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。