zoukankan      html  css  js  c++  java
  • JavaScript类的写法(一)

    转自:http://segmentfault.com/a/1190000000725051

    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>
    

    在这里,我们需要知道的几种定义类的方法,除了上面的构造函数外,还有:

    Object.create()方法

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

     var Person = {
            name : "trigkit4",
            age : 21,
            run:  function(){
                alert("I like running");
            }
        }
    

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

    var p1 = Object.create(Person);
        alert(p1.age);//21
        p1.run();//I like running
    

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

    createNew()方法

    这种方法不需要用到this和prototype,其做法是用对象来模拟一个类,然后在类里面定义一个构造函数createNew(),然后在createNew()里面定义实例对象,把这个实例对象作为返回值。

    <script>
        var Person = {
    
            createNew : function () {
                var person = {};
                person.name = "trigkit4";
                person.run = function(){
                    alert("I like running");
                };
                return person;
            }
    
        }
    </script>
    

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

     var p1 = Person.createNew();
        p1.run();//I like running
    

    这种写法其实和对象字面量的写法是很类似的,只不过一个是逗号分隔,一个是分号分隔。

  • 相关阅读:
    scons配置文件
    与冯大辉谈数据库架构(InfoQ)
    7 Habits of Highly Effective Program Managers
    开心农场的架构
    二级下拉菜单被遮住,css设置zindex在ie下没作用的问题解决办法
    可伸缩性最佳实践(翻译)
    AJAX延迟异步加载边栏+服务器端缓存AJAX输出
    SQLServer索引调优实践
    SQLServer索引调优实践(2) 索引覆盖
    简单JS实现走马灯效果的文字(无需jQuery)
  • 原文地址:https://www.cnblogs.com/simonryan/p/4831600.html
Copyright © 2011-2022 走看看