Erstellung und Verwendung von JavaScript-Objekten

Objektklassifizierung: 1. Eingebaute Objekte. 2. Hostobjekte: BOM, DOM. 3. Selbstgebautes Objekt

Die erste Möglichkeit, ein selbst erstelltes Objekt zu definieren: neues Objekt verwenden (nicht empfohlen)


        let student = new Object();

        student.Sex = "Female";//定义的同时如果没有赋值就是undefined。这种方法创建的对象属性可以不赋值
        console.log(student.Sex);//不写=XXX则输出undefined
        student.Score = 40;
        console.log(student.Score);


        delete student.Score;//删除对象属性值
        console.log(student.Score);//undefined

        //用中括号也可以定义属性和赋值。更灵活(同样的,这种方式定义的属性也可以不赋值)
        student["Age"] = 23;
        student["telephone"] = "132423";
        let flag = "Age";
        console.log(student[flag]);//改的时候只要改flag的string从Age改成telephone
        student.PrintInformation = function () {
    
    
            console.log("Sex is:" + this["Sex"] + ",Age is:" + this["Age"]);//不在块级作用域里,用点.调不到?虽然写了也没报错?
        }
        student.PrintInformation();
        console.log(student);//直接输出对象名则会打印所有属性名和值和函数名称

Die zweite Möglichkeit, selbst erstellte Objekte zu definieren: Verwendung von Objektliteralen (empfohlen):

let Teacher =
            {
    
    
                Name: "ZhangSan",
                Age: 19,
                Sex: undefined,//和第一种方法不同的是,这里如果定义时不想为属性赋值不能空着不写,空着会报错

                PrintInformation: function () {
    
    
                    console.log("Name is:" + this.Name + ",Age is:" + this.Age);
                },//记得有逗号

                InsertSex: function (Sex) {
    
    //JS中形参不声明类型!最好给所写的函数添加类似的实参类型检查逻辑(这里没写)
                    this.Sex = Sex;
                    console.log("Sex is " + this.Sex);
                    return 1;
                }//最后一条的逗号可以不加
            };//分号可以加也可以不加
            Teacher.PrintInformation();
        	let result = Teacher.InsertSex("Male");
//对象也可以当作对象的属性
        let Person = {
    
    
            child: Teacher
        };
        console.log("Teacher对象的性别是:" + Person.child.Sex);


        function fun1() {
    
    
            console.log("直接定义一个函数,不和对象绑定")
        }

        fun1();


        (function ()//函数用()包起来并且不写函数名表示这是一个匿名函数,不写函数名(在其他场景,如事件,可以省略最外侧的()括号)
        {
    
    
            console.log("这是立即执行函数");//立即执行函数声明完马上调用,仅用一次。立即执行函数会形成一个单独的作用域,我们可以封装一些临时变量或者局部变量,避免污染全局变量
        })()//最后的括号表示立即调用(不加的话就相等于一个匿名函数)


        //for in 遍历对象的属性
        for (let teacherKey in Teacher) {
    
    
            console.log(teacherKey);//遍历属性名
            console.log(Teacher[teacherKey]);//遍历属性值(只能用中括号,用点没用)
        }

        //在全局中,this指向window对象
        console.log(this);

Zweite Methode: Konstruktor verwenden:

1. Verwenden Sie Factory-Methoden, um Objekte stapelweise zu erstellen (Referenz, nicht empfohlen).

        function CreateObj(age, sex) {
    
    
            let obj =
                {
    
    
                    Age: age,
                    Sex: sex,
                    ShowMes: function () {
    
    
                        console.log("age:" + this.Age + " " + "Sex:" + this.Sex);
                    }
                }
            return obj;
        }

        let obj1 = CreateObj("13", "Male");
        let obj2 = CreateObj("11", "Female");

        obj1.ShowMes();
        obj2.ShowMes();

2. Erstellen Sie Objekte mit Konstruktoren

