回归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()这样的函数!这样的话就丝毫没有封装性(很高大上的思想)可言了。这时,便出现了一种传说中的原型模式!
下节再说,工作喽 ─=≡Σ(((つ•̀ω•́)つ