美文网首页
JavaScript对象

JavaScript对象

作者: 好_快 | 来源:发表于2021-01-20 18:17 被阅读0次

    1、概述

    • 一个对象就是一系列属性的集合
    • 一个属性包含一个名和一个值
    • 一个属性的值可以是函数,该属性也被称为方法

    2、对象和属性

    • 一个 javascript 对象有很多属性。
    • 一个对象的属性可以被解释成一个附加到对象上的变量。
    • 对象的属性和普通的 javascript 变量基本没什么区别,仅仅是属性属于某个对象。
    • 属性定义了对象的特征
    • 可以通过点符号或者方括号访问或者设置一个对象的属性
    • 对象的名字(可以是普通的变量)和属性的名字都是大小写敏感
    • 对象中未赋值的属性的值为undefined,而不是null
    var myCar = new Object();
    myCar.make = "Ford";
    myCar.model = "Mustang";
    myCar.year = 1969; 
    
    myCar["make"] = "Ford";
    myCar["model"] = "Mustang";
    myCar["year"] = 1969;
    

    3、枚举一个对象的所有属性

        class Parent {
            constructor(name) {
                this.name = name;
                this.height = name;
            }
            say() {}
        }
        class Child extends Parent {
            constructor(name, age) {
                super(name);
                this.age = age;
            }
            say() {}
        }
        Child.prototype.sex = "1";
        const child = new Child("child", 10);
        console.log(child);
    

    3.1 ES5 之前 getOwnPropertyNames

       <!-- ES6之前 -->
        function listAllProperties(o, isEnumerable = false) {
            //获取所有属性,包含原型链
            let objectToInspect;
            let result = [];
            for (
                objectToInspect = o;
                objectToInspect !== null;
                objectToInspect = Object.getPrototypeOf(objectToInspect)
            ) {
                result = result.concat(Object.getOwnPropertyNames(objectToInspect));
            }
            //数组元素去重
            const newRes = [];
            result.forEach((item) => {
                if (newRes.indexOf(item) === -1) {
                    if (isEnumerable === true) {
                        //保留不可枚举属性
                        newRes.push(item);
                    } else {
                        //不保留不可枚举属性
                        o.propertyIsEnumerable(item) && newRes.push(item);
                    }
                }
            });
            return newRes;
        }
        console.log("ES5之前:", listAllProperties(child, true));
        
        <!--//结果-->
        <!--["name", "height", "age", "constructor", "say", "sex", "__defineGetter__", "__defineSetter__", "hasOwnProperty", "__lookupGetter__", "__lookupSetter__", "isPrototypeOf", "propertyIsEnumerable", "toString", "valueOf", "__proto__", "toLocaleString"]-->
    

    3.2 for...in

    该方法依次访问一个对象及其原型链中所有可枚举的属性。

        const keys = [];
        for (let key in child) {
            keys.push(key);
        }
        console.log("for...in:", keys);
        <!--结果:["name", "height", "age", "sex"]-->
    

    3.3 Object.keys(o)

    该方法返回对象 o 自身包含(不包括原型中)的所有可枚举属性的名称的数组。

        console.log("Object.keys:", Object.keys(child));
        <!--结果:["name", "height", "age"]-->
    

    3.4 Object.getOwnPropertyNames(o)

    该方法返回对象 o 自身包含(不包括原型中)的所有属性(无论是否可枚举)的名称的数组。

         console.log(
            "Object.getOwnPropertyNames:",
            Object.getOwnPropertyNames(child)
        );
        <!--结果:["name", "height", "age"]-->
    

    4、创建新对象

    4.1 Object 构造函数

        <!--Object构造函数-->
        const obj1 = new Object();
        obj1.name = "zs";
        obj1.say = function () {
            console.log("obj1:", this.name);
        };
        obj1.say();
        console.log("obj1:", obj1);
    

    4.2 Object.create()

    创建一个新对象,使用现有的对象来提供新创建的对象的__proto__

        <!--Object.create函数-->
        // const obj2 = Object.create(obj1);
        // const obj2 = Object.create(Object.prototype);
        const obj2 = Object.create({});
        obj2.name = "zs";
        obj2.say = function () {
            console.log("obj2:", this.name);
        };
        obj2.say();
        console.log("obj2:", obj2);
    

    4.3 构造函数

    两步来创建对象:

    • 通过创建一个构造函数来定义对象的类型。首字母大写是非常普遍而且很恰当的惯用法。
    • 通过 new 创建对象实例。
        <!--构造函数-->
        function Person(name) {
            this.name = name;
            this.say = function () {
                console.log("obj3:", this.name);
            };
        }
    
        const obj3 = new Person("zs");
        obj3.name = "zs";
        obj3.say = function () {
            console.log("obj3:", this.name);
        };
        obj3.say();
        console.log("obj3:", obj3);
    

    4.4 字面量

        <!--字面量-->
        const obj4 = {};
        obj4.name = "zs";
        obj4.say = function () {
            console.log("obj4:", this.name);
        };
        obj4.say();
        console.log("obj4:", obj4);
    

    4.5 class 创建

        <!--class-->
        class People {
            constructor(name) {
                this.name = name;
            }
            say() {
                console.log("obj5:", this.name);
            }
        }
        const obj5 = new People("zs");
        obj5.name = "zs";
        obj5.say = function () {
            console.log("obj5:", this.name);
        };
        obj5.say();
        console.log("obj5:", obj5);
    

    5、原型

    • JavaScript 常被描述为一种基于原型的语言
    • 每个对象拥有一个原型对象,是隐藏属性
    • 对象以其原型为模板、从原型继承方法和属性。
    • 原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。
    • 这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。

    5.1 函数对象获取原型

    通过 prototype 属性访问原型。该属性定义在 Function 对象上。没有找到相关文档,但是可以通过以下验证

    Function.hasOwnProperty("prototype")
    //结果为 true
    
    • 每个 JavaScript 函数实际上都是一个 Function 对象实例
    • 构造函数也是函数
    function doSomething(){}
    console.log( doSomething.prototype );
    //var doSomething = function(){};
    //console.log( doSomething.prototype );
    
    

    输出结果为

    {
        constructor: ƒ doSomething(),
        __proto__: {
            constructor: ƒ Object(),
            hasOwnProperty: ƒ hasOwnProperty(),
            isPrototypeOf: ƒ isPrototypeOf(),
            propertyIsEnumerable: ƒ propertyIsEnumerable(),
            toLocaleString: ƒ toLocaleString(),
            toString: ƒ toString(),
            valueOf: ƒ valueOf()
        }
    }
    

    5.2 实例对象获取原型

    • __proto__属性,该方法从 Object.prototype 继承而来
    • Object.getPrototypeOf(obj)方法
    • obj.constructor.prototype,其中 constructor 方法从 Object.prototype 继承而来
    function People(){};
    const p = new People();
    console.log(p.__proto__)
    console.log(Object.getPrototypeOf(p))
    console.log(p.constructor.prototype)
    
    <!-- 结果-->
    <!--constructor: ƒ People()-->
    <!--__proto__:-->
    <!--constructor: ƒ Object()-->
    <!--hasOwnProperty: ƒ hasOwnProperty()-->
    <!--isPrototypeOf: ƒ isPrototypeOf()-->
    <!--propertyIsEnumerable: ƒ propertyIsEnumerable()-->
    <!--toLocaleString: ƒ toLocaleString()-->
    <!--toString: ƒ toString()-->
    <!--valueOf: ƒ valueOf()-->
    <!--__defineGetter__: ƒ __defineGetter__()-->
    <!--__defineSetter__: ƒ __defineSetter__()-->
    <!--__lookupGetter__: ƒ __lookupGetter__()-->
    <!--__lookupSetter__: ƒ __lookupSetter__()-->
    <!--get __proto__: ƒ __proto__()-->
    <!--set __proto__: ƒ __proto__()-->
    
    
    console.log(p.__proto__ === p.constructor.prototype)
    console.log(p.__proto__ === Object.getPrototypeOf(p))
    console.log(p.constructor.prototype === Object.getPrototypeOf(p))
    <!-- 结果-->
    <!--true->
    
    

    6、继承

    • JavaScript没有类,全是 ++对象++
    • 对象的原型叫 ++对象原型++
    • 通过对象创建的叫 ++对象实例++
    • 对象实例的原型是 ++对象原型++ 不是 ++对象++
    • 对象实例的初始属性来自 ++复制、初始化对象属性++ 和 ++继承对象原型/链属性++

    6.1 继承方式1:call

     //定义父类
        function People1(name) {
            //定义父类属性,每个实例对象值都一样,定义在对象上
            this.name = name;
        }
        //定义父类方法,每个实例对象执行方法一样,定义在原型上
        People1.prototype.say = function () {};
    
        //定义子类
        //1、实现属性拷贝和赋值
        function Student1(name, age) {
            //使用this调用父类构造函数,生成对象
            People1.call(this, name);
            //子类属性初始化赋值
            this.age = age;
        }
        //2、实现原型链指向
        /*
         * //不能直接指向父类原型,因为还要修改原型constructor指向,会破坏父类的原型链
         * Student1.prototype = People1.prototype;
         * */
        /*
         * //父类构造函数需要初始化参数,作为原型来讲还需要提供不必要的参数
         * Student1.prototype = new People1("");
         * */
        // 重新生成一个新的原型对象,防止子类父类原型链互相污染
        Student1.prototype = Object.create(People1.prototype);
        Student1.prototype.constructor = Student1;
    
        const people = new People1("ww");
        console.log("people:", people);
        console.log(
            "people.constructor.prototype:",
            people.constructor.prototype
        );
        People1.prototype.run2 = function () {};
        Student1.prototype.run3 = function () {};
        const student = new Student1("zs", 20);
        console.log("student:", student);
        console.log(
            "student.constructor.prototype:",
            student.constructor.prototype
        );
    

    6.2 继承方式1:extends

      class People2 {
            constructor(name) {
                this.name = name;
            }
            say = function () {};
        }
        class Student2 extends People2 {
            constructor(name, age) {
                super(name);
                this.age = age;
            }
        }
        const people2 = new People2("ww");
        console.log("people2:", people2);
        console.log(
            "people2.constructor.prototype:",
            people2.constructor.prototype
        );
        People2.prototype.run2 = function () {};
        Student2.prototype.run3 = function () {};
        const student2 = new Student2("zs", 20);
        console.log("student2:", student2);
        console.log(
            "student2.constructor.prototype:",
            student2.constructor.prototype
        );
    

    7、 Function 和 Object

    • Object.protype 是顶级原型对象
     //Object对象
        console.log("Object:", Object);
        console.log("-Object函数属性---");
        //Object函数原型
        console.log("Object.prototype:", Object.prototype);
        //Object函数原型的原型: 值为null
        console.log(
            "Object.prototype.__proto__:",
            Object.prototype.__proto__
        );
        console.log("-Object对象属性---");
        //Object对象-原型
        console.log("Object.__proto__:", Object.__proto__);
        //Object对象-原型-原型
        console.log(
            "Object.__proto__.__proto__:",
            Object.__proto__.__proto__
        );
        //Object对象-原型-原型 等于 Object.prototype
        console.log(
            "Object.__proto__.__proto__:",
            Object.__proto__.__proto__ === Object.prototype
        );
        //Object对象-原型-原型-原型 : 值为null
        console.log(
            "Object.__proto__.__proto__.__proto__:",
            Object.__proto__.__proto__.__proto__
        );
    
        console.log("-Object构造函数属性---");
        //Object对象-构造函数:Function
        console.log("Object.constructor:", Object.constructor);
    
        console.log("-Function构造函数属性---");
        //Function函数-原型
        console.log("Function.prototype:", Function.prototype);
        //Function函数-原型-原型
        console.log(
            "Function.prototype.__proto__:",
            Function.prototype.__proto__
        );
        //Function函数-原型-原型 等于 Object.prototype 等于 Object.__proto__.__proto__
        console.log(
            "Function.prototype.__proto__:",
            Function.prototype.__proto__ === Object.prototype
        );
        console.log("-Function对象属性---");
        //Function对象-原型
        console.log("Function.__proto__:", Function.__proto__);
        //Function对象-原型 等于 Function.prototype
        console.log(
            "Function.__proto__:",
            Function.__proto__ === Function.prototype
        );
    
        //Function对象-原型-原型
        console.log(
            "Function.__proto__.__proto__:",
            Function.__proto__.__proto__
        );
        //Function对象-原型-原型 等于Function.prototype.__proto__ 等于 Object.prototype 等于 Object.__proto__.__proto__
        console.log(
            "Function.__proto__.__proto__:",
            Function.__proto__.__proto__ === Function.prototype.__proto__
        );
    
        console.log("-Function构造函数属性---");
        console.log("Function.constructor:", Function.constructor);
        console.log(
            "Function.constructor:",
            Function.constructor.prototype
        );
        console.log(
            "Function.constructor:",
            Function.constructor.prototype === Function.__proto__
        );
    

    参考链接

    相关文章

      网友评论

          本文标题:JavaScript对象

          本文链接:https://www.haomeiwen.com/subject/gwakzktx.html