ecma-262把对象定义为:“ 无序属性的集合,其属性可以包含基本值、对象、或者函数。”
解释:对象是一组没有特定顺序的值。对象的每个属性或方法都有一个名字,而每个名字都映射到一个值。可以把对象想象成散列表,无非就是一组名值对,其中值可以是数据或函数。
创建一个对象可以有如下方法:
根据引用类型Object
使用对象字面量
自定义引用类型
根据引用类型——Object 创建一个对象,代码如下
//创建一个实例对象
var person = new Object();
//为该实例添加属性和方法
person.name = "xiaoming";
person.age = 18;
person.job = "student";
person.sayName = function () {
alert(this.name)
}
早期的JavaScript开发人员经常使用跟这个模式创建新对象。后来对象字面量以其简洁直观的优势成为创建这种对象的首选模式。
使用对象字面量创建对象,代码如下
var person = {
name:"xiaoming",
age:18,
job:"student",
sayName(){
alert(this.name)
}
};
虽然以上方法都可以用来创建单个对象,但这些方式有个明显的确定:使用同一个接口创建很多对象,会产生大量的重复代码。为解决这个问题,人们开始使用工厂模式的一种变体,来抽象创建具体对象的过程,用函数来封装以特定接口创建对象的细节。
使用工厂模式创建对象,代码如下
function Person(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 = Person("xiaoming", 18, "student");
var person2 = Person("xiaohong", 25, "teacher");
上述代码能够根据接受的参数来构建一个包含必要信息的Person对象,可以无数次的调用这个函数,它都会返回一个包含三个属性一个方法的对象。但是工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。即在使用instanceof 关键字时返回的是 Object,而不是Person或者其他。示例代码如下
console.log(person1 instanceof Object);//true
console.log(person1 instanceof Person);//false
于是一种新的模式出现了。
使用构造函数模式创建对象
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
alert(this.name)
}
}
var person1 = new Person("xiaoming", 18, "student");
var person2 = new Person("xiaohong", 25, "teacher");
创建Person的新实例,必须使用new操作符。以这种方式调用构造函数实际上会经历以下四个步骤:
创建一个新对象
将构造函数的作用域赋给新对象(因此this就指向了这个新对象)
执行都在函数中的代码(为这个新对象添加属性)
返回新对象
创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型;这正是构造函数模式优于工厂模式的地方。
alert(person1 instanceof Object);//true
alert(person1 instanceof Person);//true
alert(person2 instanceof Object);//true
alert(person2 instanceof Person);//true
但是构造函数模式虽然好用,但是也有缺点,例如,每一个方法都要在每个实例上重新创建一遍。在上个例子中,person1和person2都有一个名为sayName的方法,但那两个方法不是同一个Function的实例。于是可以在这个方法上进行修改,示例如下:
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName=sayName;
}
function sayName () {
alert(this.name)
}
我们把sayName函数的定义转移到构造函数外部,这样person1和person2对象就共享了在全局作用域中定义的同一个sayName函数。但是这种方法不符合全局作用域函数的使用场景,而且当需要多个实例函数的时候就要定义多个全局函数,自定义的引用类型就丝毫没有封装性可言。于是我们可以通过原型模式来解决。
使用原型模式创建函数对象,示例如下
function Person() {
}
Person.prototype.name = "xiaoming";
Person.prototype.age = 18;
Person.prototype.job = "student";
Person.prototype.sayName = function () {
alert(this.name);
};
var person1 = new Person();
person1.sayName();//"xiaoming"
var person2 = new Person();
person2.sayName();//"xiaoming"
alert(person1.sayName == person2.sayName);//true
我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途就是包含可以有特定类型的所有实例共享的属性和方法。原型模式虽然解决了上述问题但是它省略了为构造函数初始化传参这一环节,结果所有实例在默认情况下都将取得相同的属性值。示例代码如下
Person.prototype = {
constructor: Person,
name: "xiaoming",
age: 18,
job: "student",
friends: ["xiaohong", "xiaolan"],
sayName: function () {
alert(this.name);
}
};
var person1 = new Person();
var person2 = new Person();
person1.friends.push("joker");
alert(person1.friends);//"xiaohong,xiaolan,joker"
alert(person2.friends);//"xiaohong,xiaolan,joker"
alert(person1.friends === person2.friends);//true
实例一般都是要有属于自己的全部属性的,上述案例中对person1对象friend属性进行改变person2也会发生改变,所以我们很少单独使用原型模式。而是组合使用构造函数模式和原型模式。
组合使用构造函数模式和原型模式创建对象,示例代码如下
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.friends = ["xiaohong", "xiaolan"]
}
Person.prototype = {
constructor: Person,
sayName: function () {
alert(this.name)
}
}
var person1 = new Person("xiaoming", 18, "student");
var person2 = new Person("joker", 25, "basketball player");
person1.friends.push("james");
alert(person1.friends);//"xiaohong,xiaolan,joker"
alert(person2.friends);//"xiaohong,xiaolan"
alert(person1.friends === person2.friends);//false
alert(person1.sayName === person2.sayName);//true
这种构造函数与原型混成的模式是目前在ecmasript中使用最广泛,认同度最高的一种创建自定义类型的方法。
使用动态原型模式自定义引用类型
function Person(name, age, job) {
//属性
this.name = name;
this.age = age;
this.job = job;
//方法
if (typeof this.sayName != "function") {
Person.prototype.sayName = function () {
alert(this.name);
};
}
}
var person = new Person("xiaoming", 18, "student");
person.sayName();
这个案例中,只在sayName方法不存在的情况下,才会将它添加到原型中。这个方法只会初次调用构造函数时才会执行。此后,原型已经完成初始化,不需要再做什么修改了。这里对原型所作的修改,能够立即在所有实例中得到反映。
javascript开发语言前端ecmascripthtml
发布于2022-07-11
著作权归作者所有
相关推荐更多
详细分析Javascript中创建对象的四种方式
weixin_38610870 0 下载
javascript中创建对象的几种方法总结
weixin_38566180 0 下载
javascript创建对象的几种模式介绍
weixin_38644780 0 下载
JavaScript 三种创建对象的方法
weixin_38675967 0 下载
Javascript创建对象的七种常用方式
AMMC 1594 阅读 0 评论
JavaScript创建对象的三种方式
强壮的病猫~ 2660 阅读 2 评论
javascript 创建对象常用几种方式_IT-CLASS的博客
javascript 创建对象常用几种方式 1.工厂模式 functionPerson(name,age,job){varo=newObject();o.name=name;o.age=age;o.job=job;o.sayName=function(){alert(this.name);};returno;}varperson=Person("Greg",27,"Doctor");pe...
JavaScript 创建对象的七种经典方式_黑夜中的潜行者的博客
JavaScript 创建对象的方式有很多,通过 Object构造函数或对象字面量的方式也可以创建单个对象,显然这两种方式会产生大量的重复代码,并不适合量产。 接下来介绍七种非常经典的创建对象的方式,他们也各有优缺点。
JavaScript的对象7种创建方式(总结)_彼得潘中国分潘的...
每次通过Person创建对象的时候,所有的say方法都是一样的,但是却存储了多次,浪费资源。 2.构造函数模式 套路: 自定义构造函数, 通过new创建对象 适用场景: 需要创建多个类型确定的对象,与上方工厂模式有所对比 ...
JavaScript创建类/对象的几种方式概述及实例
weixin_38538312 0 下载
javascript创建对象的6种方式
xicao1 1231 阅读 0 评论
最新发布 Javascript创建对象的4种方法
wo_2123311 1230 阅读 0 评论
JavaScript中创建类/对象的几种方法总结
weixin_38570202 0 下载