javascript的类的学习笔记

js类的基本含义

我们知道,在js中,是没有类的概念的。类的所有实例对象都从同一个原型对象上继承属性,因此,原型对象是类的核心。

类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。———百度百科

早期的javascript需求都很简单,基本都是写成函数的,然后是面向过程的写法,后来慢慢的引入面向对象开发思想,再后来就慢慢写成 类。

在js中,写成类的本质基本都是 构造函数+原型。下面,就讨论一下js类的几种写法:

构造函数 法

/**
    * Person类:定义一个人,有name属性和getName方法
   */    <script>
        function Person(name){         
          this.name = name;     
              this.getName = function(){
                              return this.name;
            }
        }        //我们在这里实例化几个对象
        var p1 = new Person("trigkit4");    
           var p2 = new Person("mike");    
              console.log(p1 instanceof Person);//true
        console.log(p2 instanceof Person);//true
    </script>
由上面控制台输出结果可知,p1和p2的确是类Person的实例对象。instanceof操作符左边是待检测类的对象,右边是定义类的构造函数。这里,instanceof用来检测对象p1是否属于Person类。

这种方式的优点是:我们可以根据参数来构造不同的对象实例 ,缺点是每次构造实例对象时都会生成getName方法,造成了内存的浪费 。

我们可以用一个外部函数来代替类方法,达到了每个对象共享同一个方法。改写后的类如下:

//外部函数<script>
    function getName() { 
          return this.name;
    }    function Person(name)
    {        this.name = name;
           this.getName = getName;//
    }</script>

原型方式

<script>
    function Person(){};
    Person.prototype.name = "trigkit4";//类的属性都放在prototype上
    Person.prototype.getName = function(){        return " I'm " + this.name;
    }    var p1 = new Person();    var p2 = new Person();    console.log(p1.name);//trigkit4
    console.log(p2.getName());//I'm trigkit4</script>
原型方式的缺点就是不能通过参数来构造对象实例 (一般每个对象的属性是不相同的) ,优点是所有对象实例都共享getName方法(相对于构造函数方式),没有造成内存浪费 。

构造函数+原型方式

取前面两种的优点:

a、用构造函数来定义类属性(字段)。
b、用原型方式来定义类的方法。

<script>
    function Person(name){        this.name = name;
    }    //原型的特性可以让对象实例共享getName方法
    Person.prototype.getName = function(){        return " I'm " + this.name;
    }</script>

这样,我们就既可以构造不同属性的对象,也可以让对象实例共享方法,不会造成内存的浪费。

为了让js代码风格更紧凑,我们让prototype方法代码移到function Person的大括号内。

<script>
    function Person(name){    
       this.name = name;
        Person.prototype.getName = function(){
                    return this.name;
        }
    }    var p1 = new Person('trigkit4');  
     console.log(p1.getName());//trigkit4
     </script>

补充:

首先说说类,在一个类里我们会有以下的几个特征:
1. 公有方法
2. 私有方法
3. 属性
4. 私有变量
5. 析构函数
一、构造函数法

这是经典方法,也是教科书必教的方法。它用构造函数模拟"类",在其内部用this关键字指代实例对象。

  function Cat() {

    this.name = "大毛";

  }
生成实例的时候,使用new关键字。

  var cat1 = new Cat();

  alert(cat1.name); // 大毛
类的属性和方法,还可以定义在构造函数的prototype对象之上。

  Cat.prototype.makeSound = function(){

    alert("喵喵喵");

  }
关于这种方法的详细介绍,请看我写的系列文章《Javascript 面向对象编程》,这里就不多说了。它的主要缺点是,比较复杂,用到了this和prototype,编写和阅读都很费力。

二、Object.create()法

为了解决"构造函数法"的缺点,更方便地生成对象,Javascript的国际标准ECMAScript第五版(目前通行的是第三版),提出了一个新的方法Object.create()。

用这个方法,"类"就是一个对象,不是函数。

  var Cat = {

    name: "大毛",

    makeSound: function(){ alert("喵喵喵"); }

  };
然后,直接用Object.create()生成实例,不需要用到new。

  var cat1 = Object.create(Cat);

  alert(cat1.name); // 大毛

  cat1.makeSound(); // 喵喵喵
