回归JavaScript基础,九

主题:理解对象,创建对象。

小明是一名程序猿,也是一条单身狗!他常常自嘲:每天都会有很多对象,但却没有女朋友!

多么痛的领悟。哈哈,目前比较流行的编程语言都是面向对象的语言(Object-Oriented)。而我们的JavaScript也是面向对象的,尽管它比较特殊。JavaScript中没有类这个概念,每个对象都是基于一个引用类型创建的。这个引用类型可以是前几节说到的原生类型,也可以是开发人员自定义的类型。

对象中可以有属性、方法,创建时赋予一些特征值来定义对象的行为。ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或函数”

1 var person = new Object();
2 person.name = "xuchaoi";
3 person.age = 24;
4 person.printName = function() {
5     console.log(this.name);
6 };

事实上,我们更喜欢这样创建一个对象:

1 var person = {
2     name: "xuchaoi",
3     age: 24,
4     printName: function() {
5         console.log(this.name);
6     }
7 };

在ECMAScript5中还为我们提供了Object.defineProperty()方法去修改对象属性默认的特性,有兴趣自行了解吧,一般也用不到!

人类总是“懒惰”的!日常中我们的程序可能会写很对对象,这其中就有很多对象是差不多的。既然差不多,为什么要重复写呢?这样就出现了一个概念,工厂模式!所谓工厂模式,就是一种设计模式(废话...),抽象创建对象的过程(疑惑...)。在JavaScript中,我们通过函数来封装创建(一类)对象的细节,这样就可以通过这个函数创建很多差不多的对象啦,这个函数就像一个工厂一样(明白了...)。补充:这里会比较多的用到this,后面会单独详细的讲解。这里可以先这么理解:在全局函数中,this指向window。函数被某个对象调用,函数中的this就指向那个对象。匿名函数中的this指向window。

 1 function createPerson(name, age) {
 2     var person = {
 3         name: name,
 4         age: age,
 5         printName: function() {
 6             console.log(this.name); 
 7         }
 8     };
 9     return person;
10 }
11 var person1 = createPerson("xuchaoi", 24);    //*补充:person1.constructor = Object
12 var person2 = createPerson("xiaoming", 25);   //*constructor属性:构造函数。

这里运用createPerson()函数创建对象很方便。但存在一个问题,就是新产生的对象的constructor属性(构造函数)都指向了Function,而不是person。打个比方的说,函数createPerson就像一个厂房把构造person的机器关在了里面,我们无法知道构造机器是什么样的。为了识别这些机器(识别对象),出现了一个新的方式:构造函数模式。

1 function Person(name, age) {
2     this.name = name;
3     this.age = age;
4     this.printName = function() {
5         console.log(this.name);
6     }
7 } //构造函数的特点:1.函数名首字母大写;2.属性和方法赋给了this对象;3.没有return语句
8 var person1 = new Person("xuchaoi", 24);  //用构造函数创建实例时,用new这个关键字
9 var person2 = new Person("xiaoming", 25); //person2.constructor === Person  =>  true

这时,“懒惰”的人又说了,person1和person2重复创建了Person的printName函数...

1 person1.printName === person2.printName; // false

好吧,那我把构造函数中的函数单独拎出来!

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.printName = printName;
}
function printName() {
    console.log(this.name)
}
var person1 = new Person("xuchaoi", 24); 
var person2 = new Person("xiaoming", 25);

这样完美了吧! NO NO NO,那要是构造函数中的方法很多怎么办?那岂不是全局window下有好多像printName()这样的函数!这样的话就丝毫没有封装性(很高大上的思想)可言了。这时,便出现了一种传说中的原型模式!

下节再说,工作喽 ─=≡Σ(((つ•̀ω•́)つ