JavaScript创建对象的几种方式

    xiaoxiao2021-12-14  19

    ECMA-262把对象定义为:”无序属性的集合,其属性可以包含基本值、对象或者函数”。 我们可以把ECMAScript的对象想象成是拥有属性和方法的数据。

    1.object的构造函数

    创建自定义对象最简单的方式就是创建一个object的实例,然后为它添加属性和方法,早期JavaScript开发人员经常使用这个模式创建新对象。

    var person = new Object(); person.name = "Nicholas"; person.age = 29; person.job = "Software Engineer"; person.sayName = function () { alert(this.name); }

    2.对象字面量

    几年后,对象字面量成为创建这种对象的首选模式。

    var person = { name: "Nicholas", age:29, job:"Software Engineer", sayName: function () { alert(this.name); } };
    问题:

    虽然Object构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点: 使用同一个接口创建很多对象,会产生大量的重复代码。为解决这个问题,人们开始使用工厂模式的一种变体。

    3.工厂模式

    定义:开发人员用一种函数封装以特定接口创建对象的细节

    function createPerson(name, age, job) { var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function () { alert(this.name); }; return o; } var person1 = createPerson("Nicholas", 29, "Software Engineer"); var person2 = createPerson("Greg", 27, "Doctor");
    问题:

    工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。

    4.构造函数模式

    解决问题:解决对象识别的问题(即怎样知道一个对象的类型) 存在的问题: 1.在全局作用域中定义的函数实际上只能被某个对象(person1,person2)调用,这让全局作用域有点名不副实。 2.如果对象需要定义很多方法,就要定义很多个全局函数,于是我们这个自定义的引用类型就丝毫没有封装性可言。 规则:构造函数始终应以一个大写字母开头,非构造函数则应以小写字母开头 原生构造函数:Object和Array 自定义的构造函数,如下所示 1.person1和person2都有一个sayName()的方法,但那两个方法不是同一个Function的实例。

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

    2.通过把函数定义到构造函数外面解决这个问题

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

    5.原型模式

    解决的问题: 1.不必再构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象(prototype)中。 2.可以让所有实例对象 (var person1 = new Person(); ) 共享它所包含的属性和方法。 存在的问题: 向friends数组添加一个字符串,由于数组存在于prototype属性中,添加字符串也会通过person2.friends反映出来。

    function Person() { } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.friends= ["Shelby","Court"]; Person.prototype.sayName = function () { alert(this.name); } var person1 = new Person(); person1.sayName(); //"Nicholas" var person2 = new Person(); person2.sayName(); //"Nicholas" alert(person1.friends == person2.friends);

    6.组合使用构造函数和原型模式(推荐)

    function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.friends = ["Shelby", "Court"]; } Person.prototype = { constructor:Person, sayName :function () { alert(this.name); } } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor"); person1.friends.push("Van"); alert(person1.friends); //"Shelby,Count,van" alert(person2.friends); //"Shelby,Count" alert(person1.friends === person2.friends); //false alert(person1.sayName === person2.sayName); //true
    转载请注明原文地址: https://ju.6miu.com/read-970238.html

    最新回复(0)