• JavaScript ES6 类和对象 简单记录



    /*
    1.在ES6之前如果定义一个类?
    通过构造函数来定义一个类
    */
            function Person(myName, myAge) {
                // 实例属性
                // this.name = "lnj";
                // this.age = 34;
                this.name = myName;
                this.age = myAge;
    
                // 实例方法
                this.say = function () {
                    console.log(this.name, this.age);
                }
                // 静态属性
                Person.num = 666;
                // 静态方法
                Person.run = function () {
                    console.log("run");
                }
            }
            // let p = new Person();
            let p = new Person("zs", 18);
            p.say();
            console.log(Person.num);
            Person.run();
    /*
    2.从ES6开始系统提供了一个名称叫做class的关键字, 这个关键字就是专门用于定义类的
    */
      class Person{
                // 当我们通过new创建对象的时候, 系统会自动调用constructor
                // constructor我们称之为构造函数
                constructor(myName, myAge){
                    this.name = myName;
                    this.age = myAge;
                }
                // 实例属性
                // name = "lnj";
                // age = 34;
                // 实例方法
                say(){
                    console.log(this.name, this.age);
                }
                // 静态属性
                static num = 666;
                // 静态方法
                static run() {
                    console.log("run");
                }
            }
            // let p = new Person();
            let p = new Person("zs", 18);
            p.say();
            console.log(Person.num);
            Person.run();

    需要注意的地方:

    class Person{
                // 以下定义"实例属性"的方式并不是ES6正式版标准中的写法, 大部分的浏览器不支持
                // 在ES6标准中添加实例属性都需要在constructor中添加
                // 实例属性
                // name = "lnj";
                // age = 34;
                constructor(){
                    this.name = "lnj";
                    this.age = 34;
                }
                // 实例方法
                say(){
                    console.log(this.name, this.age);
                }
            }
            let p = new Person();
            console.log(p);

     class Person{
                // 以下定义"静态属性"的方式并不是ES6正式版标准中的写法, 大部分的浏览器不支持
                // 在ES标准中static只支持定义静态方法不支持定义静态变量
                // 静态属性
                // static num = 666;
    
                // 静态方法
                static run() {
                    console.log("run");
                }
            }
            Person.num = 666;
            let p = new Person();
            console.log(p);

    function Person(myName, myAge) {
                // 实例属性
                this.name = myName;
                this.age = myAge;
                // 实例方法
                
                this.hi = function () {
                    console.log("hi");
                }
            }
            // 原型上的方法
            Person.prototype.say = function () {
                console.log(this.name, this.age);
            }
            let p = new Person("lnj", 34);
            console.log(p);
    
    
            class Person{
                constructor(myName, myAge){
                    this.name = myName;
                    this.age = myAge;
                  //构造函数里面添加的方法会添加到 对象本身
                    this.hi = function () {
                        console.log("hi");
                    }
                }
                //在类里面添加的方法会加到原型对象中
                say(){
                    console.log("hi");
                }
            }
            let p = new Person("lnj", 34);
            console.log(p);

    注意点:
    如果通过class定义类, 那么不能自定义这个类的原型对象
    如果想将属性和方法保存到原型中, 只能动态给原型对象添加属性和方法
     function Person(myName, myAge) {
                // 实例属性
                this.name = myName;
                this.age = myAge;
                // 实例方法
                this.hi = function () {
                    console.log("hi");
                }
            }
            // 原型上的方法
            // Person.prototype.type = "人";
            // Person.prototype.say = function () {
            //     console.log(this.name, this.age);
            // };
            //function方式定义的构造函数可以修改 原型对象
            Person.prototype = {
                constructor: Person,
                type: "",
                say: function () {
                    console.log(this.name, this.age);
                }
            };
    
    
            class Person{
                constructor(myName, myAge){
                    this.name = myName;
                    this.age = myAge;
                    this.hi = function () {
                        console.log("hi");
                    }
                }
                run(){
                    console.log("run");
                }
            }
            // Person.prototype.type = "人";
            // Person.prototype.say = function () {
            //     console.log(this.name, this.age);
            // };
    
            let obj = {
                constructor: Person,
                type: "",
                say: function () {
                    console.log(this.name, this.age);
                }
            };
            //修改对象原型无效
            Person.prototype = obj;
    
            let p = new Person("lnj", 34);
            console.log(p);

    五  继承

     ES6之前的继承
    1.在子类中通过call/apply方法借助父类的构造函数
    2.将子类的原型对象设置为父类的实例对象
    function Person(myName, myAge) {
                this.name = myName;
                this.age = myAge;
            }
            Person.prototype.say =  function () {
                console.log(this.name, this.age);
            }
            function Student(myName, myAge, myScore) {
                // 1.在子类中通过call/apply方法借助父类的构造函数
                Person.call(this, myName, myAge);
                this.score = myScore;
                this.study = function () {
                    console.log("day day up");
                }
            }
            // 2.将子类的原型对象设置为父类的实例对象
            Student.prototype = new Person();
            Student.prototype.constructor = Student;
    
            let stu = new Student("zs", 18, 99);
            stu.say();
    1.在ES6中如何继承
    1.1在子类后面添加extends并指定父类的名称
    1.2在子类的constructor构造函数中通过super方法借助父类的构造函数
    class Person{
                constructor(myName, myAge){
                    // this = stu;
                    this.name = myName; // stu.name = myName;
                    this.age = myAge; // stu.age = myAge;
                }
                say(){
                    console.log(this.name, this.age);
                }
            }
            /*
            1.在ES6中如何继承
            1.1在子类后面添加extends并指定父类的名称
            1.2在子类的constructor构造函数中通过super方法借助父类的构造函数
            */
            // 以下代码的含义: 告诉浏览器将来Student这个类需要继承于Person这个类
            class Student extends Person{
                constructor(myName, myAge, myScore){
                    // 1.在子类中通过call/apply方法借助父类的构造函数
                    // Person.call(this, myName, myAge);
                    super(myName, myAge);
                    this.score = myScore;
                }
                study(){
                    console.log("day day up");
                }
            }
            let stu = new Student("zs", 18, 98);
            stu.say();

    六  获取对象类型

     let obj = new Object();
            console.log(typeof obj); // object
    
            let arr = new Array();
             /*
             * 这样的打印会是object,这是因为 在所有构造函数中,内部其实会新建一个Object对象,然后赋值给this
             * */
             console.log(typeof arr); // object
            console.log(arr.constructor.name); // Array
    
    
            function Person() {
                // let obj = new Object();
                // let this = obj;
                this.name = "lnj";
                this.age = 34;
                this.say = function () {
                    console.log(this.name, this.age);
                }
                // return this;
            }
            let p = new Person();
            // console.log(typeof p); // object
            console.log(p.constructor.name); // Person

    七 instanceof 关键字

    1.什么是instanceof关键字?
    instanceof用于判断 "对象" 是否是指定构造函数的 "实例"

       2.instanceof注意点

    只要 构造函数的原型对象出现在实例对象的原型链中都会返回true
     class Person{
                name = "lnj";
            }
            let p = new Person();
            console.log(p instanceof Person); // true
    
            class Cat{
                name = "mm";
            }
            let c = new Cat();
            console.log(c instanceof Person); // false
    
    
            function Person(myName) {
                this.name = myName;
            }
            function Student(myName, myScore) {
                Person.call(this, myName);
                this.score = myScore;
            }
            Student.prototype = new Person();
            Student.prototype.constructor = Student;
    
            let stu = new Student();
            /*
            * 返回true的原因为 Person的原型对象出现在了stu的原型链上
            * */
            console.log(stu instanceof Person); // true

    八 isPrototypeOf

    1.什么是isPrototypeOf属性
    isPrototypeOf用于判断 一个对象是否是另一个对象的原型
    2.isPrototypeOf注意点
    2.1只要调用者在传入对象的原型链上都会返回true

     class Person{
                name = "lnj";
            }
            let  p = new Person();
            console.log(Person.prototype.isPrototypeOf(p)); // true
    
            class Cat{
                name = "mm";
            }
            console.log(Cat.prototype.isPrototypeOf(p)); // false
            
    
            function Person(myName) {
                this.name = myName;
            }
            function Student(myName, myScore) {
                Person.call(this, myName);
                this.score = myScore;
            }
            Student.prototype = new Person();
            Student.prototype.constructor = Student;
    
            let stu = new Student();
            console.log(Person.prototype.isPrototypeOf(stu)); // true

    八 判断某一个对象是否拥有某一个属性

    // 需求: 判断某一个对象是否拥有某一个属性
            class Person{
                name = null;
                age = 0;
            }
            Person.prototype.height = 0;
            
            let p = new Person();
            // in的特点: 只要类中或者原型对象中有, 就会返回true
            console.log("name" in p); // true
            console.log("width" in p); // false
            console.log("height" in p); // true
            
    
            // 需求: 判断某一个对象自身是否拥有某一个属性
            let p = new Person();
            // 特点: 只会去类中查找有没有, 不会去原型对象中查找
            console.log(p.hasOwnProperty("name")); // true
            console.log(p.hasOwnProperty("height")); // false

    九 深拷贝和浅拷贝

    1.什么是深拷贝什么是浅拷贝?
    1.1深拷贝
    修改新变量的值不会影响原有变量的值
    默认情况下基本数据类型都是深拷贝

    1.1浅拷贝
    修改新变量的值会影响原有的变量的值
    默认情况下引用类型都是浅拷贝

    万能深拷贝方法
    class Person{
                name = "lnj";
                cat = {
                    age : 3
                };
                scores = [1, 3, 5];
            }
            let p1 = new Person();
            let p2 = new Object();
            /*
    
            // p2.name = p1.name;
            // p2.name = "zs";
            // console.log(p1.name);
            // console.log(p2.name);
            p2.cat = p1.cat;
            p2.cat.age = 666;
            console.log(p1.cat.age);
            console.log(p2.cat.age);
            */
    
            depCopy(p2, p1);
            // console.log(p2);
    
            p2.cat.age = 666;
            console.log(p1.cat.age);
            console.log(p2.cat.age);
    
            function depCopy(target, source) {
                // 1.通过遍历拿到source中所有的属性
                for(let key in source){
                    // console.log(key);
                    // 2.取出当前遍历到的属性对应的取值
                    let sourceValue = source[key];
                    // console.log(sourceValue);
                    // 3.判断当前的取值是否是引用数据类型
                    if(sourceValue instanceof Object){
                        // console.log(sourceValue.constructor);
                        // console.log(new sourceValue.constructor);
                        let subTarget = new sourceValue.constructor;
                        target[key] = subTarget;
                        depCopy(subTarget, sourceValue);
                    }else{
                        target[key] = sourceValue;
                    }
                }
            }
  • 相关阅读:
    简单工厂模式&工厂方法模式&抽象工厂模式的区别及优缺点及使用场景
    JDK1.8的新特性
    在Button样式中添加EventSetter,理解路由事件
    关于C#低版本升级高版本时,项目中引用Microsoft.Office.Interop.Word,程序提示不存在类型或命名空间名office.
    无法安装或运行此应用程序。该应用程序要求首先在"全局程序集缓存(GAC)"中安装程序集
    C#winform跨窗体传值和调用事件的办法
    C#线程处理:七、线程实列
    C#线程处理:六、线程同步(三)
    C#线程处理:五、线程同步(二)
    C#线程处理:四、线程同步
  • 原文地址:https://www.cnblogs.com/xiaonanxia/p/10935418.html
Copyright © 2020-2023  润新知