zoukankan      html  css  js  c++  java
  • javascript--创建对象

    面向对象(Object-Oriented,OO)的语言有一个特点,那就是它们都有类的概念。而javascript中没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。

    ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或函数”,我们可以把对象想象成散列集:无非就是一组名值对,其中值可以是数据或函数。下面介绍几种创建对象的按方法。

    一、Object构造函数或对象字面量

    var person={
                name:"Bob",
                age:"24",
                sayName:function(){
                    alert(this.name);    
                }
            }

    这种方法有明显缺陷:会产生大量重复代码。

    二、工厂模式

    考虑到ECMAscript中无法创建类,开发人员想到用函数封装以特定接口创建对象的细节。

    function createPerson(name,age){
                return {
                    name:name,
                    age:age,
                    sayName:function(){
                        alert(this.name);
                    }
                }
            }
            var person1=createPerson("Bob","24");

    工厂模式虽然定义接口创建对象,单却没有解决对象识别的问题(即怎样知道一个对象的类型)。

    三、构造函数模式

    大家都知道在javascript中用构造函数可创建特定类型的对象,如:Object、Array。此外,也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。

    function Person(name,age){
                this.name=name;
                this.age=age;
                this.sayName=function(){
                    alert(this.name);    
                }
            }
            var person1=new Person("Bob","24");    
            var person2=new Person("Rose","27");

    创建Person构造函数的新实例,必须使用new操作符。调用构造函数会经历以下几个步骤:

    1. 创建一个新对象;
    2. 将构造函数的作用域赋给新对象--this就指向新对象;
    3. 执行构造函数中的代码;
    4. 返回新对象;

    每个对象都有个constructor(构造函数)属性:

    alert(person1.constructor==Person);    //true
            alert(person1 instanceof Person);    //true
            alert(person1 instanceof Object);    //true

    构造函数模式虽然好用,但也并非没有缺点。每个实例中的方法都是重新创建的,以构造函数模式穿件实例会导致不同的作用域链和标识符解析。因此,不同实例上的同名函数是不相等的。

    alert(person1.sayName==person2.sayName)    //false

    四、原型模式

    每一个创建的函数都有一个prototype属性,指向一个对象,而这个对象的用途是包含了其所有实例共享的属性和方法。因此,我们可以把那些不变的属性和方法直接定义在prototype对象上。

    function Person(name,age){
                Person.prototype.name=name;
                Person.prototype.age=age;
                Person.prototype.sayName=function(){
                    alert(this.name);    
                }
            } 
    var person1=new Person("Bob","24");    
            var person2=new Person("Rose","27");
            person1.sayName();    //Rose
            person2.sayName();    //Rose
            alert(person1.sayName==person2.sayName)    //true

    有原型模式创建的实例的属性和方法都指向prototype对象。且原型的属性、方法都是动态的,我们对原型对象所做的任何修改都能从实例上体现出来,所以person1.sayName()输出Rose。但是,实例一般都是要有属于自己的全部属性的,这也是很少有人单独使用原型模式的原因。

    五、组合使用构造函数模式和原型模式

    由上可知,构造函数模式可以定义每个实例特有的属性和方法,原型模式定义所有实例共享的动态属性和方法。混成模式可谓是集两家之所长!

    function Person(name,age){
                this.name=name;
                this.age=age;
                this.sayName=function(){
                    alert(this.name);    
                }
            }
            Person.prototype={
                job:"teacher",
                age:"30",
                sayAge:function(){
                    alert(this.age);
                }
            }
    var person1=new Person("Bob","24");    
            var person2=new Person("Rose","27");
            person1.sayAge();    //24
            person2.sayAge();    //37
            alert(person1.sayName==person2.sayName);    //false
            alert(person1.sayAge==person2.sayAge);    //true

    在这个例子中,我们可以把共享的属性和方法,定义在prototype对象上;特有的属性、方法定义在实例对象上。但是上例中,我们在实例和原型中都定义了age属性,实例结果显示实例属性。若我们将实例中的age属性去掉:

    function Person(name,age){
                this.name=name;
                this.sayName=function(){
                    alert(this.name);    
                }
            }
            Person.prototype={
                job:"teacher",
                age:"30",
                sayAge:function(){
                    alert(this.age);
                }
            }
    var person1=new Person("Bob","24");    
            var person2=new Person("Rose","27");
            person1.sayAge();    //30
            person2.sayAge();    //30

    实例结果都返回原型中的属性值。这是由于当代码读取某个对象的某个属性时,搜索首先从对象实例开始,若实例中存在则返回该值且屏蔽掉原型中的同名属性;若没找到,则继续在原型对象中搜索。

    构造函数和原型的混成模式,是目前用来创建自定义类型的一种默认模式!

  • 相关阅读:
    启动 Eclipse 弹出“Failed to load the JNI shared library jvm.dll”错误的解决方法!
    Eclipse 出现Some sites could not be found. See the error log for more detail.错误 解决方法
    Android sdk manager不能更新下载缓慢的解决方法
    Android图像处理之Bitmap类
    FAQ_1_陌生的VERSION.SDK_INT
    Android5.0新特性——新增的Widget(Widget)
    Android5.0新特性——兼容性(support)
    springmvc通过ajax异步请求返回json格式数据
    redhat7学习笔记之从零到部署javaweb项目
    ssm框架实现图片上传显示并保存地址到数据库
  • 原文地址:https://www.cnblogs.com/lodadssd/p/6390227.html
Copyright © 2011-2022 走看看