js中利用prototype给类添加方法

2020-05-20 22:30:14

参考地址 js中利用prototype给类添加方法

1.如何定义一个简单的类? 
以下是一个没有任何属性和方法的类的定义:

function MyClass(){};
  • 1

你可能会想,这不就是个简单的函数声明?没错,这个函数就是一个类的定义的实现。如何使用这个类呢?看下面的代码:var cls1 = new MyClass();

这样,利用new就可以生成MyClass的一个实例了。所以在js中可以说函数就是类,类就是函数。

2.给类增加属性和方法

function MyClass(name,age){this.name = name;this.age = age;}var cls1 = new MyClass("lily",18);alert(cls1.name);
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

从上面的代码可以看出,在函数内使用this就能给函数本身增加属性值。而在上面的代码中就给myClass函数增加了name和age属性。 
同样,还可以利用this给这个类增加一个 toString 方法,代码如下:

function MyClass(name,age){this.name = name;this.age = age;this.toString() = function(){alert(this.name +":"+ this.age);};}var cls1 = new MyClass("liming",10);cls1.toString();
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

我们已经成功的给MyClass增加了toString方法。另外也可以用以下代码来添加方法:

function MyClass(name,age){this.name = name;this.age = age;}var cls1 = new MyClass("liming",10);cls1.toString() =  function(){alert(this.name +":"+ this.age);};cls1.toString(); // [liming:10]var cls2 = new MyClass("zhang",10);cls2.toString(); //报错
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

虽然这样也能给这个类添加一个方法,但这种方式只是给cls1这个实例增加了方法,并未给MyClass本身增加方法。 
cls2并不存在toString方法。

3.引出prototype 
从上面我们已经知道要给MyClss类的本身增加方法,需要讲方法定义在MyClass这个函数内部,这样的话,每声明一个新的实例,就会将MyClass本身复制一遍,这显然不是最优的做法。

既然不能将一个类(函数)所包含的方法都定义在函数的内部,那么,如何来给一个类添加方法呢?这就需要用到函数的prototype属性了。 
每一个函数都会包含一个prototype属性,这个属性指向了一个prototype对象,我们可以指定函数对应的prototype对象。如果不指定,则函数的prototype属性将指向一个默认的prototype对象,并且次默认的prototype对象的constructor属性又会指向该函数。

当用构造函数创建一个新的对象时,新的对象会获取构造函数的prototype属性所指向的prototype对象的所有属性和方法,这样一来,构造函数对应的prototype对象所做的任何操作都会反映到它所生成的对象上,所有的这些对象将共享与构造函数对应的prototype对象的属性和方法。

虽然新创建的对象可以使用它的构造函数所指向的prototype对象的属性和方法,但不能像构造函数那样直接调用prototype对象(对象没有prototype属性)。

简而言之,就是如果我们使用函数的prototype对象来给函数添加方法,那么在创建一个新的对象的时候,并不会复制这个函数的所有方法,而是指向了这函数的所有方法。 
具体看下面的代码:

function MyClass(name,age){this.name = name;this.age = age;}MyClass.prototype.toString = function(){//}var cls1 = new MyClass("liming",10);cls1.toString(); //var cls2 = new MyClass("zhang",10);cls2.toString();
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

如果要加入多个方法,也可以使用下面的方式:

function MyClass(name,age){this.name = name;this.age = age;}MyClass.prototype = {toString:function(){//},sayHellow:function(){//}};
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

这就是js中给类添加方法的实现,它是利用prototype来实现封装的。


  • 2018-04-18 15:56:00

    linux下如何实现mysql数据库每天自动备份定时备份

    备份是容灾的基础,是指为防止系统出现操作失误或系统故障导致数据丢失,而将全部或部分数据集合从应用主机的硬盘或阵列复制到其它的存储介质的过程。而对于一些网站、系统来说,数据库就是一切,所以做好数据库的备份是至关重要的!

  • 2018-04-18 20:44:19

    $(...).live is not a function

    jquery中的live()方法在jquery1.9及以上的版本中已被废弃了,如果使用,会抛出TypeError: $(...).live is not a function错误。

  • 2018-04-19 16:31:03

    mysql双机热备的实现

    准备两个mysql,A和B,A为主,B为从。前提是这两个数据库现在的表结构要一模一样,否则不成功。这个要锁表处理了。

  • 2018-04-19 16:32:47

    mysql binlog_do_db参数设置的坑

    在配置文件中想当然地配置成binlog_do_db=test,xx,jj,以为是三个库。结果无论什么操作都没有binlog产生

  • 2018-04-20 02:11:58

    Android中finish掉其它的Activity

    在Android开发时,一般情况下我们如果需要关掉当前Activity非常容易,只需要一行代码 this.finish;即可。 那么,如果是想要在当前Activity中关掉其它的Activity应该怎么实现呢? 比如更改了某个设定,程序需要重新运行并加载新的配置文件,就要用到restart或finish让程序重启。

  • 2018-04-20 09:12:07

    如何在 7 分钟内黑掉 40 家网站?

    去年夏天我开始学习信息安全与黑客技术。在过去的一年中,我通过参加各种战争游戏、夺旗以及渗透测试模拟,不断提高我的黑客技术,还学习了很多关于“如何让计算机偏离其预期行为”的新技术。

  • 2018-04-25 00:46:48

    Android开发笔记——SharedPreferences 存储实体类以及任意类型

    我们常常要用到保存数据,Android中常用的存储方式有SQLite,sharedPreferences 等,当然也有各自的应用场景,前者适用于保存较多数据的情形,后者责倾向于保存用户偏好设置比如某个checkbox的选择状态,用户登录的状态等等,都是以键值对的形式进行的文件读取,可以存储String,int,booean等一些基本数据类型等等。