• 对象


        1 对象类型定义

        2 对象实例

        3 对象表示方式(对象字面量)

        4 对象属性和方法,及属性特性

        5. 原型与原型链

        6. 面向对象设计编程

     


    1 对象类型定义:无序属性的集合,其属性可以包含简单数据类型值,函数或者对象。

     

    2 对象实例:(对象类型的值) 每种数据类型都有相应的值,比如数字8是Number类型的一个值。对于对象类型,值被称为对象实例,任意一种对象都是object对象类型的实例(值)。比如简单类型包装对象(boolean,string,number)就是对象类型的值(实例)。

     

    3 对象的表示方式:(对象字面量) 最外层的一对大括号({})就表示这是一个对象字面量。数组类型的实例也可以直接通过数组字面量来表示。

    //对象字面量和数组字面量
    //流行的JSON数据格式就是基于如此,不过两者有区别,
    
    {    //对象字面量
        name: 'Games',
        getName:fucntion(){
            return this.name;
        }
    }
    
    [{    //数组字面量    
        name: 'Games',
        age:'31'
    },{    
        name: 'Kobe',
        age:'34'
    }
    
    ]

    3.1 对象字面量直接创建对象

    var person = {
        "name":"Games",
        "age":"31"
    }; 
    
    //用对象字面量创建对象,实际没有利用构造函数
    //但创建出的对象仍然有指向这个函数的属性
    //constructor用于保存创建这个对象实例的函数
    
    console.info(person.constructor===Object);//true

     

    4. 对象属性和方法,及属性特性

         方法本质也是一种属性,只是属性的值类型是函数,就称为方法。

         1_属性类型:

                         数据属性:直接属性值的属性

                         访问器属性:通过getter/setter方法来访问属性值的属性

                         内部属性:不能通过代码直接访问的属性,只是为了规范说明目的而存在

        2_常见内部属性 (在规范中也使用两个中括号的形式来描述)

    哪些对象具备 内部属性名称 说明
    所有对象 [[Put]] 属性赋值调用的方法
    所有对象 [[Get]] 读取一个属性值调用的方法
    所有对象 [[Prototype]] 指向每一个对象的原型对象,不能在代码中直接访问这个内部属性,
    可以通过Object.getPrototypeOf(object)来获取原型对象(在Firefox中可以通过__proto__来直接访问)。
    所有对象 [[Class]] Object.prototype.toString方法中按照规范内建对象会返回包含[[Class]]的值“[object class]”,
    而内建对象的[[Class]]值就是相应的名称(比如Array对象的[[Class]]值为'Array'),
    因此可以通过Object.prototype.toString.call(value) == '[object Array]'来判断value是否是一个Array。
    New创建对象 [[Construct]] 使用new操作符调用一个函数时,后台调用[[Construct]]
    调用call方法 [[Call]] 而使用call方法来调用函数时,后台会调用[[Call]]
    执行函数时 [[Scope]]

    当一个函数被执行时,就会创建一个[[Scope]]对象,可以理解为[[Scope]]就是函数活动对象,而this、arguments、形参、函数内部定义的变量和函数都是的[[Scope]]对象的属性。

     

        3_属性定义及定义属性相关特性(用来描述属性的特性)

    最常见的定义属性的方法就是直接在对象上添加属性,比如obj.name = 'linjisong',这种情况下定义的属性所具有的内部特性都是默认的。

    如果想定义一个值不能被修改的属性要怎么做呢?

           属性定义方法:defineProperty() 定义一个属性 和 defineProperties() 定义一组属性

           属特相关特性:

    特性含义 特性名称 直接添加属性时默认值 通过方法定义属性时默认值
    属性具体的值 value undefined undefined
    能够修改属性值

    writable

    true   可以

    false  不可以
    能否通过for-in枚举返回属性 enumerable true   可以 false  不可以
    能够重新配置属性特性或删除属性 configurable true   可以 false  不可以
    读取属性时调用的函数 get undefined undefined
    写入属性时调用的函数 set undefined undefined
    //注意说明
    
    //       1. 对于访问器属性,[[Get]]、[[Set]]不一定都有,没有[[Get]]的属性不能读(返回undefined,严格模式下抛出异常),没有[[Set]]的属性不能写(会忽略,严格模式下抛出异常)
    
    //       2.  使用属性定义方法时 [[Enumerable]] [[Configurable]] [[Writable]] 默认值为false。
    
    //       3.  这些方法设置或获取的属性特殊和属性的类型有关,比如数据属性只能设置[[Confirurable]]、[[Enumerable]]、[[Writable]]、[[Value]]。

    定义属性:

    // 创建一个包含一个默认属性job的对象(job属性可以修改、删除、在for-in中枚举)
    var person = {job:'it'};
    
    Object.defineProperty(person, 'name', {            // 添加一个不能被修改、删除的name属性                  
    
        value:'Games',                                         
        enumerable:true                                         //可以通过for-in遍历,但是Configurable,Writable都为false.所以不能被修改和删除
    });
    
    
    Object.defineProperties(person, {                            // 定义多个属性(数据属性year和访问器属性age)
        year:{                                                   //数据属性year可以直接被访问
            value : 2012, 
            configurable:true,
            writable:true    
        },
        age:{                                                    //访问器属性age
            get : function(){
                return this.year-1984;
            }
        }
    });
    
    var job = Object.getOwnPropertyDescriptor(person, 'job');
    console.info(job.configurable);                             //true,直接添加属性时默认为true
    
    var name = Object.getOwnPropertyDescriptor(person, 'name');
    console.info(name.configurable);                            //false,使用属性定义方法添加属性时默认为false
    console.info(person.name);                                  //Games
    
    person.name = 'Kobe';                                      //由于不能修改,所以值不会改变,在严格模式下会抛出异常
    console.info(person.name);                                 //Games
    
    person.year = 2015;
    console.info(person.year);                                //2015
    console.info(person.age);                                  //31,在修改year的同时,也修改了age属性

    对象常用属性和方法:

    类型

    名称

    说明

    属性

    constructor

    指向用于创建当前对象的构造函数

    方法

    hasOwnProperty(propertyName)

    检查给定的属性是否在当前对象实例中

    propertyIsEnumerable(propertyName)

    检查给定的属性是否能够是使用for-in语句来枚举

    isPrototype(object) 检查传入的对象是否是另一个对象的原型
    toLocalString() 返回对象的字符串表示,该字符串与执行环境的地区相对应
    toString() 返回对象的字符串表示
    valueOf() 返回对象的字符串、数值或布尔值表示,通常与toString()方法返回值相同
     

    create(prototype[,descriptors])

    创建一个具有指定原型且可选择性地包含指定属性的对象

     

    getOwnPropertyNames(object)

    返回对象的属性(方法)的名称

     

    getPrototypeOf(object)

    返回对象的原型

    keys(object)

    返回对象的可枚举属性(方法)的名称

           对象属性和方法访问方式:

           确定值:用.点号方式访问,如:person1.name;

           不确定值:使用方括号[],如: oDiv[this.index];   方括号内部可以是一个变量或者表达式。

     

    如何遍历对象实例自身的属性而不包括从原型链继承而来的属性。

    for(var propertyName in object){                    //如果for-in循环
      if(object.hasOwnPorperty(propertyName)){        //通过方法判断是否属于自身对象的属性
        //循环处理
      }
    }

     

    5. 原型与原型链

    1.  原型与原型链

         每个对象都有一个原型对象,而原型对象本身也是一个对象,也有自己的原型对象,这样就形成了一个圆形链直至null对象。

         对象的内部属性[[Prototype]]指向的就是对象的原型对象,而Object.prototype的原型对象为null。

     

    2. 原型链作用-属性方法查找-继承

         在访问一个对象的属性(方法)时,JS引擎会先查找对象本身有没有这个属性,如果有,返回这个属性值,如果没有,则查找对象的原型是否有这个属性,有则返回,如果没有就继续查找原型对象的原型直至最后一个原型对象。

     

    3. 对象的原型(__proto__), 构造函数的原型(prototype)

        每一个构造函数都有一个属性prototype,这个属性是在函数定义过程中添加的,它指向的对象就是所有使用该函数创建的实例对象原型对象

        构造函数的原型对象有一个属性constructor指向该构造函数。

       1.所有函数(构造器)的__proto__都指向Function.prototype.

       2.所有对象的原型(__proto__)都指向其构造器的prototype.

     

    181637013624694

    4. 原型链与作用域链区别

      属性查找是沿着原型链,标识符查找是沿着作用域链,都是一个逐级查找的过程。

    6. 面向对象设计编程

    1. JS中没有类(class),但是利用构造函数及其原型对象来替代,

    2. 类和对象的区别于关系

        类是抽象的,代表一类事物;对象是具体的,代表一个实际的事物;类是对象实例的模板,对象实例是类的一个个体。

    3. 抽象

        在定义一个类时,实际上就是把一类事物的共有属性和行为提取出来,形成一个模板。

    4. 面向对象三大特征

        封装:封装就是把抽象出来的属性和对属性的操作方法封装在一起,属性被保护在内部,程序的其它部分只有通过被授权的操作(函数),才能对属性进行操作,比如公开的登录方法,验证通过则可以查看私有的属性,比如账户余额等!

        继承:实例化对象可以继承其对应类的属性和方法,类也可以继承其它类的属性和方法,代码复用,提高效率

        多态:即多种状态,就是指一个引用在不同情况下的多种状态,通过指向父类的引用,来调用不同子类中实现的方法。JS中一个变量的类型是在运行过程中由JS引擎决定的。JS不支持重载,子类可以覆盖父类的方法,达到不同状态实现不同的功能需求。

     

    定义类及实例化对象方法: 用构造函数方式来定义对象特有属性,用原型方式来定义类共有的属性和方法。

    子类继承父类的方法:  用构造函数方式实现对父类属性的继承,用原型方式实现对原型属性和方法的继承。

    //定义一个父类
        function Person(name,sex){               //用构造函数方式来定义对象特有属性
        this.name = name;
        this.sex = sex;    
        }
    
        Person.prototype.sayHello = function(){   //用原型方式来定义类共有的属性和方法。
            return "Hello!";    
        };
    
    
        //定义一个子类
        function Student(name,sex,major){         //用构造函数方式来继承父类的属性    
            Person.call(this,name,sex,major);      //创建子类实例时,第二次调用父类构造函数,并利用call改变this指向
            this.major = major;
        }
    
        Student.prototype = new Person();         //通过原型继承方式,子类的原型对象指向父类的实例,可以继承父类原型方法
        Student.prototype.study = function(){     //子类的方法
            return "Never too late to learn!";    
        }
    
        var s1 = new Student('Games','male','IT');   //实例化子类的对象,并初始化
        
        console.info(s1.name);                         //Games  继承父类的属性
        console.info(s1.sex);                          //male   继承父类的属性
        console.info(s1.sayHello());                   //Hello  继承父类的方法
        console.info(s1.major);                        //IT     子类自身的属性
        console.info(s1.study());                      //Never too late to learn!  子类自身的方法
     
    寄生组合式继承:这种方式只调用了一次父类构造函数,从而避免了在子类型的原型对象上创建不必要的属性,也能够保证原型链不变,可以正常使用instanceof和isPrototypeOf()。
    function create(o){                          //创建一个新对象并返回
        var fn = function(){};
        fn.prototype = o;
        return new fn();    
    }
    
    function inherit(sub, sup){               //实现子类原型继承父类原型实例
        var prototype = create(sup.prototype);
        prototype.constructor = sub;
        sub.prototype = prototype;    
    }
    
    
    //定义一个父类
        function Person(name,sex){               //用构造函数方式来定义对象特有属性
        this.name = name;
        this.sex = sex;    
        }
    
        Person.prototype.sayHello = function(){   //用原型方式来定义类共有的属性和方法。
            return "Hello!";    
        };
    
    
        //定义一个子类
        function Student(name,sex,major){         //用构造函数方式来继承父类的属性    
            Person.call(this,name,sex,major);      //创建子类实例时,第二次调用父类构造函数,并利用call改变this指向
            this.major = major;
        }
    
        inherit (Student,Person);                 //通过inherit方法继承
        Student.prototype.study = function(){     //子类的方法
            return "Never too late to learn!";    
        }
    
        var s1 = new Student('Games','male','IT');   //实例化子类的对象,并初始化
        
        console.info(s1.name);                         //Games  继承父类的属性
        console.info(s1.sex);                          //male   继承父类的属性
        console.info(s1.sayHello());                   //Hello  继承父类的方法
        console.info(s1.major);                        //IT     子类自身的属性
        console.info(s1.study());                      //Never too late to learn!  子类自身的方法
     
     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    【Java】IO流--文件夹的复制
    【Java】IO流--序列化与反序列化
    【Java】Java中的数组是对象吗?(转载)
    【Java】Java漫谈-数组(转载)
    【Java】IO流--对象流--ObjectInputStream、ObjectOutputStream
    【Java】IO流--数据流--DataInputStream、DataOutputStream
    【Java】IO流--打印流--PrintStream
    【Java】IO流--转换流--InpuStreamReader、OutputStreamWriter
    CentOS快速安装Nginx的方法,nginx如何启动重启停止
    Mac查看端口号是否被占用及释放
  • 原文地址:https://www.cnblogs.com/Peng2014/p/4716311.html
Copyright © 2020-2023  润新知