当前位置: 移动技术网 > IT编程>开发语言>JavaScript > JavaScript对象的创建初学

JavaScript对象的创建初学

2018年10月15日  | 移动技术网IT编程  | 我要评论

javascript最初被称之为一门玩具性语言,主要的功能用于表单提交时的验证。时至今日,仍然有一些人认为javascript非常简单,有过其他语言的人学起来似乎不用几小时看下文档就行。其实不然,javascript虽然是一门脚本语言,但是他有着自己特色,如果不去了解他与众不同的地方,那遇到的坑将数不胜数。而javascript中难点之一就是原型链,他也是javascript中继承实现的重要基础。

函数

在开始讲原型链之前,我们先来聊一聊javascript中的函数。

javascript有5种基本类型以及一种复杂数据类型object,object本质上由一组无序的名值对组成。

object其实是一种引用类型,在javascript中引用类型和其他如c#语言中的类有点像。我们可以把javascript中的引用类型假想成类,引用类型的值就是类的一个实例,即对象。

引用类型:

object array date regexp function

我们可以看到,其实函数也是一种引用类型,即每一个函数实例可以称之为一个对象。

创建对象

前面已经说到,在javascript中,对象本质就是一组名值对。那如何来创建对象呢?

方式一:使用object构造函数创建

var person = new object();
person.name = 'jack';
person.age = 18;
person.sayname = function () {
   console.log(this.name);
};

早期的开发人员经常使用这种模式创建对象,不过后来又兴起来一种更为简单直接的方式。

方式二:使用对象字面量的方式创建

这种方式你可能经常在使用,但是不知道这种创建方式的名字——对象字面量。

var person = {
  name: 'jack',
  age: 18,
  sayname: function () {
    console.log(this.name)
  }
};

当你使用上面两种方式创建单个对象时,无疑是很方便简单的,但是现实中往往不是那么的简单,很多时候,我们都会面临一些复杂的场景。如果我们需要创建多个对象,那么采用上述方法就会产生大量重复代码。

方式三:使用工厂模式创建

工厂模式是软件工程领域中一种广为人知的设计模式,通过这种模式我们可以避免在创建多个对象时产生大量重复代码。

function createperson (name, age) {
  var obj = new object();
  obj.name = name;
  obj.age = age;
  obj.sayname = function () {
    console.log(this.name);
  };

  return obj;
}

var person1 = createperson('jack', 20);
var person2 = createperson('tony', 22); 

方式四:使用构造函数模式创建

虽然工厂模式解决了创建多个相似对象的问题,但是这里却存在另一个问题。我们知道在程序中,当我们要对某个参数进行处理时,往往会先判断其类型或检查其值是否符合我们的要求。

通过工厂创建的方式,显然无法对其创建的对象进行识别。随着javascript的发展,另一种方式出现了——构造函数模式。

在本文开始讲函数的时候提到,每个函数都是function类型的一个实例,即函数是对象。函数不仅可以使用函数声明语法和函数表达式去定义,而且还可以使用function构造函数定义。

在javascript中,构造函数可以用来创建特点类型的对象,比如像object、array以及function这样的原生构造函数,当然我们亦可以创建自定义构造函数。

function person (name, age) {
  this.name = name;
  this.age = age;
  this.sayname = function () {
    console.log(this.name);
  };
}
var person1 = new person('jack', 20);
var person2 = new person('tony', 22);

观察上面的代码,我们可以发现这种写法有点像其他oop语言。

class person {
  private $name;
  private $age;

  public function __construct(name, age)
  {
    $this->name = name;
    $this->age = age;
  }

  public function sayname()
  {
    echo $this->name;
  }
}

在前面的例子当中,person1和person2两个对象都有一个constructor(构造函数)属性,该属性指向person。如此一来,便可以解决对象类型的问题。我们可以使用如下方式进行判断:

console.log(person1.constructor == person);  // true

方式五:使用原型模式创建

构造函数虽然好用,但是并非没有缺点。构造函数的主要问题,就是每个方法都要在每个实例上重新创建一遍。

让我们再看一下前面的例子:

function person (name, age) {
  this.name= name;
  this.age = age;
  this.sayname = new function('console.log(this.name)');
}

前面提供,每个函数其实就是一个对象,上面定义函数方法和之前是等价的。

面对这种情况,我们可以通过原型模式来解决。

首先我们要牢记三个概念:

构造函数(类似于oop中的类) 实例或对象,通过new 构造函数()创建(类似于oop中的对象) 原型对象,可以想象成所有通过new操作符产生的实例的原始对象,只要我们创建一个构造函数,那么就会生成一个原型对象。在构造函数内部也会创建一个prototype属性,该属性指向原型对象。

下面我们看看如何使用原型模式来重写上面的例子:

function person () {}

person.prototype.name = 'jack';
person.prototype.age = 18;
person.prototype.sayname = function () {
  console.log(this.name);
};

var person1 = new person();

首先我们创建了一个自定义构造函数,里面是空的,什么也没加。然后,我们通过其包含的属性prototype,为其原型对象添加属性和方法。最后我们通过new操作符,创建了一个person实例。这个时候,person1也拥有了name属性、age属性以及sayname方法。

看到这里,如果你是新手,肯定觉得一脸蒙蔽。产生这种现象的原因其实就是javascript的原型链,也就是本文的主题。

当我们访问person1的name属性时,javascript会现在person1实例中查找,如果找不到,就根据person1实例内部的一个指针[[prototype]](该指针指向原型对象),去寻找其原型对象,如果原型对象里面有,那么就会取这个值。

在这我们来回顾一下方式四中说道person1和person2两个对象都有一个constructor,该属性指向person构造函数。其实从这里可以看出,不是这两个实例中有constructor,而是在它们的原型对象中有这个指向构造函数的constructor属性。所以实例和构造函数是没有直接联系的。

方式六:组合使用构造函数模式和原型模式创建

如果仅仅使用原型模式去创建对象,这样又会造成一个问题。我们希望像name、age这样的属性,能够通过参数进行传递,所以大多数情况都是结合两种方式来创建对象的。

构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性

function person (name, age) {
    this.name = name;
    this.age = age;
}
person.prototype.sayname = function () {
  console.log(this.name);
};

var person1 = new person('jack', 18);

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网