• Javascript 定义类或对象的方法总结


    Javascript 从名字上听起来跟JAVA有着联系,但其实却是两门根本不同的语言。在Java中定义类是轻而易举的事情,但是要在JavaScript中定义一个好的对象却是要花点心思。本文介绍几种方法,并比较他们的优劣。

    1、 工厂方式

    这种方式可能是我们最容易想到的了,见代码:

    var employee = new Object;
    employee.name
    = "Tim";
    employee.age
    = 24;
    employee.getName
    = function(){
    alert(
    this.name);
    }

    这段代码创建了一个employee 对象,并设置了他的几个属性:name ,age 。而getName这个属性其实是一个指针,他指向一个函数,因而成为该对象的一个方法。使用这种方式可以创建一个对象,但是如果我们需要创建多个对象呢?总不能类似的再敲几片吧。我们把他封装一下,写出一个方法:

    function createEmployee(names,ages){
    var employee = new Object;
    employee.name
    = names;
    employee.age
    = ages;
    employee.getName
    = function(){
    alert(
    this.name);
    }
    return employee;
    }
    var employee1 = createEmployee("Tim",24);
    var employee2 = createEmployee("Tom",22);
    employee1.getName();
    employee2.getName();

    但是你会发现其实我们在创建两个对象的时候,创建了两个getName()方法,其实每个对象共享一个getName()就可以了,浪费内存空间。
    2、构造函数方式

    function Employee( names,ages ){
    this.name = names;
    this.age = ages;
    this.getName= function(){
    alert(
    this.name);
    }
    }
    var employee1 = new Employee("Tim",24);
    var employee2 = new Employee("Tom",22);
    employee1.getName();
    employee2.getName();

    这种方式不像第一种方式需要在函数内部创建对象,而是使用了this关键字。然后用new来创建对象,这跟Java的非常相像了。但是他同样跟工厂模式一样会重复生成函数。
    3、原型方式

    function employee(){

    }
    employee.prototype.name
    = "Tim";
    employee.prototype.age
    = 24;
    employee.prototype.getName
    = function (){
    alert(
    this.name );
    };
    var employee1 = new employee();
    var employee2 = new employee();

    使用这种方式很好的解决了前两种方法的问题,但是新的问题有来了,如果这样:

    function employee(){

    }
    employee.prototype.name
    = "Tim";
    employee.prototype.age
    = 24;
    employee.prototype.friends
    = new Array( "Jack", "Tom" );
    employee.prototype.getName
    = function (){
    alert(
    this.name );
    };
    var employee1 = new employee();
    var employee2 = new employee();
    employee1.friends.push(
    "Tina" );
    alert(employee1.friends);
    alert(employee2.friends);

    这两个对象都是输出“Jack,Tom,Tina”。这是因为friends是指向Array对象的指针,两个对象都指向同一个Array,因而修改一个对象的friends,另一个对象也是修改。这肯定不是我们想要的。
    4、混合构造函数/原型模式

    function Employee( names,ages ){
    this.name = names;
    this.age = ages;
    this.friends = new Array( "Jack", "Tom" );
    }
    Employee.prototype.getName
    = function (){
    alert(
    this.name );
    };
    var employee1 = new Employee("Tim",24);
    var employee2 = new Employee("Tom",22);
    employee1.friends.push(
    "Tina" );
    alert(employee1.friends);
    //输出“Jack,Tom,Tina”
    alert(employee2.friends); //输出“Jack,Tom”

    结合构造和原型两种方式,彻底解决了上诉两种情况。他只创建一个getName实例,不会浪费内存,而且在修改friends属性时,也不会修改其他对象的friends属性。
    5、动态原型方法

    function Employee( names,ages ){
    this.name = names;
    this.age = ages;
    this.friends = new Array( "Jack", "Tom" );
    if( typeof Employee._initialized == "undefined" ){
    Employee.prototype.getName
    = function(){
    alert(
    this.name );
    }
    Employee._initialized
    = true;
    }
    }

    使用这种方式,是不是觉得更像Java的CLASS编写方式了?
    总结:通过比较,明显可以看出“构造函数/原型模式”和“动态原型”的优势,建议编程时采用。

  • 相关阅读:
    java.lang.ExceptionInInitializerError异常分析
    项目中碰到的ExceptionInInitializerError异常
    获取全局上下文(getApplicationContext)_创建Shared Preference工具类_实现自动登录
    IntelliJ Idea 常用快捷键列表
    Qt 创建圆角、无边框、有阴影、可拖动的窗口 good
    去掉 Windows 中控件的虚线框(当当 element == QStyle::PE_FrameFocusRect 时,直接返回,不绘制虚线框)
    Qt 显示 GIF
    C++ 查看预处理后的源文件(查看真实代码)
    数据库访问工具 DBUtl(公孙二狗)
    Tornado
  • 原文地址:https://www.cnblogs.com/codebean/p/2059914.html
Copyright © 2020-2023  润新知