• JS面向对象(封装,继承)


    在六月份找工作中,被问的最多的问题就是: js面向对象,继承,封装,原型链这些,你了解多少?

    额,,,我怎么回答呢, 只能说,了解一些,不多不少,哈哈哈哈,当然,这是玩笑话。

    不过之前学过java,来理解这些还是很容易的。

    所以趁着自己空闲的时间,理一理,,这些,,

    一、封装

    1.原始方法

     1 // 通过new关键字生成一个对象,然后根据javascript是动态语言的特性来添加属性和方法,构造一个对象。其中this表示调用该方法的对象。
     2     var obj = new Object();
     3     obj.name = 'jessie';
     4     obj.age = 22;
     5     obj.showName = function(){
     6         alert(this.name);
     7     };
     8     obj.showAge = function(){
     9         alert(this.age);
    10     }
    11     obj.showName(); //jessie
    12     obj.showAge(); // 22
    13     // 这种方式的问题是如果需要多次创建对象,那么需要重复代码多次,不利于代码的复用。

    2.工厂模式

     1 function createBlog(name, url) {
     2         var obj = new Object();
     3         obj.name = name;
     4         obj.url = url;
     5         obj.sayName = function(){
     6             alert(this.name);
     7         };
     8         obj.sayUrl = function() {
     9             alert(this.url);
    10         };
    11         return obj;
    12     }
    13     var blog1 = createBlog('jessie', 'http://www.cnblogs.com/xiayu25/');
    14     var blog2 = createBlog('cuit', 'http://www.cuit.edu.cn');
    15     blog1.sayName(); // jessie
    16     blog1.sayUrl(); // http://www.cnblogs.com/xiayu25/
    17     blog2.sayName(); // cuit
    18     blog2.sayUrl(); // http://www.cuit.edu.cn
    19 
    20     // 通过定义几个函数的对象,解决了不同对象持有函数对象的私有属性问题。
    21     // 现在所有对象的方法都持有上面两个函数的引用,
    22     // 但这么一来,对象的函数又和对象相互独立了,这和面向对象中持有方法属于与特定类的思想不符。
    23     // 可以看到工厂模式的实现方法非常简单,解决了创建多个相似对象的问题,
    24     // 但是工厂模式却无从识别对象的类型,因为全部都是Object,不像Date、Array等,因此出现了构造函数模式。

    3.构造函数模式

     1 function Blog(name, url){
     2         //var this=new Object();  //系统模拟创建对象
     3         this.name = name;
     4         this.url = url;
     5         this.sayName = function(){
     6             alert(this.name);
     7         };
     8         this.sayUrl = function(){
     9             alert(this.url);
    10         };
    11     }
    12     var blog1 = Blog('jessie', 'http://www.cnblogs.com/xiayu25/');
    13     var blog2 = Blog('cuit', 'http://www.cuit.edu.cn');
    14     blog1.sayName(); // jessie
    15     blog1.sayUrl(); // http://www.cnblogs.com/xiayu25/
    16     blog2.sayName(); // cuit
    17     blog2.sayUrl(); // http://www.cuit.edu.cn
    18     // 这个例子与工厂模式中除了函数名不同以外,细心的童鞋应该发现许多不同之处:
    19     // 函数名首写字母为大写(虽然标准没有严格规定首写字母为大写,但按照惯例,构造函数的首写字母用大写)
    20     // 没有显示的创建对象
    21     // 直接将属性和方法赋值给了this对象
    22     // 没有return语句
    23     // 使用new创建对象
    24     // 能够识别对象(这正是构造函数模式胜于工厂模式的地方)
    25     // 构造函数虽然好用,但也并非没有缺点
    26     // 构造函数的方式与工厂加工方式一样,会为每个对象创建独享的函数对象,
    27     // 当然也可以将这些函数对象定义在构造函数外面,这样又有了对象和方法相互独立的问题

    4.原型模式

     1 function Blog() {}
     2     Blog.prototype.name = 'jessie';
     3     Blog.prototype.url = 'http://www.cnblogs.com/xiayu25/';
     4     Blog.prototype.friend = ['fr1', 'fr2', 'fr3', 'fr4'];
     5     Blog.prototype.alertInfo = function() {
     6         alert(this.name + this.url + this.friend );
     7     };
     8     
     9     var blog1 = new Blog(), blog2 = new Blog();
    10     blog1.alertInfo();  // jessiehttp://www.cnblogs.com/xiayu25/fr1,fr2,fr3,fr4
    11     blog2.alertInfo();  // jessiehttp://www.cnblogs.com/xiayu25/fr1,fr2,fr3,fr4
    12     blog1.name = 'test1';
    13     blog1.url = 'http://***.com';
    14     blog1.friend.pop();
    15     blog2.name = 'test2';
    16     blog2.url = 'http://+++.com';
    17     blog1.alertInfo();  // test1http://***.comfr1,fr2,fr3
    18     blog2.alertInfo();  // test2http://+++.comfr1,fr2,fr3
    19     // 上面的代码通过blog1向blog1的属性friend添加元素时,
    20     // blog2的friend属性的元素也跟着受影响,原因是在于blog1和blog2对象的friend属性引用的是同一个Array
    21     // 对象,那么改变这个Array对象,另一个引用Array对象的属性自然也会受到影响

    5.混合模式(原型模式 + 构造函数模式)

     1 function Blog(name, url, friend) {
     2         this.name = name;
     3         this.url = url;
     4         this.friend = friend;
     5     }
     6 
     7     Blog.prototype.alertInfo = function() {
     8         alert(this.name + this.url + this.friend);
     9     };
    10 
    11     var blog1 = new Blog('jessie', 'http://www.cnblogs.com/xiayu25/', ['fr1', 'fr2', 'fr3']),
    12             blog2 = new Blog('cuit', 'http://www.cuit.edu.cn', ['a', 'b']);
    13 
    14     blog1.friend.pop();
    15     blog1.alertInfo();  // jessiehttp://www.cnblogs.com/xiayu25/fr1,fr2
    16     blog2.alertInfo();  // cuithttp://www.cuit.edu.cna,b
    17 
    18     //属性私有后,改变各自的属性不会影响别的对象。
    19     // 同时,方法也是由各个对象共享的。在语义上,这符合了面向对象编程的要求。

    6.动态原型模式

    动态原型模式将所有信息封装在了构造函数中,而通过构造函数中初始化原型(仅第一个对象实例化时初始化原型),这个可以通过判断该方法是否有效而选择是否需要初始化原型。

     1 function Blog(name, url) {
     2         this.name = name;
     3         this.url = url;
     4 
     5         if (typeof this.alertInfo != 'function') {
     6             // 这段代码只执行了一次
     7             alert('exe time');
     8             Blog.prototype.alertInfo = function() {
     9                 alert(thia.name + this.url);
    10             }
    11         }
    12     }
    13 
    14     var blog1 = new Blog('jessie', 'http://www.cnblogs.com/xiayu25/'),
    15             blog2 = new Blog('cuit', 'http://www.cuit.edu.cn');
    16     // 可以看到上面的例子中只弹出一次窗,'exe time',即当blog1初始化时,
    17     // 这样做blog2就不在需要初始化原型,对于使用这种模式创建对象,可以算是perfect了。

    二、继承(主要是方法的继承和属性的继承)

     1 function person(name, sex){
     2         this.name=name;
     3         this.sex=sex;
     4     }
     5     person.prototype.showName=function(){
     6         alert(this.name);
     7     };
     8     person.prototype.showSex=function(){
     9         alert(this.sex);
    10     };
    11 
    12     function worker(name,sex,job){
    13         person.call(this,name,sex);//构造函数伪装   调用父级的构造函数--为了继承属性
    14         this.job=job;
    15     }
    16     //原型链  通过原型来继承父级的方法
    17     for(attr in person.prototype){
    18         worker.prototype[attr]=person.prototype[attr];
    19     }
    20     worker.prototype.showJob=function(){
    21         alert(this.job);
    22     };
    23 
    24     var op=new person('blue','女');
    25     var ow=new worker('blue','女','程序员');
    26     op.showName();  //blue
    27     op.showSex();  //
    28     ow.showName();  //blue
    29     ow.showSex();  //
    30     ow.showJob();  //程序员
    31 
    32     //继承的好处:父类新加的功能,子类也具备该功能,子类新加的功能不会影响父类的功能
  • 相关阅读:
    js判断undefined类型
    【转】 C#操作FTP
    FTP
    Failed to execute request because the App-Domain could not be created. Error: 0x80070002 系统找不到指定的文件。
    [转]C# 安装与部署
    ASP.NET 实现重启系统或关机
    ORA-00257: archiver error. Connect internal only, until freed 错误的处理方法
    C#取整函数Math.Round、Math.Ceiling和Math.Floor
    Oracle 更改字符集 更改后之前的中文全成乱码了
    oracle
  • 原文地址:https://www.cnblogs.com/xiayu25/p/7105739.html
Copyright © 2020-2023  润新知