• js-原生对象


    工厂模式:
    多个类似对象的创建,可以使用工厂模式,但工程模式不知道新创建的对象是什么类型。

    构造函数模式:
    使用构造函数创建对象:

    function Person(name, age, job){ 
     this.name = name; 
     this.age = age; 
     this.job = job; 
     this.sayName = function() { 
     console.log(this.name); 
     }; 
    } 
    let person1 = new Person("Nicholas", 29, "Software Engineer"); 
    let person2 = new Person("Greg", 27, "Doctor");
    

    person1和person2实例对象的constructor都指向Person,因此构造函数可以区分实例为哪种类型。
    这是相比工厂模式/构造函数模式所具有的优点

    console.log(person1.constructor == Person); // true 
    console.log(person2.constructor == Person); // true
    

    只要使用new操作符,调用的就是构造函数。不使用new操作符的就是普通函数。

    构造函数的缺点:在构造函数中定义的方法,在每个实例上都不同,并不是共享一个操作方法。

    解决方案是,将方法单独定义在构造函数的外部,但是形成的问题是为实例赋予方法的引用的时候,会使用全局的方法的应用,这样会导致全局变量的混乱。
    因此可使用原型模式来解决这些问题。

    原型模式:
    原型对象上创建属性和方法。

    function Person() {} 
    Person.prototype.name = "Nicholas"; 
    Person.prototype.age = 29; 
    Person.prototype.job = "Software Engineer"; 
    Person.prototype.sayName = function() { 
     console.log(this.name); 
    }; 
    let person1 = new Person(); 
    person1.sayName(); // "Nicholas"
    

    原型上的属性和方法,都被所有的属性和方法共享。

    理解原型:
    定义构造方法时,原型对象上就有了constructor属性。指向与之关联构造函数。

    注意:构造函数。实例。原型对象,都是不同的对象。

    原型层级覆盖:如果在对象的属性找没有找到对应的方法或属性,那么就会去它的原型对象上去找对应的方法或属性。
    如果存在同名的属性,那么会覆盖到原型对象上的属性。

    原型和in操作符
    in操作符:可以通过对象属性名,判断该属性名是否在于对象或者对象的原型上

    定义原型的语法:

    function Person() {} 
    Person.prototype = {
     name: "Nicholas", 
     age: 29, 
     job: "Software Engineer", 
     sayName() { 
     console.log(this.name); 
     } 
    };
    

    上述方法,会将constructor指向object对象,而它应该指向的是相关的构造函数,因此可以单独设置constructor

    } 
    Person.prototype = { 
     constructor: Person, 
     name: "Nicholas", 
     age: 29, 
     job: "Software Engineer", 
     sayName() { 
     console.log(this.name); 
     } 
    };
    

    但上述方法又存在了新的问题。这样会创建的一个Enumerable为true的属性。而原生的constructor是不可枚举的。
    因此添加以下方式来进行给更改:

    function Person() {} 
    Person.prototype = { 
     name: "Nicholas", 
     age: 29, 
     job: "Software Engineer", 
     sayName() { 
     console.log(this.name); 
     } 
    }; 
    // 恢复 constructor 属性
    Object.defineProperty(Person.prototype, "constructor", { 
     enumerable: false, 
     value: Person 
    });
    

    原型的动态性:
    如果先创建了对象,然后再在对象的原型上进行了修改,那么仍然会改变之前已经创建好的对象。
    这是因为实例与原型之间就是简简单单的指针。会在原型上找到对应修改的属性。

    原生对象原型:
    修改原生的String对象

    String.prototype.startsWith = function (text) { 
     return this.indexOf(text) === 0; 
    }; 
    let msg = "Hello world!"; 
    console.log(msg.startsWith("Hello")); // true
    

    但并不建议这么做。推荐的做法是使用继承。

    原型的问题:
    原型上包含引用属性值,会存在问题。

    继承:
    原型链:
    将对象原型指针,更改为指向另外一个对象。

  • 相关阅读:
    C++进阶语法——OOP(面向对象)【学习笔记(四)】
    CentOS 7搭建Gitlab流程
    22/6/30
    浏览器截图扩展增加快捷键
    OpenCL专题04:ViennaCL与Eigen双剑合璧
    网易云签到可抽奖?那一年我能签到365天。不信?你看。
    【C++】类和对象的知识点
    家电行业智慧物流体系构建:数商云供应链系统击破家电供应链数字化管理难题
    Hive之内部表外部表和分区表分桶表
    H5页面使用iosSelect.js省市县乡村四级联动
  • 原文地址:https://blog.csdn.net/qq_44895567/article/details/127107742