zoukankan      html  css  js  c++  java
  • JavaScript学习二-----JS对象一

    1.私有变量和公有变量

    function Obj(){
                    var a=0; //私有变量
                    var fn=function(){ //私有函数
    
                    }
                }
    //这样在函数对象Obj外部无法访问变量a和函数fn,它们就变成私有的,只能在Obj内部使用,即使是函数Obj的实例仍然无法访问这些变量和函数
    function Obj(){
                    this.a=0; //公有变量
                    this.fn=function(){ //公有函数
    
                    }
                }
    //函数对象Obj在外部可以访问变量a和函数fn,实例化Obj也可以访问这些变量和函数。

    2.静态变量

    当定义一个函数后通过 “.”为其添加的属性和函数,通过对象本身仍然可以访问得到,但是其实例却访问不到,这样的变量和函数分别被称为静态变量和静态函数。

    function Obj(){
    
                }
    
                Obj.a=0; //静态变量
    
                Obj.fn=function(){ //静态函数
    
                }
    
                console.log(Obj.a); //0
                console.log(typeof Obj.fn); //function
    
                var o=new Obj();
                console.log(o.a); //undefined
                console.log(typeof o.fn); //undefined
    

    3.使用自定义构造函数模式创建对象。这种方式有个缺陷是sayName这个方法,它的每个实例都是指向不同的函数实例,而不是同一个。

    function Person(name,age,job)
    {
        this.name=name;
        this.age=age;
        this.job=job;
        this.sayName=function()
        {
            alert(this.name);
        };
    }
    
    var person = new Person("kevin",31,"SE");
    person.sayName();
    

     这个对属性来说没有什么问题,但是对于方法来说问题就很大了,因为方法都是在做完全一样的功能,但是却又两份复制,如果一个函数对象有上千和实例方法,那么它的每个实例都要保持一份上千个方法的复制,这显然是不科学的,这可肿么办呢,prototype应运而生。

    4.prototype属性

    无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,默认情况下prototype属性会默认获得一个constructor(构造函数)属性,这个属性是一个指向prototype属性所在函数的指针。

    当创建了一个foo对象之后,设置它的原型链z为3.

     此时实例化对象obj,此时obj和foo的原型链都指向了prototype。为obj添加x,y属性,可以通过obj.z直接访问z属性。z属性其实不包含在实例化的obj中,但是却在obj对象的原型链上。当访问z属性的时候,在实例化中找不到对应z属性便会在它的原型链上寻找。但是通过obj.hasOwnProperty(obj.z);检测z是否是obj本身的属性。返回的是false,说明z不是obj的属性。

    function foo(){};
        foo.prototype.z = 3;
    
        var obj = new foo();
        obj.x = 1;
        obj.y = 2;

    根据上图可以看出Person对象会自动获得prototyp属性,而prototype也是一个对象,会自动获得一个constructor属性,该属性正是指向Person对象。

    当调用构造函数创建一个实例的时候,实例内部将包含一个内部指针(很多浏览器这个指针名字为__proto__)指向构造函数的prototype,这个连接存在于实例和构造函数的prototype之间,而不是实例与构造函数之间。

    function Person(name){
                    this.name=name;
                }
    
                Person.prototype.printName=function(){
                    alert(this.name);
                }
    
                var person1=new Person('Byron');
                var person2=new Person('Frank');
    

     5.使用原型模式创建对象;解决了方法3中提到的缺陷,使不同的对象的函数(如sayFriends)指向了同一个函数。但它本身也有缺陷,就是实例共享了引用类型friends,从下面的代码执行结果可以看到,两个实例的friends的值是一样的,这可能不是我们所期望的。

    function Person()
    {
    
    }
    
    Person.prototype = {
        constructor : Person,
        name:"kevin",
        age:31,
        job:"SE",
        friends:["Jams","Martin"],
        sayFriends:function()
        {
            alert(this.friends);
        }
    };
    var person1 = new Person();
    person1.friends.push("Joe");
    person1.sayFriends();//Jams,Martin,Joe
    var person2 = new Person(); 
    person2.sayFriends();//James,Martin,Joe
    

     6.组合使用原型模式和构造函数创建对象,解决了方法5中提到的缺陷,而且这也是使用最广泛、认同度最高的创建对象的方法。

    function Person(name,age,job)
    {
        this.name=name;
        this.age=age;
        this.job=job;
       this.friends=["Jams","Martin"];
    }
    Person.prototype.sayFriends=function()
    {
        alert(this.friends);
    };
    var person1 = new Person("kevin",31,"SE");
    var person2 = new Person("Tom",30,"SE");
    person1.friends.push("Joe");
    person1.sayFriends();//Jams,Martin,Joe
    person2.sayFriends();//Jams,Martin
    

     7. 动态原型模式:这个模式的好处在于看起来更像传统的面向对象编程,具有更好的封装性,因为在构造函数里完成了对原型创建。这也是一个推荐的创建对象的方法。

    function Person(name,age,job)
    {
        //属性
        this.name=name;
        this.age=age;
        this.job=job;
        this.friends=["Jams","Martin"];
        //方法
        if(typeof this.sayName !="function")
        {
            Person.prototype.sayName=function()
            {
                alert(this.name);
            };
            
            Person.prototype.sayFriends=function()
            {
                alert(this.friends);
            };
        }
    }
    
    var person = new Person("kevin",31,"SE");
    person.sayName();
    person.sayFriends();
    
  • 相关阅读:
    【转】揭秘令牌桶
    各空白字符说明
    【转】Python正则表达式指南
    python的urlparse
    【转】HTTP Header 详解
    ElasticSearch(六)底层索引控制
    ElasticeSearch(五)分布式索引架构
    Elasticsearch(四)优化用户体验
    ElasticSearch(三)不仅仅是查询
    ElasticSearch(二) 关于DSL
  • 原文地址:https://www.cnblogs.com/moxuexiaotong/p/6738931.html
Copyright © 2011-2022 走看看