• JS中的对象



    语法

    let obj = {
        属性名:,
        方法名: 函数,
        get 属性名() {},
        set 属性名(新值) {}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    例1

    let stu1 = {
        name: "小明",
        age: 18,
        study: function(){
            console.log(this.name + "爱学习");
        }    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    例2

    let name = "小黑";
    let age = 20;
    let study = function(){
        console.log(this.name + "爱学习");
    }
    
    let stu2 = { name, age, study }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    例3(重点)

    let stu3 = {
        name: "小白",
        age: 18,
        study(){
            console.log(this.name + "爱学习");
        }    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 注意:对象方法这么写,仅限于对象内部

    例4

    let stu4 = {
        _name: null, /*类似于java中私有成员变量*/
        get name() {
            console.log("进入了get");
            return this._name;
        },
        set name(name) {
            console.log("进入了set");
            this._name = name;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    调用 get,set

    stu4.name = "小白"
    
    console.log(stu4.name)
    
    • 1
    • 2
    • 3

    特色

    属性增删

    对比一下 Java 中的 Object

    • Java 的 Object 是以类作为模板来创建,对象不能脱离类模板的范围,一个对象的属性、能用的方法都是确定好的
    • js 的对象,不需要什么模板,它的属性和方法可以随时加减
    let stu = {name:'张三'};
    stu.age = 18;					// 添加属性
    delete stu.age;					// 删除属性
    
    stu.study = function() {		// 添加方法
        console.log(this.name + "在学习");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    添加 get,set,需要借助 Object.definePropery

    let stu = {_name:null};
    
    Object.defineProperty(stu, "name", {
        get(){
            return this._name;
        },
        set(name){
            this._name = name;
        }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 参数1:目标对象
    • 参数2:属性名
    • 参数3:get,set 的定义
    this关键字

    先来对 Java 中的 this 有个理解

    public class TestMethod {
    
        static class Student {
            private String name;
    
            public Student(String name) {
                this.name = name;
            }
    
            public void study(Student this, String subject) {
                System.out.println(this.name + "在学习 " + subject);
            }
        }
    
        public static void main(String[] args) {
            Student stu = new Student("小明");
            
            // 下面的代码,本质上是执行 study(stu, "java"),因此 this 就是 stu
            stu.study("java"); 
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • Java 中的 this 是个隐式参数
    • Java 中,我们说 this 代表的就是调用方法的那个对象

    js 中的 this 也是隐式参数,但它与函数运行时上下文相关

    例如,一个“落单”的函数

    function study(subject) {
        console.log(this.name + "在学习 " + subject)
    }
    
    • 1
    • 2
    • 3

    测试一下

    study("js");  // 输出 在学习 js
    
    • 1

    这是因为此时函数执行,全局对象 window 被当作了 this,window 对象的 name 属性是空串

    同样的函数,如果作为对象的方法

    let stu = {
        name:"小白",
        study
    }
    
    • 1
    • 2
    • 3
    • 4

    这种情况下,会将当前对象作为 this

    stu.study('js'); 	// 输出 小白在学习 js
    
    • 1

    还可以动态改变 this

    let stu = {name:"小黑"};
    study.call(stu, "js");	// 输出 小黑在学习 js
    
    • 1
    • 2

    这回 study 执行时,就把 call 的第一个参数 stu 作为 this

    一个例外是,在箭头函数内出现的 this,以外层 this 理解

    匿名函数

    let stu = {
        name: "小花",
        friends: ["小白","小黑","小明"],
        play() {
            this.friends.forEach(function(e){
                console.log(this.name + "与" + e + "在玩耍");
            });
        }
    }
    stu.play()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • this.name 所在的函数是【落单】的函数,因此 this 代表 window

    输出结果为

    与小白在玩耍
    与小黑在玩耍
    与小明在玩耍
    
    • 1
    • 2
    • 3

    用箭头函数

    let stu = {
        name: "小花",
        friends: ["小白","小黑","小明"],
        play() {
            this.friends.forEach(e => {
                console.log(this.name + "与" + e + "在玩耍");
            })
        }    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • this.name 所在的函数是箭头函数,因此 this 要看它外层的 play 函数,play 又是属于 stu 的方法,因此 this 代表 stu 对象

    输出结果为

    小花与小白在玩耍
    小花与小黑在玩耍
    小花与小明在玩耍
    
    • 1
    • 2
    • 3

    不用箭头函数的做法

    let stu = {
        name: "小花",
        friends: ["小白","小黑","小明"],
        play() {
            let me = this;
            this.friends.forEach(function(e){
                console.log(me.name + "与" + e + "在玩耍");
            });
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    原型继承

    let father = {
        f1: '父属性',
        m1: function() {
            console.log("父方法");
        }
    }
    
    let son = Object.create(father);
    
    console.log(son.f1);  // 打印 父属性
    son.m1();			  // 打印 父方法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • father 是父对象,son 去调用 .m1 或 .f1 时,自身对象没有,就到父对象找
    • son 自己可以添加自己的属性和方法
    • son 里有特殊属性 __proto__ 代表它的父对象,js 术语: son 的原型对象
    • 不同浏览器对打印 son 的 __proto__ 属性时显示不同
      • Edge 打印 console.dir(son) 显示 [[Prototype]]
      • Firefox 打印 console.dir(son) 显示
    基于函数的原型继承

    出于方便的原因,js 又提供了一种基于函数的原型继承

    函数职责

    1. 负责创建子对象,给子对象提供属性、方法,功能上相当于构造方法

    2. 函数有个特殊的属性 prototype,它就是函数创建的子对象的父对象

      **注意!**名字有差异,这个属性的作用就是为新对象提供原型

    function cons(f2) {
        // 创建子对象(this), 给子对象提供属性和方法
        this.f2 = f2;
        this.m2 = function () {
            console.log("子方法");
        }
    }
    // cons.prototype 就是父对象
    cons.prototype.f1 = "父属性";
    cons.prototype.m1 = function() {
        console.log("父方法");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    配合 new 关键字,创建子对象

    let son = new cons("子属性")
    
    • 1

    子对象的 __proto__ 就是函数的 prototype 属性

  • 相关阅读:
    Kernel: config: PARAVIRT; 部分虚拟化;类虚拟化
    【听课笔记】复旦大学遗传学_03基因
    Docker images 常用shell脚本
    公司电脑文件透明加密、防泄密管理软件系统
    python+pytest接口自动化测试之接口测试基础
    Megatron-LM GPT 源码分析(三) Pipeline Parallel分析
    在ubuntu系统中设置virtualbox虚拟机开机自动启动
    SpringSecurity(六)【自定义认证案例】
    (十五)使用Redis实现发布订阅功能
    数据改版 | CnOpenData中国高新技术企业专利统计数据
  • 原文地址:https://blog.csdn.net/Az201706/article/details/126912967