• 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
    

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

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

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

  • 相关阅读:
    【力扣】16. 最接近的三数之和
    JDBC:批量插入
    利用gpt进行数据分析:用户生命周期专题分析
    Splunk 之 filed 恢复
    牛客网语法篇练习基础语法(一)
    0085 查找算法
    NFNet:NF-ResNet的延伸,不用BN的4096超大batch size训练 | 21年论文
    论文投稿指南——中文核心期刊推荐(计算机技术)
    【逐步剖C++】-第一章-C++类和对象(上)
    G1垃圾回收器
  • 原文地址:https://blog.csdn.net/qq_44895567/article/details/127107742