目前,各大浏览器的最新版本(包括IE9)都部署了这个方法。如果遇到老式浏览器,可以用下面的代码自行部署。

  if (!Object.create) {

    Object.create = function (o) {

       function F() {}

      F.prototype = o;

      return new F();

    };

  }
这种方法比"构造函数法"简单,但是不能实现私有属性和私有方法,实例对象之间也不能共享数据,对"类"的模拟不够全面。

三、极简主义法

荷兰程序员Gabor de Mooij提出了一种比Object.create()更好的新方法,他称这种方法为"极简主义法"(minimalist approach)。这也是我推荐的方法。

3.1 封装

这种方法不使用this和prototype,代码部署起来非常简单,这大概也是它被叫做"极简主义法"的原因。

首先,它也是用一个对象模拟"类"。在这个类里面,定义一个构造函数createNew(),用来生成实例。

  var Cat = {

    createNew: function(){

      // some code here

    }

  };
然后,在createNew()里面,定义一个实例对象,把这个实例对象作为返回值。

  var Cat = {

    createNew: function(){

      var cat = {};

      cat.name = "大毛";

      cat.makeSound = function(){ alert("喵喵喵"); };

      return cat;

    }

  };
使用的时候,调用createNew()方法,就可以得到实例对象。

  var cat1 = Cat.createNew();

  cat1.makeSound(); // 喵喵喵
这种方法的好处是,容易理解,结构清晰优雅,符合传统的"面向对象编程"的构造,因此可以方便地部署下面的特性。

3.2 继承

让一个类继承另一个类,实现起来很方便。只要在前者的createNew()方法中,调用后者的createNew()方法即可。

先定义一个Animal类。

  var Animal = {

    createNew: function(){

      var animal = {};

      animal.sleep = function(){ alert("睡懒觉"); };

      return animal;

    }

  };
然后,在Cat的createNew()方法中,调用Animal的createNew()方法。

  var Cat = {

    createNew: function(){

      var cat = Animal.createNew();

      cat.name = "大毛";

      cat.makeSound = function(){ alert("喵喵喵"); };

      return cat;

    }

  };
这样得到的Cat实例,就会同时继承Cat类和Animal类。

  var cat1 = Cat.createNew();

  cat1.sleep(); // 睡懒觉
3.3 私有属性和私有方法

在createNew()方法中,只要不是定义在cat对象上的方法和属性,都是私有的。

  var Cat = {

    createNew: function(){

      var cat = {};

      var sound = "喵喵喵";

      cat.makeSound = function(){ alert(sound); };

      return cat;

    }

  };
上例的内部变量sound,外部无法读取,只有通过cat的公有方法makeSound()来读取。

  var cat1 = Cat.createNew();

  alert(cat1.sound); // undefined
3.4 数据共享

有时候,我们需要所有实例对象,能够读写同一项内部数据。这个时候,只要把这个内部数据,封装在类对象的里面、createNew()方法的外面即可。

  var Cat = {

    sound : "喵喵喵",

    createNew: function(){

      var cat = {};

      cat.makeSound = function(){ alert(Cat.sound); };

      cat.changeSound = function(x){ Cat.sound = x; };

      return cat;

    }

  };
然后,生成两个实例对象:

  var cat1 = Cat.createNew();

  var cat2 = Cat.createNew();

  cat1.makeSound(); // 喵喵喵
这时,如果有一个实例对象,修改了共享的数据,另一个实例对象也会受到影响。

  cat2.changeSound("啦啦啦");

  cat1.makeSound(); // 啦啦啦

时间: 2024-10-31 17:14:52

javascript的类的学习笔记的相关文章

《JavaScript高级编程》学习笔记之object和array引用类型_javascript技巧

本文给大家分享我的javascript高级编程学习笔记之object和array引用类型,涉及到javascript引用类型相关知识,大家一起看看把. 1. Object类型      大多数引用类型值都是Object类型的实例:而且Object也是ECMAScript中使用最多的一个类型.      创建Object实例有如下两种方式: new操作符后跟Object构造函数: var person=new Object( ); person.name="webb"; person.a

《JavaScript高级程序设计》学习笔记

