美文网首页
JavaScript创建对象的方式

JavaScript创建对象的方式

作者: 狂奔的胖蜗牛 | 来源:发表于2022-11-16 11:59 被阅读0次

    1.使用工厂模式创建

    使用特定的函数创建对象。

    function createClass(name, age) {
        let o = new Object();
        o.name = name;
        o.age = age;
        o.say = function() {
            console.log(this.name, this.age)
        }
        return o;
    }
    
    let c = createClass('xxx', 11);
    c.say();
    

    函数createClass接收两个参数,然后函数的内部通过这两个参数创建出一个对象返回。
    这种创建方式,有个问题,就是不知道内部创建的对象是什么类型的。

    2.构造函数创建

    使用构造函数模式,可以这样创建对象。

    function CustomClass(name, age) {
        this.name = name;
        this.age = age;
        this.say = function() {
            console.log(this.name, this.age);
        }
    }
    let c = new CustomClass('xxx', 11);
    c.say();
    

    通过CustomClass()构造函数代替了createClass()工厂函数。实际上内部是一致的,区别在于:

    • 1.没有显示的创建对象。
    • 2.属性和方法直接赋值给了this。
    • 3.没有return。
    • 4.函数名首字母大写了,这是一种约定俗成的写法,表示是一个对象。

    new关键字的作用:

    • 1.创建空对象{}
    • 2.this指向这个空对象 this={}
    • 3.给对象赋值
    • 4.返回这个对象 return this

    通过这种方式创建的对象,会有一个属性constructor指向了CustomClass,如下所示:

    console.log(c.constructor);
    console.log(c.constructor === CustomClass);
    输出:
    ƒ CustomClass(name, age) {
        this.name = name;
        this.age = age;
        this.say = function() {
            console.log(this.name, this.age);
        }
    }
    true
    

    这样,我们就可以通过constructor知道对象的类型。不过一般来说,都是通过instanceof操作符来判断对象的类型的。如下:

    console.log(c instanceof CustomClass)
    console.log(c instanceof Object)
    输出:
    true
    true
    

    可以看到,都是true,之所以Object也是true,那是因为所有的对象都继承自Object。

    构造函数可以赋值给变量,然后通过变量来创建对象。

    const CustomClass = function(name, age) {
        this.name = name;
        this.age = age;
        this.say = function() {
            console.log(this.name, this.age);
        }
    }
    let c = new CustomClass('xxx', 11);
    c.say();
    

    调用构造函数的时候,参数可以不写,只要有new操作符,就可以调用构造函数创建对象。

    let c = new CustomClass();
    

    构造函数和普通函数没有区别,唯一的不同就是调用时候的不同。构造函数前面如果添加了new操作符,那么他就会创建出一个对象,否则,他就是一个普通的函数。


    通过构造函数创建的对象,会有一个问题,就是对象的方法每次创建对象时,都是新建一个方法,然后赋值给对象。这样就会导致不同的对象,相同的方法不是同一个对象。如下所示:

    let c1 = new CustomClass();
    let c2 = new CustomClass();
    console.log(c1.say === c2.say)
    输出:
    false
    

    这是可以解决的,我们只需要让函数只创建一次就可以了,如下所示:

    function CustomClass(name, age) {
        this.name = name;
        this.age = age;
        this.say = say
    }
    
    function say() {
        console.log(this.name, this.age);
    }
    

    在外部创建,然后内部引用同一个函数,可以解决上述问题。但是这样非常容易造成需要在外部定义多个函数,导致代码可能会被分散在各个地方。

    3.原型模式创建

    每一个函数,都有一个prototype属性,我们叫做原型。我们可以通过prototype属性,将需要在构造函数内赋值的值,在外部赋值给prototype属性,这样,创建出来的对象实例就都会通过原型获得这些值。

    function Person() {}
    Person.prototype.name = "哈哈哈";
    Person.prototype.age = 29;
    Person.prototype.sayName = function() {
        console.log(this.name);
    };
    let person1 = new Person();
    person1.sayName(); // "哈哈哈"
    let person2 = new Person();
    person2.sayName(); // "哈哈哈"
    console.log(person1.sayName == person2.sayName); // true
    

    我们需要了解到,无论何时,只要创建出一个函数,就会给该函数创建出一个prototype属性,指向了原型对象。默认情况下,所有的原型对象会自动获得一个constructor属性,指向与之关联的构造函数。
    然后在调用属性或者方法的时候,会先在对象实例本身进行搜索,如果实例上有该方法属性,则执行,没有则会沿着prototype找到原型对象,如果原型对象上有,则执行。


    in操作符可以判断属性是否可用。该属性在实例或者原型上,都会返回true。
    hasOwnProperty方法,如果属性在原型上,则会返回true。

    4.通过类创建

    使用关键字class声明类,然后创建出对象。

    // 类声明
    class Person {}
    // 类表达式
    const Animal = class {}
    

    可使用constructor关键字,在类定义内部创建类的构造函数,constructor会告诉解释器,在使用new操作符创建新实例时,调用该函数。如下:

    class Person {
        constructor() {
            console.log('init')
        }
    }
    let p = new Person() // init
    

    可在实例创建时,传入参数,也可以不传,不传参数时,创建的时候类后面的()也可以省略。如下:

    class Person {
        constructor(name) {
            this.name = name
            console.log('init', name)
        }
    }
    let p = new Person() // init undefined
    let p2 = new Person("aa") // init aa
    let p3 = new Person // init undefined
    

    类构造和构造函数构造主要区别是,类构造必须使用new操作符,构造函数的话,不写new操作符,那就是一个普通的函数,类构造不写则会报错。

    相关文章

      网友评论

          本文标题:JavaScript创建对象的方式

          本文链接:https://www.haomeiwen.com/subject/sovsxdtx.html