//声明一个函数,那么浏览器就会在内存中创建一个原型对象,而且每个函数都默认会有一个属性 prototype 指向了这个对象
        //通过构造函数new的对象会存在一个默认的不可见的属性,来指向了构造函数的原型对象。 这个不可见的属性我们一般用 [[prototype]] 来表示,只是这个属性没有办法直接访问到。
        function Person(firstname, lastname) {
    
    
            //在JavaScript中,this通常指向的是我们正在执行的函数本身,或者是指向该函数所属的对象(运行时)
            this.firstname = firstname;
            this.lastname = lastname;
            this.changeFirstname = changeFirstname;
            this.age;
            //js的构造函数除了定义对象的属性也能定义方法
            //方法只不过是附加在对象上的函数。
            function changeFirstname(changeFirstname) {
    
    
                this.firstname = changeFirstname;
            }

            //prototype存在于构造函数中(括号外也可以访问到),他指向了这个构造函数的原型对象。
            ///给Person函数的原型对象中添加属性
            Person.prototype.firstname = "Wang";
            Person.prototype.lastname = "Er";
            Person.prototype.age = "24";

        }
 //new 和不 new的区别:
        //如果 new 了函数内的 this 会指向当前这个 Person 并且就算函数内部不 return 也会返回一个对象。
        //如果不 new 的话函数内的 this 指向的是 window。
        let person01 = new Person("Zhang", "San");
        console.log("FirstName:" + person01.firstname + ",LastName:" + person01.lastname);
        person01.changeFirstname("Li");
        console.log("FirstName:" + person01.firstname + ",LastName:" + person01.lastname);
        //构造方法创建的对象通过__proto__属性访问原型对象
        console.log("原型对象的FirstName:" + person01.__proto__.firstname + ",LastName:" + person01.__proto__.lastname);
        //访问person01中的一个属性age,如果在该对象中找到,则直接返回。如果该对象中没有找到,
        // 则直接去person01对象的[[prototype]]属性指向的原型对象中查找,如果查找到则返回。(如果原型中也没有找到,则继续向上找原型的原型—原型链。)
        console.log("原型对象的age:" + person01.age);//因为没有给person01的age属性赋值,所以找到输出的是原型对象的值
        person01.age = "14";
        console.log("person01的age:" + person01.age);//给person01 age属性赋予值之后,无法再通过它访问原型对象的属性

        //可以通过函数的prototype属性给对象的构造函数添加新的属性
        Person.prototype.Sex = "Male";
        console.log("原型对象的Sex:" + person01.Sex);
        //当然也可以给对象的构造函数添加新的方法
        Person.prototype.SaySex = function () {
    
    
            console.log("性别是:" + this.Sex);
        }
        person01.__proto__.SaySex();//等同于person01.SaySex();因为person01没有实现该方法,所以指向它的原型对象的该方法(和上文写的属性原理是一样的)

        //constructor属性存在于原型对象中,该属性指向构造函数
        console.log(Person.prototype.constructor === Person);//true


        直接给Person构造函数的原型对象指定对象字面量的话,则这个函数的原型对象的constructor属性不再指向该函数(但是构造函数还是指向该原型对象的)
        Person.prototype = {
    
    
            Score: 75
            //如果constructor对你很重要,应该在Person.prototype中添加一行这样的代码--让constructor重新指向Person函数
            //constructor : Person

        };
        let person02 = new Person("Zhi", "ling");
        console.log("原型对象的分数:" + person02.__proto__.Score);//验证此时构造函数依然指向原型对象
        console.log(Person.prototype.constructor === Person);//false 原型对象不再指向构造函数


        //hasOwnProperty方法,可以判断一个属性是否来自对象本身
        console.log(person02.hasOwnProperty("Age"));//false     person02没有赋予age属性值(但原型对象有,如果此时调用输出的就是原型对象的age值了)

        //为对象添加私有属性(通过构造函数生成的实例对象有什么用?最主要的作用就是用来存放实例对象的公有属性和公有方法)
        person01.shengao = "180cm";
        console.log("person01身高:" + person01.shengao);//180cm


        //判断person02是否有shengao属性(这里没有定义所以结果应该是没有)
        //(VVV不推荐VVV)可以判断但是存在缺陷。最特殊的情况就是我们有该字段,而它的值偏偏就是 undefined
        console.log("person02身高:" + person02.shengao);//undefined(原型链上如果某个属性不存在就会返回undefined)
        //(VVV推荐VVV)使用 in 运算符,用法是属性名 in 对象,如果存在返回 true,反之为 false
        console.log("person02身高真的存在吗?:" + 'shengao' in person02);//false

        //函数在js中,也算是一种特殊的对象,在js中,所有函数都可以看做是Function()构造函数生成的实例对象(原型对象)
        console.log(Person.constructor === Function);//true(Person看作原型对象)
        //Function()函数的原型对象就是Function自己,Function对象的构造函数就是Function()函数自己
        console.log(Person.__proto__ === Function.prototype);//true
        console.log(Function.__proto__ === Function.prototype);//true
        console.log(Function.constructor === Function);//true
    **总结:**
    构造函数访问原型对象:prototype
    构造函数new出来的实例对象访问原型对象:__proto__
    原型对象访问构造函数:constructor
    声明一个函数本质上就是生成Function函数的对象

Supongo que te gusta

Origin blog.csdn.net/weixin_48251552/article/details/129771267
Recomendado
Clasificación