系统学习JS, 从<JavaScript高级程序设计>入门,通过学习jQuery或者angularJS源码来进阶. 第1章 JavaScript简介 1.JS问世的目的是处理以前由服务器端语言(如Perl)负责的一些输入验证操作, 由Netscape主导开发,那时候微软的IE还不能独领风骚.最初叫做LiveScript,当时媒体热炒Java,于是改名为JavaScript. JavaScript和ECMAScript通常指同一门语言,但是,JavaScript是ECMA-262标准的实现和扩展

javascript类型系统 Array对象学习笔记_javascript技巧

       数组是一组按序排列的值,相对地,对象的属性名称是无序的.从本质上讲,数组使用数字作为查找键,而对象拥有用户自定义的属性名.javascript没有真正的关联数组,但对象可用于实现关联的功能 Array()仅仅是一种特殊类型的Object(),也就是说,Array()实例基本上是拥有一些额外功能的Object()实例.数组可以保存任何类型的值,这些值可以随时更新或删除,且数组的大小是动态调整的 一.数组创建 与Javascript中的大多数对象一样,可以使用new操作符连同Array

JavaScript高级程序设计 DOM学习笔记_javascript技巧

第十章 DOM DOM是针对XML和HTML文档的一个API:即规定了实现文本节点操控的属性.方法,具体实现由各自浏览器实现. 1. 节点层次 1) 文档节点:document,每个文档的根节点. 2) 文档元素:即<html>元素,文档最外层元素,文档节点第一个子节点. 3) Node类型: ①Node是DOM中各种节点类型的基类型,共享相同的基本属性和方法. □ Node.Element_NODE(1); □ Node.ATTRIBUTE_NODE(2); □ Node.TEXT_NODE

javascript中类的定义及其方式(《javascript高级程序设计》学习笔记)_js面向对象

关于javascript中类的继承可以参考阮一峰的Blog<Javascript继承机制的设计思想>,说的很透. 一.在javascript中实例化遇到的问题: 下面用<javascript高级程序设计>中的例子来做说明,假如现在定义了一个car的对象,它是Object类的实例.像下面这样的: 复制代码 代码如下: var oCar=new Object(); oCar.color = "red"; oCar.doors = 4; oCar.mpg = 23;

javascript类型系统 Window对象学习笔记_javascript技巧

window对象是Web浏览器中javascript的一个终极兜底儿对象,在作用域中处于最末端,是一个包含所有对象的对象.所有在全局作用域中定义的属性和函数都是window对象的属性 var myStringVar = 'myString'; var myFunctionVar = function(){}; console.log('myStringVar' in window);//true console.log('myFunctionVar' in window);//true   1.

javascript入门教程之学习笔记

呵呵,,好久没写文章了,,近来接触js比较多久顺便写个与js相关的文吧. 嗯,今天就谢谢与变量相关的东东吧,变量这东西只要你是敲代码的天天都得接触呢. 有人说变量有啥好写的?我不会告诉你Javascript里的变量很奇怪呢,没好好学一遍真的会被搞晕掉的. 好,先拿一篇已存的文,个人感觉写的还可以. 1.变量类型:基本类型和引用类型     在js 中,基本类型:Number,Boolen,null,String,Underfined 存放在栈内存中,数据长度是固定的.     而引用类型,Obj

JavaScript高级程序设计 事件学习笔记_javascript技巧

第12章 事件 1.事件流 1.1事件冒泡(IE事件流) □事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接受,然后逐级向上传播到较为不具体的节点(文档). □所有浏览器均支持事件冒泡.Firefox.chrome.safari将事件一直冒泡到window对象. 1.2事件捕获(Netscape事件流) □不太具体的节点更早收到事件,而具体的节点最后收到节点. □Safari.chrome.Opera.firefox支持,但从window对象

Java编程中的vector类用法学习笔记_java

java.util.vector提供了向量类(vector)以实现类似动态数组的功能.在Java语言中没有指针的概念,但如果正确灵活地使用指针又确实可以大大提高程序的质量.比如在c,c++中所谓的"动态数组"一般都由指针来实现.为了弥补这个缺点,Java提供了丰富的类库来方便编程者使用,vector类便是其中之一.事实上,灵活使用数组也可以完成向量类的功能,但向量类中提供大量的方法大大方便了用户的使用. 创建了一个向量类的对象后,可以往其中随意插入不同类的对象,即不需顾及类型也不需预先